SlideShare a Scribd company logo
1 of 55
Download to read offline
How to Build and Run Node Applications With
Docker and Compose
- Kathleen Juell, Developer @ DigitalOcean, @katjuell
● Building containers
● Containerizing for development
with Compose
● Containerizing for deployment
Containers
Containers and VMs
● Container features
○ Lightweight
○ Portable
○ Isolated
Containers Virtual Machines
1. Building an Image for a
Node App
Dockerfile
CODE EDITOR
FROM node:12-alpine
1. Build the base
Dockerfile
CODE EDITOR
FROM node:12-alpine
RUN apk add --update --no-cache vim
1. Build the base
2. Install
container-level
dependencies
Dockerfile
CODE EDITOR
FROM node:12-alpine
RUN apk add --update --no-cache 
curl 
git 
vim
1. Build the base
2. Install
container-level
dependencies
Dockerfile
CODE EDITOR
FROM node:12-alpine
RUN apk add --update --no-cache 
curl 
git 
vim
RUN mkdir -p /home/node/app/node_modules && chown
-R node:node /home/node/app
USER node
WORKDIR /home/node/app
1. Build the base
2. Install
container-level
dependencies
3. Set working
directory & user
Dockerfile
CODE EDITOR
FROM node:12-alpine
RUN apk add --update --no-cache 
curl 
git 
vim
RUN mkdir -p /home/node/app/node_modules && chown
-R node:node /home/node/app
USER node
WORKDIR /home/node/app
COPY package*.json ./
COPY --chown=node:node . .
RUN npm install
1. Build the base
2. Install
container-level
dependencies
3. Set working
directory & user
4. Copy code, set
permissions, and
install project
dependencies
Dockerfile
CODE EDITOR
FROM node:12-alpine
RUN apk add --update --no-cache 
curl 
git 
vim
RUN mkdir -p /home/node/app/node_modules && chown
-R node:node /home/node/app
USER node
WORKDIR /home/node/app
COPY package*.json ./
COPY --chown=node:node . .
RUN npm install
EXPOSE 8080
CMD [ “node”, “app.js” ]
1. Build the base
2. Install
container-level
dependencies
3. Set working
directory & user
4. Copy code, set
permissions, and
install project
dependencies
5. Expose ports and
invoke commands
Up & Running
● Build: docker build -t <docker-demo> .
● Run: docker run --name <docker-demo> -p
80:8080 -d <docker-demo>
● Logs: docker logs <container-id>
● Check: docker ps -a
● Exec: docker exec -it <container-id> sh
Demo Time
2. Development Setup
with Compose
A. Prepare the Application
● Service: A running container
● Service definition: Information
about how the container will run
● Service: A running container
● Service definition: Information about how
the container will run
● 12FA principles to consider: 1. Store config
in the environment & separate it from code;
2. Treat backing services as attached
resources
Where to look & what to do?
● Where are your database credentials defined?
● Anything else that talks to an attached service?
Before:
const mongoose = require('mongoose');
const MONGO_USERNAME = 'sammy';
const MONGO_PASSWORD = 'your_password';
const MONGO_HOSTNAME = '127.0.0.1';
const MONGO_PORT = '27017';
const MONGO_DB = 'sharkinfo';
const url =
`mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_H
OSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;
mongoose.connect(url, {useNewUrlParser: true});
After:
const mongoose = require('mongoose');
const {
MONGO_USERNAME,
MONGO_PASSWORD,
MONGO_HOSTNAME,
MONGO_PORT,
MONGO_DB
} = process.env;
const url =
`mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_H
OSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;
mongoose.connect(url, {useNewUrlParser: true});
Environment Variables:
● Use .env file
Environment Variables:
● Use .env file
MONGO_USERNAME=sammy
MONGO_PASSWORD=your_password
MONGO_PORT=27017
MONGO_DB=sharkinfo
Environment Variables:
● Use .env file
● Credentials manager (orchestrated
environments)
One more stop at `db.js`:
. . .
const options = {
useNewUrlParser: true,
reconnectTries: Number.MAX_VALUE,
reconnectInterval: 500,
connectTimeoutMS: 10000,
};
const url =
`mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MO
NGO_PORT}/${MONGO_DB}?authSource=admin`;
mongoose.connect(url, options).then( function() {
console.log('MongoDB is connected');
})
.catch( function(err) {
console.log(err);
});
And an addition to `package.json`:
...
"dependencies": {
"ejs": "^2.6.1",
"express": "^4.16.4",
"mongoose": "^5.4.10"
},
"devDependencies": {
"nodemon": "^1.18.10"
}
}
B. Write the Compose File
Compose
File
CODE EDITOR
version: '3.4'
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
1. Tell Compose
how it should
build the app
image
Compose
File
CODE EDITOR
version: '3.4'
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
env_file: .env
environment:
- MONGO_HOSTNAME=db
volumes:
- .:/home/node/app
- node_modules:/home/node/app/node_modules
1. Tell Compose
how it should
build the app
image
2. Add environment
and volume info
Compose
File
CODE EDITOR
version: '3.4'
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
env_file: .env
environment:
- MONGO_HOSTNAME=db
volumes:
- .:/home/node/app
- node_modules:/home/node/app/node_modules
1. Tell Compose
how it should
build the app
image
2. Add environment
and volume info
Compose
File
CODE EDITOR
version: '3.4'
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
env_file: .env
environment:
- MONGO_HOSTNAME=db
volumes:
- .:/home/node/app
- node_modules:/home/node/app/node_modules
1. Tell Compose
how it should
build the app
image
2. Add environment
and volume info
Compose
File
CODE EDITOR
version: '3.4'
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
env_file: .env
environment:
- MONGO_HOSTNAME=db
volumes:
- .:/home/node/app
- node_modules:/home/node/app/node_modules: delegated
1. Tell Compose
how it should
build the app
image
2. Add environment
and volume info
Compose
File
CODE EDITOR
version: '3.4'
services:
nodejs:
build:
context: .
dockerfile: Dockerfile
image: nodejs
container_name: nodejs
env_file: .env
environment:
- MONGO_HOSTNAME=db
volumes:
- .:/home/node/app
- node_modules:/home/node/app/node_modules: delegated
ports:
- "80:8080"
command: ./wait-for.sh db:27017 --
/home/node/app/node_modules/.bin/nodemon app.js
1. Tell Compose
how it should
build the app
image
2. Add environment
and volume info
3. Add ports and
commands
Compose
File
CODE EDITOR
. . .
db:
image: mongo:4.2-bionic
container_name: db1. Tell Compose
what image it
should use
Compose
File
CODE EDITOR
. . .
db:
image: mongo:4.2-bionic
container_name: db
env_file: .env
environment:
- MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
- MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
1. Tell Compose
what image it
should use
2. Add environment
info
Compose
File
CODE EDITOR
. . .
db:
image: mongo:4.2-bionic
container_name: db
env_file: .env
environment:
- MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME
- MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD
volumes:
- dbdata:/data/db
1. Tell Compose
what image it
should use
2. Add environment
info
3. Add volumes
Compose
File
CODE EDITOR
. . .
volumes:
dbdata:
node_modules:1. Add top-level
volumes key for
named volumes
● Run: docker-compose up -d
● List: docker-compose ps
● Logs: docker-compose logs <container>
● Exec: docker-compose exec <container>
<command>
● Down: docker-compose down
Demo Time
3. Preparing to Deploy
Compose
File
TODO
CODE EDITOR
version: '3.4'
services:
nodejs:
image: <yourDockerHubUsername>/nodejs:v1
container_name: nodejs
1. Application
images: Pull from
registry
Compose
File
TODO
CODE EDITOR
version: '3.4'
services:
nodejs:
image: <yourDockerHubUsername>/nodejs:v1
container_name: nodejs
volumes:
- app_code:/home/node/app
- node_modules:/home/node/app/node_modules
1. Application
images: Pull from
registry
2. Use Named
Volumes: Prefer
them over bind
mounts for app
code
Compose
File
TODO
CODE EDITOR
webserver:
image: nginx:1.17-alpine
container_name: webserver
ports:
- "80:80"
volumes:
- app_code:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
depends_on:
- nodejs
1. Application
images: Pull from
registry
2. Use Named
Volumes: Prefer
them over bind
mounts for app code
3. Add a web server
Compose
File
TODO
CODE EDITOR
webserver:
image: nginx:1.17-alpine
container_name: webserver
ports:
- "80:80"
volumes:
- app_code:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
depends_on:
- nodejs
1. Application
images: Pull from
registry
2. Use Named
Volumes: Prefer
them over bind
mounts for app code
3. Add a web server
Compose
File
TODO
CODE EDITOR
certbot:
image: certbot/certbot
container_name: certbot
volumes:
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
- app_code:/var/www/html
depends_on:
- webserver
command: certonly --webroot --webroot-path=/var/www/html
--email sammy@example.com --agree-tos --no-eff-email --staging -d
example.com -d www.example.com
1. Application
images: Pull from
registry
2. Use Named
Volumes: Prefer
them over bind
mounts for app code
3. Add a web server
Compose
File
TODO
CODE EDITOR
webserver:
image: nginx:1.17-alpine
container_name: webserver
ports:
- "80:80"
volumes:
- app_code:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
depends_on:
- nodejs
1. Application
images: Pull from
registry
2. Use Named
Volumes: Prefer
them over bind
mounts for app code
3. Add a web server
Compose
File
TODO
CODE EDITOR
webserver:
image: nginx:1.17-alpine
container_name: webserver
ports:
- "80:80"
volumes:
- app_code:/var/www/html
- ./nginx-conf:/etc/nginx/conf.d
- certbot-etc:/etc/letsencrypt
- certbot-var:/var/lib/letsencrypt
depends_on:
- nodejs
1. Application
images: Pull from
registry
2. Use Named
Volumes: Prefer
them over bind
mounts for app code
3. Add a web server
4. Docker for certs:
How To Secure a
Containerized Node
Application with Let's
Encrypt
How to Build and Run Node Applications With
Docker and Compose
- Kathleen Juell, Developer @ DigitalOcean, @katjuell

