Docker for JS Developer
Nguyen Sy Thanh Son
thanhson1085@gmail.com
@thanhson1085
https://sonnguyen.ws
Developer@Sigma IT Solutions
(Git/DevOps) Lecturer@Techmaster
A Big Fan of Open Source
Member of Docker Hanoi (https://www.facebook.com/dockerhanoi/)
Building a Starter Project
Requirements:
Architecture: Microservices
Culture: DevOps
Backend: NodeJS
Frontend/CMS: AngularJS
Database: MongoDB
Cache/Queue: Redis
Gateway: Nginx
APIs
NPM
ExpressJS
Packages
node-config
winston
mongoose
momentjs
mocha
redis
+-- api-seed
¦ +-- apis
¦ +-- config
¦ +-- Dockerfile
¦ +-- docs
¦ +-- entrypoint.sh
¦ +-- helpers
¦ +-- index.js
¦ +-- middlewares
¦ +-- models
¦ +-- node_modules
¦ +-- package.json
¦ +-- queues
¦ +-- README.md
¦ +-- test
¦ +-- views
APIs - Dockerfile
$ cat api-seed/Dockerfile
FROM mhart/alpine-node:4.4
MAINTAINER Nguyen Sy Thanh Son
RUN npm install -g pm2
WORKDIR /build
COPY ./ /build
EXPOSE 3000
RUN chmod +x /build/entrypoint.sh
RUN cp /build/config/default.json
/build/config/local.json
ENTRYPOINT ["/build/entrypoint.sh"]
$ cat api-seed/entrypoint.sh
#!/bin/sh
cd /build
pm2 start -x --no-daemon index.js
$ docker build -t thanhson1085/api-seed
$ docker push thanhson1085/api-seed
CMS
AngularJS
SB Admin 2
Bower Packages
angular
angular-ui-router
oclazyload
angular-resource
angular-translate
angular-bootstrap
"dependencies": {
"angular": "^1.4.0",
"angular-animate": "^1.5.7",
"bootstrap-sass-official": "^3.2.0",
"angular-touch": "^1.4.0",
"angular-ui-router": "^0.2.18",
"oclazyload": "^1.0.9",
"font-awesome": "fontawesome#^4.6.3",
"angular-resource": "^1.5.7",
"angular-cookies": "^1.5.7",
"angular-bootstrap": "^1.3.3",
"angular-translate": "^2.11.0",
"angular-translate-storage-local": "^2.11.0",
"angular-translate-loader-static-files": "^2.11.0",
"angular-loading-bar": "^0.9.0",
"jquery": "2.2.3"
},
CMS - Dockerfile
$ cat site-seed/Dockerfile
FROM nginx:1.11-alpine
MAINTAINER Nguyen Sy Thanh Son
COPY ./dist/ /usr/share/nginx/html/
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
+-- site-seed
¦ +-- app
¦ +-- bower_components
¦ +-- bower.json
¦ +-- config
¦ +-- dist
¦ +-- Dockerfile
¦ +-- Gruntfile.js
¦ +-- node_modules
¦ +-- package.json
¦ +-- README.md
¦ +-- test
$ docker build -t thanhson1085/site-seed
$ docker push thanhson1085/site-seed
Orchestration
Orchestration
version: "2"
services:
apis:
image: thanhson1085/api-seed
depends_on:
- db
- redis
networks:
- front-net
- back-net
site:
image: thanhson1085/site-seed
networks:
- front-net
redis:
image: redis:alpine
container_name: redis
networks:
- back-net
db:
image: mongo:3.2
container_name: db
volumes:
- "mongodb:/data/db"
networks:
- back-net
gateway:
image: nginx
container_name: gateway
volumes:
- ./app.template:/etc/nginx/conf.d/default.conf
- ./nginx.template:/etc/nginx/nginx.conf
ports:
- "80:80"
- "443:443"
depends_on:
- apis
networks:
- front-net
volumes:
mongodb:
networks:
front-net:
back-net:
docker-compose.yml
Gateway - Nginx
upstream backend {
server apis:3000;
}
upstream frontend {
server site;
}
server {
listen 80 default_server;
listen [::]:80 default_server ipv6only=on;
location /api/ {
rewrite ^/api/(.*)$ /api/$1 break;
proxy_pass http://backend/;
}
location / {
proxy_pass http://frontend/;
}
}
gateway:
image: nginx
container_name: gateway
volumes:
- ./app.template:/etc/nginx/conf.d/default.conf
- ./nginx.template:/etc/nginx/nginx.conf
ports:
- "80:80"
- "443:443"
depends_on:
- apis
networks:
- front-net
Vagrant.configure(2) do |config|
config.vm.box = "ubuntu/trusty64"
config.vm.provision "shell", inline: <<-SHELL
sudo apt-get update
sudo apt-get install -y whois git unzip wget curl
sudo useradd -m -p `mkpasswd password` -s /bin/bash dev
sudo usermod -a -G sudo dev
SHELL
config.vm.provision :shell, path: "./ops/init.sh"
config.vm.provider "virtualbox" do |vb|
vb.gui = false
vb.memory = 1024
vb.cpus = 2
end
config.vm.define "nodeone" do |n1|
n1.vm.hostname = "nodeone"
n1.vm.network "private_network", ip: "172.20.20.20"
n1.vm.provision :shell, path: "./ops/nodeone.sh"
end
config.vm.define "nodetwo" do |n2|
n2.vm.hostname = "nodetwo"
n2.vm.network "private_network", ip: "172.20.20.21"
n2.vm.provision :shell, path: "./ops/nodetwo.sh"
end
FROM mhart/alpine-node:4.4
MAINTAINER Nguyen Sy Thanh Son
RUN npm install -g pm2
WORKDIR /build
COPY ./ /build
EXPOSE 3000
RUN chmod +x /build/entrypoint.sh
RUN cp /build/config/default.json
/build/config/local.json
ENTRYPOINT ["/build/entrypoint.sh"]
Development Steps
DEMO
https://github.com/thanhson1085/bean-seed
vagrant up
Q&A

ContainerDayVietnam2016: Docker for JS Developer

  • 1.
    Docker for JSDeveloper
  • 2.
    Nguyen Sy ThanhSon thanhson1085@gmail.com @thanhson1085 https://sonnguyen.ws Developer@Sigma IT Solutions (Git/DevOps) Lecturer@Techmaster A Big Fan of Open Source Member of Docker Hanoi (https://www.facebook.com/dockerhanoi/)
  • 3.
    Building a StarterProject Requirements: Architecture: Microservices Culture: DevOps Backend: NodeJS Frontend/CMS: AngularJS Database: MongoDB Cache/Queue: Redis Gateway: Nginx
  • 6.
    APIs NPM ExpressJS Packages node-config winston mongoose momentjs mocha redis +-- api-seed ¦ +--apis ¦ +-- config ¦ +-- Dockerfile ¦ +-- docs ¦ +-- entrypoint.sh ¦ +-- helpers ¦ +-- index.js ¦ +-- middlewares ¦ +-- models ¦ +-- node_modules ¦ +-- package.json ¦ +-- queues ¦ +-- README.md ¦ +-- test ¦ +-- views
  • 7.
    APIs - Dockerfile $cat api-seed/Dockerfile FROM mhart/alpine-node:4.4 MAINTAINER Nguyen Sy Thanh Son RUN npm install -g pm2 WORKDIR /build COPY ./ /build EXPOSE 3000 RUN chmod +x /build/entrypoint.sh RUN cp /build/config/default.json /build/config/local.json ENTRYPOINT ["/build/entrypoint.sh"] $ cat api-seed/entrypoint.sh #!/bin/sh cd /build pm2 start -x --no-daemon index.js $ docker build -t thanhson1085/api-seed $ docker push thanhson1085/api-seed
  • 8.
  • 9.
    Bower Packages angular angular-ui-router oclazyload angular-resource angular-translate angular-bootstrap "dependencies": { "angular":"^1.4.0", "angular-animate": "^1.5.7", "bootstrap-sass-official": "^3.2.0", "angular-touch": "^1.4.0", "angular-ui-router": "^0.2.18", "oclazyload": "^1.0.9", "font-awesome": "fontawesome#^4.6.3", "angular-resource": "^1.5.7", "angular-cookies": "^1.5.7", "angular-bootstrap": "^1.3.3", "angular-translate": "^2.11.0", "angular-translate-storage-local": "^2.11.0", "angular-translate-loader-static-files": "^2.11.0", "angular-loading-bar": "^0.9.0", "jquery": "2.2.3" },
  • 10.
    CMS - Dockerfile $cat site-seed/Dockerfile FROM nginx:1.11-alpine MAINTAINER Nguyen Sy Thanh Son COPY ./dist/ /usr/share/nginx/html/ EXPOSE 80 443 CMD ["nginx", "-g", "daemon off;"] +-- site-seed ¦ +-- app ¦ +-- bower_components ¦ +-- bower.json ¦ +-- config ¦ +-- dist ¦ +-- Dockerfile ¦ +-- Gruntfile.js ¦ +-- node_modules ¦ +-- package.json ¦ +-- README.md ¦ +-- test $ docker build -t thanhson1085/site-seed $ docker push thanhson1085/site-seed
  • 11.
  • 12.
    Orchestration version: "2" services: apis: image: thanhson1085/api-seed depends_on: -db - redis networks: - front-net - back-net site: image: thanhson1085/site-seed networks: - front-net redis: image: redis:alpine container_name: redis networks: - back-net db: image: mongo:3.2 container_name: db volumes: - "mongodb:/data/db" networks: - back-net gateway: image: nginx container_name: gateway volumes: - ./app.template:/etc/nginx/conf.d/default.conf - ./nginx.template:/etc/nginx/nginx.conf ports: - "80:80" - "443:443" depends_on: - apis networks: - front-net volumes: mongodb: networks: front-net: back-net: docker-compose.yml
  • 13.
    Gateway - Nginx upstreambackend { server apis:3000; } upstream frontend { server site; } server { listen 80 default_server; listen [::]:80 default_server ipv6only=on; location /api/ { rewrite ^/api/(.*)$ /api/$1 break; proxy_pass http://backend/; } location / { proxy_pass http://frontend/; } } gateway: image: nginx container_name: gateway volumes: - ./app.template:/etc/nginx/conf.d/default.conf - ./nginx.template:/etc/nginx/nginx.conf ports: - "80:80" - "443:443" depends_on: - apis networks: - front-net
  • 14.
    Vagrant.configure(2) do |config| config.vm.box= "ubuntu/trusty64" config.vm.provision "shell", inline: <<-SHELL sudo apt-get update sudo apt-get install -y whois git unzip wget curl sudo useradd -m -p `mkpasswd password` -s /bin/bash dev sudo usermod -a -G sudo dev SHELL config.vm.provision :shell, path: "./ops/init.sh" config.vm.provider "virtualbox" do |vb| vb.gui = false vb.memory = 1024 vb.cpus = 2 end config.vm.define "nodeone" do |n1| n1.vm.hostname = "nodeone" n1.vm.network "private_network", ip: "172.20.20.20" n1.vm.provision :shell, path: "./ops/nodeone.sh" end config.vm.define "nodetwo" do |n2| n2.vm.hostname = "nodetwo" n2.vm.network "private_network", ip: "172.20.20.21" n2.vm.provision :shell, path: "./ops/nodetwo.sh" end FROM mhart/alpine-node:4.4 MAINTAINER Nguyen Sy Thanh Son RUN npm install -g pm2 WORKDIR /build COPY ./ /build EXPOSE 3000 RUN chmod +x /build/entrypoint.sh RUN cp /build/config/default.json /build/config/local.json ENTRYPOINT ["/build/entrypoint.sh"]
  • 15.
  • 16.
  • 17.