SlideShare a Scribd company logo
Converting Your Dev Environment
to a Docker Stack
Dana Luther
https://joind.in/talk/ab10a
https://github.com/DanaLuther/DevDockerStackSampleZCOE
Consolidated Work Stack
Friend A
PHP 5.6
Apache
MySQL
Cause B
PHP 7.1 FPM
NGINX
MySQL
PHP 7.0 FPM
NGINX
MySQL
Licensed
Application
Client D
PHP 7.1 FPM
NGINX
MySQL 5.3
Client C
PHP 5.6 FPM
NGINX
MySQL 5.2
PHP 5.6
Apache
MySQL 5.3
Client A
Client B
PHP 7.1
Apache
MySQL 5.4
THERE IS A
BETTER
WAY
VM
PHP 7.0 FPM
NGINX
MySQL
So, how does that work???
🤔
?
? ?
?
docker-compose.yml
Docker Compose Version
Services in the Stack
Configurations,
Secrets,
Storage Volumes,
etc.
Version: “3.4”
services:
nginx:
image: nginx
command: [
'sh',
'-c',
"exec nginx -g 'daemon off;'"
]
…
php:
image: php:7.2-fpm
…
network:
web_frontend
config:
nginx.conf:
file: ./nginx/nginx.conf
volumes:
…https://docs.docker.com/compose/compose-file/
SIDEBAR:The Docker Hierarchy
Image Container Service Stack
Node Swarm
> docker stack deploy …
Swarm
NODE 1
NODE 2
ETC.
PHP 1 MySQL
NGINX PHP 2
SIDEBAR:Docker Command Syntax
docker (object) (action) (args)
> docker container ls
> docker image ls
> docker service ls
> docker volume ls
image
container
stack
service
config
network
node
plugin
swarm
Objects
ls
ps
prune
inspect
create
remove / rm
Common
Actions
The swarm …
Node
Manager
Node
Worker
Node
Worker
Node
Worker
Node
Manager
A SWARM OF ONE
> docker swarm init
⚠ Common “Gotcha”
Swarm init — ONE TIME ONLY
* THE SWARM PERSISTS *
> docker swarm leave
> docker swarm leave —force
POPQUIZ! A. What’s the difference
between a container and a
service?
B. What’s the difference
between a service and a
stack?
Commonly Useful Images:
mysql
php
nginx
httpd
node
redis
wordpress
composer
memcached
alpine
postgres
busybox
phpmyadmin/phpmyadmin
https://store.docker.com
> docker image pull mysql:latest
BONUS POP QUIZ!
How do you pull an image manually?
Images for Automated Testing
selenium/standalone-chrome-debug
selenium/standalone-firefox-debug:2.53.0
acceptance.suite.yml
docker-compose.yml
SIDEBAR:Legacy images, containers, volumes
> docker image prune
> docker container prune
> docker (whatever) prune
version: “3.4”
services:
nginx:
image: nginx
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “Nginx Service”
volumes:
- ./public_html:/var/ www/html
configs:
- source: mysite
target: /etc/nginx/conf.d/mysite.conf
ports:
- “80:80”
- “443:443”
depends_on:
- php
- db
labels:
com.envisageinternational.desc: “Nginx Container”
command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”]
db:
image: mysql
ports:
- “3306:3306”
networks:
- web
secrets:
- db_pwd
deploy:
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [ node.role == manager ]
environment:
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd
php:
image: php:7.0-fpm
networks:
- web
depends_on:
- db
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-FPM Service”
ports:
- “9000:9000”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-FPM Container”
php-cli:
image: php:7.0-cli
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-CLI Service”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-CLI Container”
command: [‘bin/sh’, ‘-c’, “sleep infinity”]
networks:
web:
configs:
mysite:
file: ./mysite.conf
secrets:
db_pwd:
file: ./root_db_password.txt
PHP 7.0 FPM
NGINX
MySQL
version: “3.4”
services:
nginx:
image: nginx
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “Nginx Service”
volumes:
- ./public_html:/var/ www/html
configs:
- source: mysite
target: /etc/nginx/conf.d/mysite.conf
ports:
- “80:80”
- “443:443”
depends_on:
- php
- db
labels:
com.envisageinternational.desc: “Nginx Container”
command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”]
db:
image: mysql
ports:
- “3306:3306”
networks:
- web
secrets:
- db_pwd
deploy:
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [ node.role == manager ]
environment:
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd
php:
image: php:7.0-fpm
networks:
- web
depends_on:
- db
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-FPM Service”
ports:
- “9000:9000”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-FPM Container”
php-cli:
image: php:7.0-cli
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-CLI Service”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-CLI Container”
command: [‘bin/sh’, ‘-c’, “sleep infinity”]
networks:
web:
configs:
mysite:
file: ./mysite.conf
secrets:
db_pwd:
file: ./root_db_password.txt
PHP 7.0 FPM
NGINX
MySQL
version: “3.4”
services:
nginx:
image: nginx
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “Nginx Service”
volumes:
- ./public_html:/var/ www/html
configs:
- source: mysite
target: /etc/nginx/conf.d/mysite.conf
ports:
- “80:80”
- “443:443”
depends_on:
- php
- db
labels:
com.envisageinternational.desc: “Nginx Container”
command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”]
db:
image: mysql
ports:
- “3306:3306”
networks:
- web
secrets:
- db_pwd
deploy:
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [ node.role == manager ]
environment:
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd
php:
image: php:7.0-fpm
networks:
- web
depends_on:
- db
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-FPM Service”
ports:
- “9000:9000”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-FPM Container”
php-cli:
image: php:7.0-cli
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-CLI Service”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-CLI Container”
command: [‘bin/sh’, ‘-c’, “sleep infinity”]
networks:
web:
configs:
mysite:
file: ./mysite.conf
secrets:
db_pwd:
file: ./root_db_password.txt
PHP 7.0 FPM
NGINX
MySQL
SIDEBAR:LABELS — use them everywhere!
🤔
?
? ?
? The -f toggle
-f name=vm_php
-f label=com.envisage.desc=php
version: “3.4”
services:
nginx:
image: nginx
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “Nginx Service”
volumes:
- ./public_html:/var/ www/html
configs:
- source: mysite
target: /etc/nginx/conf.d/mysite.conf
ports:
- “80:80”
- “443:443”
depends_on:
- php
- db
labels:
com.envisageinternational.desc: “Nginx Container”
command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”]
db:
image: mysql
ports:
- “3306:3306”
networks:
- web
secrets:
- db_pwd
deploy:
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [ node.role == manager ]
environment:
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd
php:
image: php:7.0-fpm
networks:
- web
depends_on:
- db
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-FPM Service”
ports:
- “9000:9000”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-FPM Container”
php-cli:
image: php:7.0-cli
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-CLI Service”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-CLI Container”
command: [‘bin/sh’, ‘-c’, “sleep infinity”]
networks:
web:
configs:
mysite:
file: ./mysite.conf
secrets:
db_pwd:
file: ./root_db_password.txt
PHP 7.0 FPM
NGINX
MySQL
Volume Example for php
php:
volumes:
- ./public_html:/var/ www/html
Local path relative
to the file
Path location within
the container
Using named storage volumes
Volumes:
pub_html:
external: true
…
php:
volumes:
- pub_html:/var/ www/html
Volume name
Path location
within the container
> docker volume create pub_html /
—opt type=none /
—opt o=bind /
—opt device=/Volumes/E/site/
—label “com.envisage.desc=Site”
⚠ Common “Gotcha”
* BEWARE WINDOWS PATHS *
C:DockerDriveSite
/C/DockerDrives/Site
/host_mnt/c/DockerDrives/Site
//c/DockerDrives/Site
Windows
LCOW
Volume
Path
Converting your DEV Environment to a Docker Stack - ZCOE18
POPQUIZ! A. What is the command to
initialize a swarm?
B. What is the command to
deploy a docker stack?
> docker stack deploy -c docker-compose.yml vm
🤔
?
? ?
?
> docker service ls
> docker stack ps vm
> docker service logs vm_db
Converting your DEV Environment to a Docker Stack - ZCOE18
Want to see it in action?
> docker service logs vm_nginx -f
⚠ Common “Gotcha”
localhost:3306 db:3306
upstream fastcgi {
server 127.0.0.1:9000
}
upstream fastcgi {
server php:9000
}
Ok, great! But … 	 ¯_(ツ)_/¯
My production server
has lots of configurations
that have been customized…
php/conf.d/*
my.cnf
nginx.conf
nginx/conf.d/*
version: “3.4”
services:
nginx:
image: nginx
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “Nginx Service”
volumes:
- ./public_html:/var/ www/html
configs:
- source: mysite
target: /etc/nginx/conf.d/mysite.conf
ports:
- “80:80”
- “443:443”
depends_on:
- php
- db
labels:
com.envisageinternational.desc: “Nginx Container”
command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”]
db:
image: mysql
ports:
- “3306:3306”
networks:
- web
secrets:
- db_pwd
deploy:
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [ node.role == manager ]
environment:
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd
php:
image: php:7.0-fpm
networks:
- web
depends_on:
- db
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-FPM Service”
ports:
- “9000:9000”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-FPM Container”
php-cli:
image: php:7.0-cli
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-CLI Service”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-CLI Container”
command: [‘bin/sh’, ‘-c’, “sleep infinity”]
networks:
web:
configs:
mysite:
file: ./mysite.conf
secrets:
db_pwd:
file: ./root_db_password.txt
PHP 7.0 FPM
NGINX
MySQL
Config: mysite
> docker config inspect vm_mysite
version: “3.4”
services:
nginx:
image: nginx
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “Nginx Service”
volumes:
- ./public_html:/var/ www/html
configs:
- source: mysite
target: /etc/nginx/conf.d/mysite.conf
ports:
- “80:80”
- “443:443”
depends_on:
- php
- db
labels:
com.envisageinternational.desc: “Nginx Container”
command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”]
db:
image: mysql
ports:
- “3306:3306”
networks:
- web
secrets:
- db_pwd
deploy:
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [ node.role == manager ]
environment:
- MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd
php:
image: php:7.0-fpm
networks:
- web
depends_on:
- db
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-FPM Service”
ports:
- “9000:9000”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-FPM Container”
php-cli:
image: php:7.0-cli
networks:
- web
deploy:
replicas: 1
restart_policy:
condition: on-failure
labels:
com.envisageinternational.desc: “PHP-CLI Service”
volumes:
- ./public_html:/var/ www/html
labels:
com.envisageinternational.desc: “PHP-CLI Container”
command: [‘bin/sh’, ‘-c’, “sleep infinity”]
networks:
web:
configs:
mysite:
file: ./mysite.conf
secrets:
db_pwd:
file: ./root_db_password.txt
PHP 7.0 FPM
NGINX
MySQL
Secret: db_pwd
> docker secret inspect zcoe_db_pwd
⚠ Common “Gotcha”
> docker config create mysite.2 ./mysite.conf
> docker service update —config-rm vm_mysite 
—config-add source:mysite.2,target=/etc/nginx/default.conf 
vm_nginx
> docker config ls
Converting your DEV Environment to a Docker Stack - ZCOE18
Done with the project for now?
> docker stack rm vm
POPQUIZ! A. How do you check the
replication status of services?
B. How do you check for error
messages on the stack?
> docker stack ps vm —no-trunc
BONUS POINT
How do you avoid truncating the error message?
Same project … multiple production
targets?
docker-compose.yml
docker-compose-clientA.yml
docker-compose-clientB.yml
POPQUIZ! A. How do you filter a list of
docker objects (services,
containers, images, etc)
SIDEBAR:The $( ) magic with -q -l -f
-q Quiet (ID only)
-l Last Updated Only (1 result)
-f Filter (you remember this)
> docker container ls -q -l
> docker container exec -it $(docker ps -q -l -f name=vm_web) bash

More Related Content

What's hot (20)

PDF
Writing & Sharing Great Modules on the Puppet Forge
Puppet
 
PDF
parenscript-tutorial
tutorialsruby
 
PDF
Plongée dans l'écosystème Laravel
Gabriel Pillet 🐙
 
PDF
Create dynamic sites with PHP & MySQL
kangaro10a
 
PDF
Modern PHP Ch7 Provisioning Guide 導讀
Chen Cheng-Wei
 
PDF
Magento 2 Capistrano Deploy
Duke Dao
 
PDF
Developing MIPS Exploits to Hack Routers
Onur Alanbel
 
PDF
Leverage HTTP to deliver cacheable websites - Codemotion Rome 2018
Thijs Feryn
 
PDF
Leverage HTTP to deliver cacheable websites - Thijs Feryn - Codemotion Rome 2018
Codemotion
 
PDF
Troubleshooting the Puppet Enterprise Stack
Puppet
 
PDF
Why we choose Symfony2
Merixstudio
 
PDF
Care and feeding notes
Perrin Harkins
 
PPTX
Performance tips for Symfony2 & PHP
Max Romanovsky
 
PDF
Die .htaccess richtig nutzen
Walter Ebert
 
PDF
Nuts and Bolts of WebSocket Devoxx 2014
Arun Gupta
 
PDF
Php through the eyes of a hoster
Combell NV
 
KEY
Php Power Tools
Michelangelo van Dam
 
PPT
ServiceMix 4 -- Integrating OSGi with JBI
Gert Vanthienen
 
PDF
PECL Picks - Extensions to make your life better
ZendCon
 
PDF
ApacheConNA 2015: Apache httpd 2.4 Reverse Proxy
Jim Jagielski
 
Writing & Sharing Great Modules on the Puppet Forge
Puppet
 
parenscript-tutorial
tutorialsruby
 
Plongée dans l'écosystème Laravel
Gabriel Pillet 🐙
 
Create dynamic sites with PHP & MySQL
kangaro10a
 
Modern PHP Ch7 Provisioning Guide 導讀
Chen Cheng-Wei
 
Magento 2 Capistrano Deploy
Duke Dao
 
Developing MIPS Exploits to Hack Routers
Onur Alanbel
 
Leverage HTTP to deliver cacheable websites - Codemotion Rome 2018
Thijs Feryn
 
Leverage HTTP to deliver cacheable websites - Thijs Feryn - Codemotion Rome 2018
Codemotion
 
Troubleshooting the Puppet Enterprise Stack
Puppet
 
Why we choose Symfony2
Merixstudio
 
Care and feeding notes
Perrin Harkins
 
Performance tips for Symfony2 & PHP
Max Romanovsky
 
Die .htaccess richtig nutzen
Walter Ebert
 
Nuts and Bolts of WebSocket Devoxx 2014
Arun Gupta
 
Php through the eyes of a hoster
Combell NV
 
Php Power Tools
Michelangelo van Dam
 
ServiceMix 4 -- Integrating OSGi with JBI
Gert Vanthienen
 
PECL Picks - Extensions to make your life better
ZendCon
 
ApacheConNA 2015: Apache httpd 2.4 Reverse Proxy
Jim Jagielski
 

Similar to Converting your DEV Environment to a Docker Stack - ZCOE18 (20)

PDF
Converting Your Dev Environment to a Docker Stack - Cascadia
Dana Luther
 
PDF
Converting Your Dev Environment to a Docker Stack - php[world]
Dana Luther
 
PDF
Convert Your Dev Environment to a Docker Stack - PHP Tek 2025.pdf
Dana Luther
 
PDF
Web scale infrastructures with kubernetes and flannel
purpleocean
 
DOCX
How to install and configure LEMP stack
RootGate
 
PDF
Docker summit 2015: 以 Docker Swarm 打造多主機叢集環境
謝 宗穎
 
PDF
Infrastructure = code - 1 year later
Christian Ortner
 
PDF
Php through the eyes of a hoster phpbnl11
Combell NV
 
PDF
Automating Container Deployments on Virtualization with Ansible: OpenShift on...
Laurent Domb
 
PDF
Docker for mac & local developer environment optimization
Radek Baczynski
 
PDF
Drupaljam 2017 - Deploying Drupal 8 onto Hosted Kubernetes in Google Cloud
Dropsolid
 
PDF
DevOps and Hybrid Applications: What You Need to Know
DevOps.com
 
PPTX
Running Docker in Development & Production (#ndcoslo 2015)
Ben Hall
 
PPTX
Fully Automate Application Delivery with Puppet and F5 - PuppetConf 2014
Puppet
 
PPTX
Docker Security workshop slides
Docker, Inc.
 
PPTX
How to create a multi tenancy for an interactive data analysis
Tiago Simões
 
PDF
The Enterprise Wor/d/thy/Press
Jeroen van Dijk
 
PPTX
PHP on Heroku: Deploying and Scaling Apps in the Cloud
Salesforce Developers
 
PDF
Automation day red hat ansible
Rodrigo Missiaggia
 
PDF
Hands on Docker - Launch your own LEMP or LAMP stack
Dana Luther
 
Converting Your Dev Environment to a Docker Stack - Cascadia
Dana Luther
 
Converting Your Dev Environment to a Docker Stack - php[world]
Dana Luther
 
Convert Your Dev Environment to a Docker Stack - PHP Tek 2025.pdf
Dana Luther
 
Web scale infrastructures with kubernetes and flannel
purpleocean
 
How to install and configure LEMP stack
RootGate
 
Docker summit 2015: 以 Docker Swarm 打造多主機叢集環境
謝 宗穎
 
Infrastructure = code - 1 year later
Christian Ortner
 
Php through the eyes of a hoster phpbnl11
Combell NV
 
Automating Container Deployments on Virtualization with Ansible: OpenShift on...
Laurent Domb
 
Docker for mac & local developer environment optimization
Radek Baczynski
 
Drupaljam 2017 - Deploying Drupal 8 onto Hosted Kubernetes in Google Cloud
Dropsolid
 
DevOps and Hybrid Applications: What You Need to Know
DevOps.com
 
Running Docker in Development & Production (#ndcoslo 2015)
Ben Hall
 
Fully Automate Application Delivery with Puppet and F5 - PuppetConf 2014
Puppet
 
Docker Security workshop slides
Docker, Inc.
 
How to create a multi tenancy for an interactive data analysis
Tiago Simões
 
The Enterprise Wor/d/thy/Press
Jeroen van Dijk
 
PHP on Heroku: Deploying and Scaling Apps in the Cloud
Salesforce Developers
 
Automation day red hat ansible
Rodrigo Missiaggia
 
Hands on Docker - Launch your own LEMP or LAMP stack
Dana Luther
 
Ad

More from Dana Luther (9)

PDF
Enums In the Wild at PHP[tek] Conference 2025
Dana Luther
 
PDF
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Dana Luther
 
PDF
How to analyze your codebase with Exakat using Docker - Longhorn PHP
Dana Luther
 
PDF
Keep it Secret, Keep it Safe - Docker Secrets and DI
Dana Luther
 
PDF
Integrated Feature Management - Using Feature Flags - PHPSerbia
Dana Luther
 
PDF
Integrated Feature Management - Using Feature Flags - MidwestPHP
Dana Luther
 
PDF
Integrated Feature Management - Using Feature Flags - SunshinePHP
Dana Luther
 
PDF
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP
Dana Luther
 
PDF
Code Coverage for Total Security in Application Migrations
Dana Luther
 
Enums In the Wild at PHP[tek] Conference 2025
Dana Luther
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Dana Luther
 
How to analyze your codebase with Exakat using Docker - Longhorn PHP
Dana Luther
 
Keep it Secret, Keep it Safe - Docker Secrets and DI
Dana Luther
 
Integrated Feature Management - Using Feature Flags - PHPSerbia
Dana Luther
 
Integrated Feature Management - Using Feature Flags - MidwestPHP
Dana Luther
 
Integrated Feature Management - Using Feature Flags - SunshinePHP
Dana Luther
 
Hands on Docker - Launch your own LEMP or LAMP stack - SunshinePHP
Dana Luther
 
Code Coverage for Total Security in Application Migrations
Dana Luther
 
Ad

Recently uploaded (20)

PPTX
Research Design - Report on seminar in thesis writing. PPTX
arvielobos1
 
PDF
DevOps Design for different deployment options
henrymails
 
PPTX
PE introd.pptxfrgfgfdgfdgfgrtretrt44t444
nepmithibai2024
 
PPTX
sajflsajfljsdfljslfjslfsdfas;fdsfksadfjlsdflkjslgfs;lfjlsajfl;sajfasfd.pptx
theknightme
 
PPTX
Cost_of_Quality_Presentation_Software_Engineering.pptx
farispalayi
 
PDF
𝐁𝐔𝐊𝐓𝐈 𝐊𝐄𝐌𝐄𝐍𝐀𝐍𝐆𝐀𝐍 𝐊𝐈𝐏𝐄𝐑𝟒𝐃 𝐇𝐀𝐑𝐈 𝐈𝐍𝐈 𝟐𝟎𝟐𝟓
hokimamad0
 
PPT
Computer Securityyyyyyyy - Chapter 1.ppt
SolomonSB
 
PDF
The Complete Guide to Chrome Net Internals DNS – 2025
Orage Technologies
 
PPTX
西班牙武康大学毕业证书{UCAMOfferUCAM成绩单水印}原版制作
Taqyea
 
PDF
How to Fix Error Code 16 in Adobe Photoshop A Step-by-Step Guide.pdf
Becky Lean
 
PDF
Technical Guide to Build a Successful Shopify Marketplace from Scratch.pdf
CartCoders
 
PDF
The Power and Impact of Promotion most useful
RajaBilal42
 
PPTX
Random Presentation By Fuhran Khalil uio
maniieiish
 
PPTX
ipv6 very very very very vvoverview.pptx
eyala75
 
PPTX
原版西班牙莱昂大学毕业证(León毕业证书)如何办理
Taqyea
 
PDF
Build Fast, Scale Faster: Milvus vs. Zilliz Cloud for Production-Ready AI
Zilliz
 
PDF
Digital Security in 2025 with Adut Angelina
The ClarityDesk
 
PPT
introductio to computers by arthur janry
RamananMuthukrishnan
 
PPTX
英国假毕业证诺森比亚大学成绩单GPA修改UNN学生卡网上可查学历成绩单
Taqyea
 
PPT
Computer Securityyyyyyyy - Chapter 2.ppt
SolomonSB
 
Research Design - Report on seminar in thesis writing. PPTX
arvielobos1
 
DevOps Design for different deployment options
henrymails
 
PE introd.pptxfrgfgfdgfdgfgrtretrt44t444
nepmithibai2024
 
sajflsajfljsdfljslfjslfsdfas;fdsfksadfjlsdflkjslgfs;lfjlsajfl;sajfasfd.pptx
theknightme
 
Cost_of_Quality_Presentation_Software_Engineering.pptx
farispalayi
 
𝐁𝐔𝐊𝐓𝐈 𝐊𝐄𝐌𝐄𝐍𝐀𝐍𝐆𝐀𝐍 𝐊𝐈𝐏𝐄𝐑𝟒𝐃 𝐇𝐀𝐑𝐈 𝐈𝐍𝐈 𝟐𝟎𝟐𝟓
hokimamad0
 
Computer Securityyyyyyyy - Chapter 1.ppt
SolomonSB
 
The Complete Guide to Chrome Net Internals DNS – 2025
Orage Technologies
 
西班牙武康大学毕业证书{UCAMOfferUCAM成绩单水印}原版制作
Taqyea
 
How to Fix Error Code 16 in Adobe Photoshop A Step-by-Step Guide.pdf
Becky Lean
 
Technical Guide to Build a Successful Shopify Marketplace from Scratch.pdf
CartCoders
 
The Power and Impact of Promotion most useful
RajaBilal42
 
Random Presentation By Fuhran Khalil uio
maniieiish
 
ipv6 very very very very vvoverview.pptx
eyala75
 
原版西班牙莱昂大学毕业证(León毕业证书)如何办理
Taqyea
 
Build Fast, Scale Faster: Milvus vs. Zilliz Cloud for Production-Ready AI
Zilliz
 
Digital Security in 2025 with Adut Angelina
The ClarityDesk
 
introductio to computers by arthur janry
RamananMuthukrishnan
 
英国假毕业证诺森比亚大学成绩单GPA修改UNN学生卡网上可查学历成绩单
Taqyea
 
Computer Securityyyyyyyy - Chapter 2.ppt
SolomonSB
 

Converting your DEV Environment to a Docker Stack - ZCOE18

  • 1. Converting Your Dev Environment to a Docker Stack Dana Luther https://joind.in/talk/ab10a https://github.com/DanaLuther/DevDockerStackSampleZCOE
  • 2. Consolidated Work Stack Friend A PHP 5.6 Apache MySQL Cause B PHP 7.1 FPM NGINX MySQL PHP 7.0 FPM NGINX MySQL
  • 3. Licensed Application Client D PHP 7.1 FPM NGINX MySQL 5.3 Client C PHP 5.6 FPM NGINX MySQL 5.2 PHP 5.6 Apache MySQL 5.3 Client A Client B PHP 7.1 Apache MySQL 5.4
  • 6. So, how does that work??? 🤔 ? ? ? ?
  • 7. docker-compose.yml Docker Compose Version Services in the Stack Configurations, Secrets, Storage Volumes, etc. Version: “3.4” services: nginx: image: nginx command: [ 'sh', '-c', "exec nginx -g 'daemon off;'" ] … php: image: php:7.2-fpm … network: web_frontend config: nginx.conf: file: ./nginx/nginx.conf volumes: …https://docs.docker.com/compose/compose-file/
  • 8. SIDEBAR:The Docker Hierarchy Image Container Service Stack Node Swarm
  • 9. > docker stack deploy … Swarm NODE 1 NODE 2 ETC. PHP 1 MySQL NGINX PHP 2
  • 10. SIDEBAR:Docker Command Syntax docker (object) (action) (args) > docker container ls > docker image ls > docker service ls > docker volume ls image container stack service config network node plugin swarm Objects ls ps prune inspect create remove / rm Common Actions
  • 12. Node Manager A SWARM OF ONE > docker swarm init
  • 13. ⚠ Common “Gotcha” Swarm init — ONE TIME ONLY * THE SWARM PERSISTS * > docker swarm leave > docker swarm leave —force
  • 14. POPQUIZ! A. What’s the difference between a container and a service? B. What’s the difference between a service and a stack?
  • 16. Images for Automated Testing selenium/standalone-chrome-debug selenium/standalone-firefox-debug:2.53.0 acceptance.suite.yml docker-compose.yml
  • 17. SIDEBAR:Legacy images, containers, volumes > docker image prune > docker container prune > docker (whatever) prune
  • 18. version: “3.4” services: nginx: image: nginx networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “Nginx Service” volumes: - ./public_html:/var/ www/html configs: - source: mysite target: /etc/nginx/conf.d/mysite.conf ports: - “80:80” - “443:443” depends_on: - php - db labels: com.envisageinternational.desc: “Nginx Container” command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”] db: image: mysql ports: - “3306:3306” networks: - web secrets: - db_pwd deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [ node.role == manager ] environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd php: image: php:7.0-fpm networks: - web depends_on: - db deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-FPM Service” ports: - “9000:9000” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-FPM Container” php-cli: image: php:7.0-cli networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-CLI Service” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-CLI Container” command: [‘bin/sh’, ‘-c’, “sleep infinity”] networks: web: configs: mysite: file: ./mysite.conf secrets: db_pwd: file: ./root_db_password.txt PHP 7.0 FPM NGINX MySQL
  • 19. version: “3.4” services: nginx: image: nginx networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “Nginx Service” volumes: - ./public_html:/var/ www/html configs: - source: mysite target: /etc/nginx/conf.d/mysite.conf ports: - “80:80” - “443:443” depends_on: - php - db labels: com.envisageinternational.desc: “Nginx Container” command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”] db: image: mysql ports: - “3306:3306” networks: - web secrets: - db_pwd deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [ node.role == manager ] environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd php: image: php:7.0-fpm networks: - web depends_on: - db deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-FPM Service” ports: - “9000:9000” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-FPM Container” php-cli: image: php:7.0-cli networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-CLI Service” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-CLI Container” command: [‘bin/sh’, ‘-c’, “sleep infinity”] networks: web: configs: mysite: file: ./mysite.conf secrets: db_pwd: file: ./root_db_password.txt PHP 7.0 FPM NGINX MySQL
  • 20. version: “3.4” services: nginx: image: nginx networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “Nginx Service” volumes: - ./public_html:/var/ www/html configs: - source: mysite target: /etc/nginx/conf.d/mysite.conf ports: - “80:80” - “443:443” depends_on: - php - db labels: com.envisageinternational.desc: “Nginx Container” command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”] db: image: mysql ports: - “3306:3306” networks: - web secrets: - db_pwd deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [ node.role == manager ] environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd php: image: php:7.0-fpm networks: - web depends_on: - db deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-FPM Service” ports: - “9000:9000” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-FPM Container” php-cli: image: php:7.0-cli networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-CLI Service” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-CLI Container” command: [‘bin/sh’, ‘-c’, “sleep infinity”] networks: web: configs: mysite: file: ./mysite.conf secrets: db_pwd: file: ./root_db_password.txt PHP 7.0 FPM NGINX MySQL
  • 21. SIDEBAR:LABELS — use them everywhere! 🤔 ? ? ? ? The -f toggle -f name=vm_php -f label=com.envisage.desc=php
  • 22. version: “3.4” services: nginx: image: nginx networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “Nginx Service” volumes: - ./public_html:/var/ www/html configs: - source: mysite target: /etc/nginx/conf.d/mysite.conf ports: - “80:80” - “443:443” depends_on: - php - db labels: com.envisageinternational.desc: “Nginx Container” command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”] db: image: mysql ports: - “3306:3306” networks: - web secrets: - db_pwd deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [ node.role == manager ] environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd php: image: php:7.0-fpm networks: - web depends_on: - db deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-FPM Service” ports: - “9000:9000” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-FPM Container” php-cli: image: php:7.0-cli networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-CLI Service” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-CLI Container” command: [‘bin/sh’, ‘-c’, “sleep infinity”] networks: web: configs: mysite: file: ./mysite.conf secrets: db_pwd: file: ./root_db_password.txt PHP 7.0 FPM NGINX MySQL
  • 23. Volume Example for php php: volumes: - ./public_html:/var/ www/html Local path relative to the file Path location within the container
  • 24. Using named storage volumes Volumes: pub_html: external: true … php: volumes: - pub_html:/var/ www/html Volume name Path location within the container > docker volume create pub_html / —opt type=none / —opt o=bind / —opt device=/Volumes/E/site/ —label “com.envisage.desc=Site”
  • 25. ⚠ Common “Gotcha” * BEWARE WINDOWS PATHS * C:DockerDriveSite /C/DockerDrives/Site /host_mnt/c/DockerDrives/Site //c/DockerDrives/Site Windows LCOW Volume Path
  • 27. POPQUIZ! A. What is the command to initialize a swarm? B. What is the command to deploy a docker stack?
  • 28. > docker stack deploy -c docker-compose.yml vm 🤔 ? ? ? ? > docker service ls > docker stack ps vm
  • 29. > docker service logs vm_db
  • 31. Want to see it in action? > docker service logs vm_nginx -f
  • 32. ⚠ Common “Gotcha” localhost:3306 db:3306 upstream fastcgi { server 127.0.0.1:9000 } upstream fastcgi { server php:9000 }
  • 33. Ok, great! But … ¯_(ツ)_/¯ My production server has lots of configurations that have been customized… php/conf.d/* my.cnf nginx.conf nginx/conf.d/*
  • 34. version: “3.4” services: nginx: image: nginx networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “Nginx Service” volumes: - ./public_html:/var/ www/html configs: - source: mysite target: /etc/nginx/conf.d/mysite.conf ports: - “80:80” - “443:443” depends_on: - php - db labels: com.envisageinternational.desc: “Nginx Container” command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”] db: image: mysql ports: - “3306:3306” networks: - web secrets: - db_pwd deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [ node.role == manager ] environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd php: image: php:7.0-fpm networks: - web depends_on: - db deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-FPM Service” ports: - “9000:9000” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-FPM Container” php-cli: image: php:7.0-cli networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-CLI Service” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-CLI Container” command: [‘bin/sh’, ‘-c’, “sleep infinity”] networks: web: configs: mysite: file: ./mysite.conf secrets: db_pwd: file: ./root_db_password.txt PHP 7.0 FPM NGINX MySQL
  • 35. Config: mysite > docker config inspect vm_mysite
  • 36. version: “3.4” services: nginx: image: nginx networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “Nginx Service” volumes: - ./public_html:/var/ www/html configs: - source: mysite target: /etc/nginx/conf.d/mysite.conf ports: - “80:80” - “443:443” depends_on: - php - db labels: com.envisageinternational.desc: “Nginx Container” command: [‘sh’,'-c',"exec nginx -g 'daemon off;’”] db: image: mysql ports: - “3306:3306” networks: - web secrets: - db_pwd deploy: replicas: 1 restart_policy: condition: on-failure placement: constraints: [ node.role == manager ] environment: - MYSQL_ROOT_PASSWORD_FILE=/run/secrets/db_pwd php: image: php:7.0-fpm networks: - web depends_on: - db deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-FPM Service” ports: - “9000:9000” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-FPM Container” php-cli: image: php:7.0-cli networks: - web deploy: replicas: 1 restart_policy: condition: on-failure labels: com.envisageinternational.desc: “PHP-CLI Service” volumes: - ./public_html:/var/ www/html labels: com.envisageinternational.desc: “PHP-CLI Container” command: [‘bin/sh’, ‘-c’, “sleep infinity”] networks: web: configs: mysite: file: ./mysite.conf secrets: db_pwd: file: ./root_db_password.txt PHP 7.0 FPM NGINX MySQL
  • 37. Secret: db_pwd > docker secret inspect zcoe_db_pwd
  • 38. ⚠ Common “Gotcha” > docker config create mysite.2 ./mysite.conf > docker service update —config-rm vm_mysite —config-add source:mysite.2,target=/etc/nginx/default.conf vm_nginx > docker config ls
  • 40. Done with the project for now? > docker stack rm vm
  • 41. POPQUIZ! A. How do you check the replication status of services? B. How do you check for error messages on the stack? > docker stack ps vm —no-trunc BONUS POINT How do you avoid truncating the error message?
  • 42. Same project … multiple production targets? docker-compose.yml docker-compose-clientA.yml docker-compose-clientB.yml
  • 43. POPQUIZ! A. How do you filter a list of docker objects (services, containers, images, etc)
  • 44. SIDEBAR:The $( ) magic with -q -l -f -q Quiet (ID only) -l Last Updated Only (1 result) -f Filter (you remember this) > docker container ls -q -l > docker container exec -it $(docker ps -q -l -f name=vm_web) bash