More Related Content

What's hot

DockerCon SF 2015: Scaling New Services
DockerCon SF 2015: Scaling New ServicesDockerCon SF 2015: Scaling New Services
DockerCon SF 2015: Scaling New Services
Docker, Inc.
 
Docker Platform 1.9
Docker Platform 1.9Docker Platform 1.9
Docker Platform 1.9
Docker, Inc.
 
Thinking Inside the Container: A Continuous Delivery Story by Maxfield Stewart
Thinking Inside the Container: A Continuous Delivery Story by Maxfield Stewart Thinking Inside the Container: A Continuous Delivery Story by Maxfield Stewart
Thinking Inside the Container: A Continuous Delivery Story by Maxfield Stewart
Docker, Inc.
 

What's hot (20)

Docker for Fun and Profit
Docker for Fun and ProfitDocker for Fun and Profit
Docker for Fun and Profit
 
DockerDay2015: Docker Security
DockerDay2015: Docker SecurityDockerDay2015: Docker Security
DockerDay2015: Docker Security
 
ContainerDayVietnam2016: Docker for JS Developer
ContainerDayVietnam2016: Docker for JS DeveloperContainerDayVietnam2016: Docker for JS Developer
ContainerDayVietnam2016: Docker for JS Developer
 
Kubernetes - Sailing a Sea of Containers
Kubernetes - Sailing a Sea of ContainersKubernetes - Sailing a Sea of Containers
Kubernetes - Sailing a Sea of Containers
 
Build Your Own SaaS using Docker
Build Your Own SaaS using DockerBuild Your Own SaaS using Docker
Build Your Own SaaS using Docker
 
DCSF19 Containers for Beginners
DCSF19 Containers for BeginnersDCSF19 Containers for Beginners
DCSF19 Containers for Beginners
 
DockerCon SF 2015: Scaling New Services
DockerCon SF 2015: Scaling New ServicesDockerCon SF 2015: Scaling New Services
DockerCon SF 2015: Scaling New Services
 
Current State of Docker Platform - Nov 2019
Current State of Docker Platform  - Nov 2019Current State of Docker Platform  - Nov 2019
Current State of Docker Platform - Nov 2019
 
Scaling jenkins with kubernetes
Scaling jenkins with kubernetesScaling jenkins with kubernetes
Scaling jenkins with kubernetes
 
Achieving CI/CD with Kubernetes
Achieving CI/CD with KubernetesAchieving CI/CD with Kubernetes
Achieving CI/CD with Kubernetes
 
Docker Platform 1.9
Docker Platform 1.9Docker Platform 1.9
Docker Platform 1.9
 
DockerDay2015: Keynote
DockerDay2015: KeynoteDockerDay2015: Keynote
DockerDay2015: Keynote
 
Scaling Docker Containers using Kubernetes and Azure Container Service
Scaling Docker Containers using Kubernetes and Azure Container ServiceScaling Docker Containers using Kubernetes and Azure Container Service
Scaling Docker Containers using Kubernetes and Azure Container Service
 
Containerizing a REST API and Deploying to Kubernetes
Containerizing a REST API and Deploying to KubernetesContainerizing a REST API and Deploying to Kubernetes
Containerizing a REST API and Deploying to Kubernetes
 
Docker Container As A Service - March 2016
Docker Container As A Service - March 2016Docker Container As A Service - March 2016
Docker Container As A Service - March 2016
 
Managing Docker Containers In A Cluster - Introducing Kubernetes
Managing Docker Containers In A Cluster - Introducing KubernetesManaging Docker Containers In A Cluster - Introducing Kubernetes
Managing Docker Containers In A Cluster - Introducing Kubernetes
 
Modernizing Traditional Apps with Docker Enterprise Edition
Modernizing Traditional Apps with Docker Enterprise EditionModernizing Traditional Apps with Docker Enterprise Edition
Modernizing Traditional Apps with Docker Enterprise Edition
 
Thinking Inside the Container: A Continuous Delivery Story by Maxfield Stewart
Thinking Inside the Container: A Continuous Delivery Story by Maxfield Stewart Thinking Inside the Container: A Continuous Delivery Story by Maxfield Stewart
Thinking Inside the Container: A Continuous Delivery Story by Maxfield Stewart
 
Continuous delivery of microservices with kubernetes - Quintor 27-2-2017
Continuous delivery of microservices with kubernetes - Quintor 27-2-2017Continuous delivery of microservices with kubernetes - Quintor 27-2-2017
Continuous delivery of microservices with kubernetes - Quintor 27-2-2017
 
ContainerDayVietnam2016: Dockerize a small business
ContainerDayVietnam2016: Dockerize a small businessContainerDayVietnam2016: Dockerize a small business
ContainerDayVietnam2016: Dockerize a small business
 

Similar to How To Build and Run Node Apps with Docker and Compose

Similar to How To Build and Run Node Apps with Docker and Compose (20)

Webinar: Building Your First App in Node.js
Webinar: Building Your First App in Node.jsWebinar: Building Your First App in Node.js
Webinar: Building Your First App in Node.js
 
Webinar: Building Your First App in Node.js
Webinar: Building Your First App in Node.jsWebinar: Building Your First App in Node.js
Webinar: Building Your First App in Node.js
 
Running MongoDB Enterprise on Kubernetes
Running MongoDB Enterprise on KubernetesRunning MongoDB Enterprise on Kubernetes
Running MongoDB Enterprise on Kubernetes
 
MeaNstack on Docker
MeaNstack on DockerMeaNstack on Docker
MeaNstack on Docker
 
Puppet at Opera Sofware - PuppetCamp Oslo 2013
Puppet at Opera Sofware - PuppetCamp Oslo 2013Puppet at Opera Sofware - PuppetCamp Oslo 2013
Puppet at Opera Sofware - PuppetCamp Oslo 2013
 
MongoDB and Node.js
MongoDB and Node.jsMongoDB and Node.js
MongoDB and Node.js
 
Ruby microservices with Docker - Sergii Koba
Ruby microservices with Docker -  Sergii KobaRuby microservices with Docker -  Sergii Koba
Ruby microservices with Docker - Sergii Koba
 
Setup docker on existing application
Setup docker on existing applicationSetup docker on existing application
Setup docker on existing application
 
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
 
ABCs of docker
ABCs of dockerABCs of docker
ABCs of docker
 
Infrastructure = code - 1 year later
Infrastructure = code - 1 year laterInfrastructure = code - 1 year later
Infrastructure = code - 1 year later
 
Troubleshooting Tips from a Docker Support Engineer
Troubleshooting Tips from a Docker Support EngineerTroubleshooting Tips from a Docker Support Engineer
Troubleshooting Tips from a Docker Support Engineer
 
Troubleshooting Tips from a Docker Support Engineer - Jeff Anderson, Docker
Troubleshooting Tips from a Docker Support Engineer - Jeff Anderson, DockerTroubleshooting Tips from a Docker Support Engineer - Jeff Anderson, Docker
Troubleshooting Tips from a Docker Support Engineer - Jeff Anderson, Docker
 
Docker primer and tips
Docker primer and tipsDocker primer and tips
Docker primer and tips
 
桃園市教育局Docker技術入門與實作
桃園市教育局Docker技術入門與實作桃園市教育局Docker技術入門與實作
桃園市教育局Docker技術入門與實作
 
How to Improve Your Image Builds Using Advance Docker Build
How to Improve Your Image Builds Using Advance Docker BuildHow to Improve Your Image Builds Using Advance Docker Build
How to Improve Your Image Builds Using Advance Docker Build
 
Docker Introduction.pdf
Docker Introduction.pdfDocker Introduction.pdf
Docker Introduction.pdf
 
Running Docker in Development & Production (#ndcoslo 2015)
Running Docker in Development & Production (#ndcoslo 2015)Running Docker in Development & Production (#ndcoslo 2015)
Running Docker in Development & Production (#ndcoslo 2015)
 
From development environments to production deployments with Docker, Compose,...
From development environments to production deployments with Docker, Compose,...From development environments to production deployments with Docker, Compose,...
From development environments to production deployments with Docker, Compose,...
 
Docker tlv
Docker tlvDocker tlv
Docker tlv
 

More from Docker, Inc.

Build & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWSBuild & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWS
Docker, Inc.
 
Virtual Meetup Docker + Arm: Building Multi-arch Apps with Buildx
Virtual Meetup Docker + Arm: Building Multi-arch Apps with BuildxVirtual Meetup Docker + Arm: Building Multi-arch Apps with Buildx
Virtual Meetup Docker + Arm: Building Multi-arch Apps with Buildx
Docker, Inc.
 

More from Docker, Inc. (20)

Build & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWSBuild & Deploy Multi-Container Applications to AWS
Build & Deploy Multi-Container Applications to AWS
 
Securing Your Containerized Applications with NGINX
Securing Your Containerized Applications with NGINXSecuring Your Containerized Applications with NGINX
Securing Your Containerized Applications with NGINX
 
Hands-on Helm
Hands-on Helm Hands-on Helm
Hands-on Helm
 
Distributed Deep Learning with Docker at Salesforce
Distributed Deep Learning with Docker at SalesforceDistributed Deep Learning with Docker at Salesforce
Distributed Deep Learning with Docker at Salesforce
 
The First 10M Pulls: Building The Official Curl Image for Docker Hub
The First 10M Pulls: Building The Official Curl Image for Docker HubThe First 10M Pulls: Building The Official Curl Image for Docker Hub
The First 10M Pulls: Building The Official Curl Image for Docker Hub
 
Monitoring in a Microservices World
Monitoring in a Microservices WorldMonitoring in a Microservices World
Monitoring in a Microservices World
 
COVID-19 in Italy: How Docker is Helping the Biggest Italian IT Company Conti...
COVID-19 in Italy: How Docker is Helping the Biggest Italian IT Company Conti...COVID-19 in Italy: How Docker is Helping the Biggest Italian IT Company Conti...
COVID-19 in Italy: How Docker is Helping the Biggest Italian IT Company Conti...
 
Predicting Space Weather with Docker
Predicting Space Weather with DockerPredicting Space Weather with Docker
Predicting Space Weather with Docker
 
How to Use Mirroring and Caching to Optimize your Container Registry
How to Use Mirroring and Caching to Optimize your Container RegistryHow to Use Mirroring and Caching to Optimize your Container Registry
How to Use Mirroring and Caching to Optimize your Container Registry
 
Monolithic to Microservices + Docker = SDLC on Steroids!
Monolithic to Microservices + Docker = SDLC on Steroids!Monolithic to Microservices + Docker = SDLC on Steroids!
Monolithic to Microservices + Docker = SDLC on Steroids!
 
Kubernetes at Datadog Scale
Kubernetes at Datadog ScaleKubernetes at Datadog Scale
Kubernetes at Datadog Scale
 
Using Docker Hub at Scale to Support Micro Focus' Delivery and Deployment Model
Using Docker Hub at Scale to Support Micro Focus' Delivery and Deployment ModelUsing Docker Hub at Scale to Support Micro Focus' Delivery and Deployment Model
Using Docker Hub at Scale to Support Micro Focus' Delivery and Deployment Model
 
From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...
From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...
From Fortran on the Desktop to Kubernetes in the Cloud: A Windows Migration S...
 
Developing with Docker for the Arm Architecture
Developing with Docker for the Arm ArchitectureDeveloping with Docker for the Arm Architecture
Developing with Docker for the Arm Architecture
 
Sharing is Caring: How to Begin Speaking at Conferences
Sharing is Caring: How to Begin Speaking at ConferencesSharing is Caring: How to Begin Speaking at Conferences
Sharing is Caring: How to Begin Speaking at Conferences
 
Virtual Meetup Docker + Arm: Building Multi-arch Apps with Buildx
Virtual Meetup Docker + Arm: Building Multi-arch Apps with BuildxVirtual Meetup Docker + Arm: Building Multi-arch Apps with Buildx
Virtual Meetup Docker + Arm: Building Multi-arch Apps with Buildx
 
DCSF 19 How Entergy is Mitigating Legacy Windows Operating System Vulnerabili...
DCSF 19 How Entergy is Mitigating Legacy Windows Operating System Vulnerabili...DCSF 19 How Entergy is Mitigating Legacy Windows Operating System Vulnerabili...
DCSF 19 How Entergy is Mitigating Legacy Windows Operating System Vulnerabili...
 
DCSF 19 Developing Apps with Containers, Functions and Cloud Services
DCSF 19 Developing Apps with Containers, Functions and Cloud ServicesDCSF 19 Developing Apps with Containers, Functions and Cloud Services
DCSF 19 Developing Apps with Containers, Functions and Cloud Services
 
DCSF 19 eBPF Superpowers
DCSF 19 eBPF SuperpowersDCSF 19 eBPF Superpowers
DCSF 19 eBPF Superpowers
 
DCSF 19 Zero Trust Networks Come to Enterprise Kubernetes
DCSF 19 Zero Trust Networks Come to Enterprise KubernetesDCSF 19 Zero Trust Networks Come to Enterprise Kubernetes
DCSF 19 Zero Trust Networks Come to Enterprise Kubernetes
 

Recently uploaded

Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Recently uploaded (20)

A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 

How To Build and Run Node Apps with Docker and Compose

  • 1. How to Build and Run Node Applications With Docker and Compose - Kathleen Juell, Developer @ DigitalOcean, @katjuell
  • 2.
  • 3.
  • 4.
  • 5.
  • 6. ● Building containers ● Containerizing for development with Compose ● Containerizing for deployment
  • 7.
  • 8.
  • 9.
  • 11. Containers and VMs ● Container features ○ Lightweight ○ Portable ○ Isolated Containers Virtual Machines
  • 12. 1. Building an Image for a Node App
  • 14. Dockerfile CODE EDITOR FROM node:12-alpine RUN apk add --update --no-cache vim 1. Build the base 2. Install container-level dependencies
  • 15. Dockerfile CODE EDITOR FROM node:12-alpine RUN apk add --update --no-cache curl git vim 1. Build the base 2. Install container-level dependencies
  • 16. Dockerfile CODE EDITOR FROM node:12-alpine RUN apk add --update --no-cache curl git vim RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app USER node WORKDIR /home/node/app 1. Build the base 2. Install container-level dependencies 3. Set working directory & user
  • 17. Dockerfile CODE EDITOR FROM node:12-alpine RUN apk add --update --no-cache curl git vim RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app USER node WORKDIR /home/node/app COPY package*.json ./ COPY --chown=node:node . . RUN npm install 1. Build the base 2. Install container-level dependencies 3. Set working directory & user 4. Copy code, set permissions, and install project dependencies
  • 18. Dockerfile CODE EDITOR FROM node:12-alpine RUN apk add --update --no-cache curl git vim RUN mkdir -p /home/node/app/node_modules && chown -R node:node /home/node/app USER node WORKDIR /home/node/app COPY package*.json ./ COPY --chown=node:node . . RUN npm install EXPOSE 8080 CMD [ “node”, “app.js” ] 1. Build the base 2. Install container-level dependencies 3. Set working directory & user 4. Copy code, set permissions, and install project dependencies 5. Expose ports and invoke commands
  • 20. ● Build: docker build -t <docker-demo> . ● Run: docker run --name <docker-demo> -p 80:8080 -d <docker-demo> ● Logs: docker logs <container-id> ● Check: docker ps -a ● Exec: docker exec -it <container-id> sh
  • 23. A. Prepare the Application
  • 24. ● Service: A running container ● Service definition: Information about how the container will run
  • 25. ● Service: A running container ● Service definition: Information about how the container will run ● 12FA principles to consider: 1. Store config in the environment & separate it from code; 2. Treat backing services as attached resources
  • 26. Where to look & what to do? ● Where are your database credentials defined? ● Anything else that talks to an attached service?
  • 27. Before: const mongoose = require('mongoose'); const MONGO_USERNAME = 'sammy'; const MONGO_PASSWORD = 'your_password'; const MONGO_HOSTNAME = '127.0.0.1'; const MONGO_PORT = '27017'; const MONGO_DB = 'sharkinfo'; const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_H OSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`; mongoose.connect(url, {useNewUrlParser: true});
  • 28. After: const mongoose = require('mongoose'); const { MONGO_USERNAME, MONGO_PASSWORD, MONGO_HOSTNAME, MONGO_PORT, MONGO_DB } = process.env; const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_H OSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`; mongoose.connect(url, {useNewUrlParser: true});
  • 30. Environment Variables: ● Use .env file MONGO_USERNAME=sammy MONGO_PASSWORD=your_password MONGO_PORT=27017 MONGO_DB=sharkinfo
  • 31. Environment Variables: ● Use .env file ● Credentials manager (orchestrated environments)
  • 32. One more stop at `db.js`: . . . const options = { useNewUrlParser: true, reconnectTries: Number.MAX_VALUE, reconnectInterval: 500, connectTimeoutMS: 10000, }; const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MO NGO_PORT}/${MONGO_DB}?authSource=admin`; mongoose.connect(url, options).then( function() { console.log('MongoDB is connected'); }) .catch( function(err) { console.log(err); });
  • 33. And an addition to `package.json`: ... "dependencies": { "ejs": "^2.6.1", "express": "^4.16.4", "mongoose": "^5.4.10" }, "devDependencies": { "nodemon": "^1.18.10" } }
  • 34. B. Write the Compose File
  • 35. Compose File CODE EDITOR version: '3.4' services: nodejs: build: context: . dockerfile: Dockerfile image: nodejs container_name: nodejs 1. Tell Compose how it should build the app image
  • 36. Compose File CODE EDITOR version: '3.4' services: nodejs: build: context: . dockerfile: Dockerfile image: nodejs container_name: nodejs env_file: .env environment: - MONGO_HOSTNAME=db volumes: - .:/home/node/app - node_modules:/home/node/app/node_modules 1. Tell Compose how it should build the app image 2. Add environment and volume info
  • 37. Compose File CODE EDITOR version: '3.4' services: nodejs: build: context: . dockerfile: Dockerfile image: nodejs container_name: nodejs env_file: .env environment: - MONGO_HOSTNAME=db volumes: - .:/home/node/app - node_modules:/home/node/app/node_modules 1. Tell Compose how it should build the app image 2. Add environment and volume info
  • 38. Compose File CODE EDITOR version: '3.4' services: nodejs: build: context: . dockerfile: Dockerfile image: nodejs container_name: nodejs env_file: .env environment: - MONGO_HOSTNAME=db volumes: - .:/home/node/app - node_modules:/home/node/app/node_modules 1. Tell Compose how it should build the app image 2. Add environment and volume info
  • 39. Compose File CODE EDITOR version: '3.4' services: nodejs: build: context: . dockerfile: Dockerfile image: nodejs container_name: nodejs env_file: .env environment: - MONGO_HOSTNAME=db volumes: - .:/home/node/app - node_modules:/home/node/app/node_modules: delegated 1. Tell Compose how it should build the app image 2. Add environment and volume info
  • 40. Compose File CODE EDITOR version: '3.4' services: nodejs: build: context: . dockerfile: Dockerfile image: nodejs container_name: nodejs env_file: .env environment: - MONGO_HOSTNAME=db volumes: - .:/home/node/app - node_modules:/home/node/app/node_modules: delegated ports: - "80:8080" command: ./wait-for.sh db:27017 -- /home/node/app/node_modules/.bin/nodemon app.js 1. Tell Compose how it should build the app image 2. Add environment and volume info 3. Add ports and commands
  • 41. Compose File CODE EDITOR . . . db: image: mongo:4.2-bionic container_name: db1. Tell Compose what image it should use
  • 42. Compose File CODE EDITOR . . . db: image: mongo:4.2-bionic container_name: db env_file: .env environment: - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD 1. Tell Compose what image it should use 2. Add environment info
  • 43. Compose File CODE EDITOR . . . db: image: mongo:4.2-bionic container_name: db env_file: .env environment: - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD volumes: - dbdata:/data/db 1. Tell Compose what image it should use 2. Add environment info 3. Add volumes
  • 44. Compose File CODE EDITOR . . . volumes: dbdata: node_modules:1. Add top-level volumes key for named volumes
  • 45. ● Run: docker-compose up -d ● List: docker-compose ps ● Logs: docker-compose logs <container> ● Exec: docker-compose exec <container> <command> ● Down: docker-compose down
  • 47. 3. Preparing to Deploy
  • 48. Compose File TODO CODE EDITOR version: '3.4' services: nodejs: image: <yourDockerHubUsername>/nodejs:v1 container_name: nodejs 1. Application images: Pull from registry
  • 49. Compose File TODO CODE EDITOR version: '3.4' services: nodejs: image: <yourDockerHubUsername>/nodejs:v1 container_name: nodejs volumes: - app_code:/home/node/app - node_modules:/home/node/app/node_modules 1. Application images: Pull from registry 2. Use Named Volumes: Prefer them over bind mounts for app code
  • 50. Compose File TODO CODE EDITOR webserver: image: nginx:1.17-alpine container_name: webserver ports: - "80:80" volumes: - app_code:/var/www/html - ./nginx-conf:/etc/nginx/conf.d depends_on: - nodejs 1. Application images: Pull from registry 2. Use Named Volumes: Prefer them over bind mounts for app code 3. Add a web server
  • 51. Compose File TODO CODE EDITOR webserver: image: nginx:1.17-alpine container_name: webserver ports: - "80:80" volumes: - app_code:/var/www/html - ./nginx-conf:/etc/nginx/conf.d depends_on: - nodejs 1. Application images: Pull from registry 2. Use Named Volumes: Prefer them over bind mounts for app code 3. Add a web server
  • 52. Compose File TODO CODE EDITOR certbot: image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - certbot-var:/var/lib/letsencrypt - app_code:/var/www/html depends_on: - webserver command: certonly --webroot --webroot-path=/var/www/html --email sammy@example.com --agree-tos --no-eff-email --staging -d example.com -d www.example.com 1. Application images: Pull from registry 2. Use Named Volumes: Prefer them over bind mounts for app code 3. Add a web server
  • 53. Compose File TODO CODE EDITOR webserver: image: nginx:1.17-alpine container_name: webserver ports: - "80:80" volumes: - app_code:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt - certbot-var:/var/lib/letsencrypt depends_on: - nodejs 1. Application images: Pull from registry 2. Use Named Volumes: Prefer them over bind mounts for app code 3. Add a web server
  • 54. Compose File TODO CODE EDITOR webserver: image: nginx:1.17-alpine container_name: webserver ports: - "80:80" volumes: - app_code:/var/www/html - ./nginx-conf:/etc/nginx/conf.d - certbot-etc:/etc/letsencrypt - certbot-var:/var/lib/letsencrypt depends_on: - nodejs 1. Application images: Pull from registry 2. Use Named Volumes: Prefer them over bind mounts for app code 3. Add a web server 4. Docker for certs: How To Secure a Containerized Node Application with Let's Encrypt
  • 55. How to Build and Run Node Applications With Docker and Compose - Kathleen Juell, Developer @ DigitalOcean, @katjuell