Docker for Developers - php[tek] 2017
-
Upload
chris-tankersley -
Category
Technology
-
view
291 -
download
6
Transcript of Docker for Developers - php[tek] 2017
php[tek] 2017
Secret Docker Wifi
3
● SSID: phptek_docker● Password: phpdocker2017
● NAS: 172.16.0.40● Username: admin● Password: secretpassword
php[tek] 2017
What Is Docker?
“Docker is an open platform for developers and sysadmins to build, ship, and run distributed applications. Consisting of Docker Engine, a portable, lightweight runtime and packaging tool, and Docker Hub, a cloud service for sharing applications and automating workflows, Docker enables apps to be quickly assembled from components and eliminates the friction between development, QA, and production environments.”
4
https://www.docker.com/whatisdocker/
php[tek] 2017
Normal Bare-Metal Server
6
CPU RAM HD Network
Operating System
nginx PHP DB
CPU RAM I/O0
5
10
15
20
25
% Resources
php[tek] 2017
Normal Bare-Metal Server
7
CPU RAM HD Network
Operating System
nginx PHP DB
CPU RAM I/O0
5
10
15
20
25
30
35
App Resources
% Resources
php[tek] 2017
Virtual Machines
8
CPU RAM HD Network
Operating System
nginx PHP DB
Operating System
nginx PHP DB
Operating System
Hypervisor
CPU RAM I/O0
10
20
30
40
50
60
70
App Resources
% Resources
php[tek] 2017
Containers
9
CPU RAM HD Network
Operating System
nginxnginx PHP DB PHP DB
CPU RAM I/O0
5
10
15
20
25
30
35
40
45
App Resources
% Resources
php[tek] 2017
Containers vs VMs
CPU RAM I/O0
10
20
30
40
50
60
70
App Resources
% Resources
CPU RAM I/O0
5
10
15
20
25
30
35
40
45
App Resources
% Resources
php[tek] 2017
Containers Are Not New
• LXC (Linux Containers)• OpenVZ• Systemd-nspawn• BSD Jails• Solaris Zones• chroot
11
php[tek] 2017
Containers are just walled processes
12
Ubuntu Kernel
/+ bin/+ etc/+ dev/+ home/+ usr/+ var/+ lib/+ …
nginx
bash
/+ bin/+ etc/+ dev/+ home/+ usr/+ var/+ lib/+ …
php
php[tek] 2017
How does it work?
16
Uses a variety of existingContainer technologies
Server ContainersHyper-V Containers xhyve Virtualization
php[tek] 2017
Running a container
• `docker run` will run a container• This will not restart an existing container, just create a new one• docker run [options] IMAGE [command] [arguments]
• [options ]modify the docker process for this container• IMAGE is the image to use• [command] is the command to run inside the container• [arguments] are arguments for the command
19
php[tek] 2017
What’s Going On?
23
Ubuntu Kernel
/+ bin/+ etc/+ dev/+ home/+ usr/+ var/+ lib/+ …
nginx
bash
/+ bin/+ etc/+ dev/+ home/+ usr/+ var/+ lib/+ …
php
php[tek] 2017
Some Notes
• All three containers are 100% self contained• Docker containers share common ancestors, but keep their own files• `docker run` parameters:
• --rm – Destroy a container once it exits• -d – Run in the background (daemon mode)• -i – Run in interactive mode• --name – Give the container a name• -p [local port]:[container port] – Forward the local port to the container port
32
php[tek] 2017
Modifying a running container
• `docker exec` can run a command inside of an existing container• Use Volumes to share data
34
php[tek] 2017
Persistent Data with Volumes
• You can designate a volume with –v• Create a named volume with `volume create`• Volumes can be shared amongst containers• Volumes can mount data from the host system
35
php[tek] 2017
Mounting from the host isn’t perfect
• The container now has a window into your host machine• Permissions can get screwy if you are modifying in the container
• Most things it creates will be root by default, and you probably aren’t root on the host machine
• Host-mounted volumes are not portable at all• OSX and Hyper-V VMs have limited pathings to mount• OSX has poor I/O performance
41
php[tek] 2017
Named Data Volumes
• Creates a space that becomes persistent• Can be mounted anywhere inside your images• Have our app containers use the data volume to store data• Use ‘editor containers’ to go in and modify data when needed
42
php[tek] 2017
vim Tutorial
• vim is a Modal text editor• ESC will drop you back to default mode• :new /opt/webconfig/default to create a new file• In default mode, i will get us into interactive (edit) mode• :w to save a file• :q will quit
43
php[tek] 2017
Why go through the hassle?
• Data volumes are portable, depending on the driver• Data volumes are safer• Separates the app containers from data• Production can use a data volume, dev can use a host volume
• Our app containers stay small• Works directly with other tools
50
php[tek] 2017
Networking
• Docker can create multiple network “pools”• Each container gets an IP address• Containers can be attached to multiple networks• Docker network allow service discovery inside networks
52
php[tek] 2017
Legacy - Docker Links
• Legacy Links work with `--link`• Only works on the legacy “bridge” network• Doesn’t support service discovery
• Not worth it to use anymore
53
php[tek] 2017
Docker Networks
• Discreet IP pool for containers• Containers can be added and removed to the network at whim• Service discovery though ‘--network-alias’• Can be set up to work across hosts
54
php[tek] 2017
Inspect a container
docker inspect [options] CONTAINER_NAME
• Returns a JSON string with data about the container• Can also query• docker inspect -f “{{ .NetworkSettings.IPAddress }}” web_server
• Really handy for scripting out things like reverse proxies
61
php[tek] 2017
Work with images
• docker pull IMAGE – Pulls down an image before using• docker images – Lists all the images that are downloaded• docker rmi IMAGE – Deletes an image if it’s not being used
62
php[tek] 2017
Our Goals
• Not change our workflow (much)• Run PHP 7, Unit Tests, and webserver• Deploy “easily”
64
php[tek] 2017
Just try and run it
docker run -d --name d4dapp \
-v C:\drago\Projects\dockerfordevs-app:/var/www/ \
-p 8080:80
php:apache
65
php[tek] 2017
Checking Logs
• Containers log to stdout/stderr• Docker aggregates the logs• Can be viewed with docker logs
67
php[tek] 2017
Custom Images
• PHP images are pretty bare• Lots of times need to install extensions
69
php[tek] 2017
Dockerfile
• Dockerfile is the configuration steps for an image• Can be created from scratch, or based on another image• Allows you to add files, create default volumes, ports, etc• Can be used privately or pushed to Docker Hub
70
php[tek] 2017
Build it
docker build -t tag_name ./
• This runs through the Dockerfile and generates the image• We can now use the tag name to run the image
72
php[tek] 2017
Use the new image
docker run -d --name d4dapp \
-v C:\drago\Projects\dockerfordevs-app:/var/www/ \
-p 8080:80
d4dapp
75
php[tek] 2017
Running Composer
docker run --rm \
-v c:/Users/drago/.composer:/root/.composer \
-v c:/Users/drago/Projects/workshop:/app \
-v c:/Users/drago/.ssh:/root/.ssh \
composer/composer \
install
79
php[tek] 2017
docker/Dockerfile
FROM php:apache
RUN a2enmod rewrite\
&& docker-php-ext-install pdo_mysql
82
php[tek] 2017
Rebuild the container
$ docker rm -f d4dapp
$ docker run -d --name d4dapp \
-v C:\drago\Projects\dockerfordevs-app:/var/www/ \
-p 8080:80
d4dapp
84
php[tek] 2017
What is Docker Compose?
• Multi-container orchestration• A single config file holds all of your container info• Works with Docker Swarm and a few other tools, like Rancher
87
php[tek] 2017
Sample docker-compose.ymlversion: '2'
volumes: mysqldata: driver: local
services: d4dapp: build: ./docker/ volumes: - ./:/var/www/ ports: - 8080:80
mysqlserver: image: mysql environment: MYSQL_DATABASE: dockerfordevs MYSQL_ROOT_PASSWORD: 's3curep@assword' volumes: - mysqldata:/var/lib/mysql
88
php[tek] 2017
Config for DB now points to the service name
91
<?php
return [ 'debug' => true,
'config_cache_enabled' => false,
'db' => [ 'driver' => 'Pdo_Mysql', 'hostname' => 'mysqlserver', 'port' => '3306', 'database' => 'dockerfordevs', 'user' => 'root', 'password' => 's3curep@assword', ],];
php[tek] 2017
Install our DB Migration Software
docker run --rm \
-v c:/Users/drago/.composer:/root/.composer \
-v c:/Users/drago/Projects/workshop:/app \
-v c:/Users/drago/.ssh:/root/.ssh \
composer/composer \
require robmorgan/phinx
93
php[tek] 2017
Set up phinx
docker run --rm \
-v C:\Users\drago\Projects\dockerfordevs-app\:/app \
-w /app \
php:cli php vendor/bin/phinx init
94
php[tek] 2017
Run the migration
docker run --rm \
-v C:\Users\drago\Projects\dockerfordevs-app\:/app \
-w /app \
--network dockerfordevsapp_default \
php:cli php vendor/bin/phinx migrate
95
php[tek] 2017
Let’s use the existing container
docker-compose run --rm \
-v C:\Users\drago\Projects\dockerfordevs-app\:/app \
-w /app \
d4dapp php vendor/bin/phinx migrate
97
php[tek] 2017
Unit Testing
docker run --rm \
-v C:\Users\drago\Projects\dockerfordevs-app\:/app \
-w /app \
d4dapp php vendor/bin/phpunit -c .
100
php[tek] 2017
Build a service
service:
testrunner:
build: ./docker/
volumes:
- ./:/app
working_dir: /app
command: vendor/bin/phpunit -c .
102
What is Docker Machine?
• A provisioning tool that is used to set up a box with Docker• Used in Docker Toolbox to create the VM• Supports:• EC2• Azure• Digital Ocean• Hyper-V• OpenStack• Virtualbox• VMWare
php[tek] 2017 106
Why use it?
• Makes it very easy to spin up new boxes• Docker Machine handles all of the dirty stuff for you• Docker Toolbox users are already using it• Integrates with Docker Swarm
• It is not necessarily portable
php[tek] 2017 107
Dependencies
• Commit both composer.json and composer.lock files• Commit Dockerfiles to the same repo as the codebase
php[tek] 2017 116
Configuration
• Anything that is environment specific should move to environment vars• Makes it much easier to build and deploy code• Code cares less what external services it is talking to
php[tek] 2017 118
Use Environment Vars
• Can specify them one-by-one– docker run e VAR_NAME=value
• Can specify a file– docker run envfile=filename
• Can specify in docker-compose.yml
php[tek] 2017 119
Everything is “external”
• Never talk to local sockets• Don’t make a determination between “locally” hosted and third party• Easier to switch environments• Easier to scale up
php[tek] 2017 121
The Workflow
• Build step installs dependencies, compiles files, and generates a Build Artifact that can be deployed
– Does not contain any deployment configuration
• Release step pushes a Build Artifact into an environment– Runs DB migrations, anything needed to happen before running
• Run step runs the app fully in the environment
php[tek] 2017 123
Tips
• Build Artifact can be an image• Builds should be completely reproducible• Release always take a build artifact, never directly from the repo• Tag all your builds• Track all your releases
php[tek] 2017 124
Build Step - Start Small
• Build your application• Run composer• Run npm/bower• Build JS/CSS
• Use the compiled output to build an image with docker build• Push full image to private registry
php[tek] 2017 125
docker build
• Additional options to look at• -f, --file – Specify a different filename for the Dockerfile• --no-cache – Don’t use a cached layer• --pull – Always pull a new version of the image
php[tek] 2017 126
Sample usage
docker build \
--no-cache \
–f docker/php/phpserver.dockerfile \
–t prod_php /opt/builds/20161010
php[tek] 2017 127
phpserver.dockerfile
FROM php:fpm
RUN docker-php-ext-install pdo pdo_mysql
COPY ./ /var/www
php[tek] 2017 128
Built Into Docker
• One Process per container• Allows tools to scale just what needs to be scaled• Allows images to be swapped out as needed
php[tek] 2017 130
Built Into Docker (Again)
• Each container gets its own IP and exposes its own ports• Processes should already be talking over a network• Can work with service locators that are port-based
php[tek] 2017 132
Built Into Docker (Again) (Again)
• One Process per container• Scale up just the container that is needed• App should not care how many instances of each service are running
php[tek] 2017 135
Signals
• Docker starts containers fairly quickly• Applications should gracefully shut down, not just die• Docker sends a SIGTERM when shutting down a container• Your CLI apps may need to handle SIGTERM properly
– Cal Evans, “Signalling PHP”
php[tek] 2017 137
10. Dev/prod Parity
Keep development, staging, and production as similar as possible
php[tek] 2017 138
Logging in Docker
• Various logging options built in– JSON file (default)– Fluentd– Syslog– Journald– Gelf– Splunk– Aws– Etwlogs– Gcplogs
php[tek] 2017 140
Push logs remotely
• When possible, push Docker logs to a remote service– Container logs only exist while the container exists
• Allows logs to be viewed in a single place• No need to get into actual servers• Can host yourself, or pay for a SaaS• ELK stack is very popular
– Docker uses fluentd instead
php[tek] 2017 141
Setting up fluentdservices:
d4dapp:
build: ./docker/d4dapp
depends_on:
fluentd
volumes:
./:/var/www/
ports:
8080:80
logging:
driver: "fluentd"
options:
fluentdaddress: 127.0.0.1:24224
tag: apache.access
php[tek] 2017 142
Setting up fluentdservices:
fluentd:
build: docker/fluentd
depends_on:
elasticsearch
volumes:
./docker/fluentd/fluent.conf:/fluentd/etc/fluent.conf
ports:
24224:24224
24224:24224/udp
php[tek] 2017 143
Setting up fluentdFROM fluent/fluentd
RUN ["gem", "install", "fluentpluginelasticsearch", "nordoc", "nori", "version", "1.9.2"]
php[tek] 2017 144
Setting up ElasticSearch and Kibanaservices:
elasticsearch:
image: elasticsearch
expose:
9200
ports:
9200:9200
kibana:
image: kibana
depends_on:
elasticsearch
ports:
5601:5601
php[tek] 2017 146
Logging notes
• docker logs does not work with external logging, only JSON• This example can be cleaned up a bit• Kibana syntax can be a bit odd to work with
php[tek] 2017 148
Very Good for Small Deployments
• Can be used to augment your dev environment• Works well with Docker Machine
php[tek] 2017 152
Create a machine
docker-machine create --driver digitalocean \
--digital-ocean-access-token [token] \
sunshinephp2017
php[tek] 2017 153
Switch to the remote node
• Run docker-machine env sunshinephp2017
& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env sunshinephp2017 | Invoke-Expression
php[tek] 2017 155
Set up docker-compose
• Docker Compose allows multiple config files with -f• Have a base docker-compose.yml for Production• Add a secondary one for Development
php[tek] 2017 156
version: '2'
volumes:
mysqldata:
driver: local
services:
nginx:
build:
context: ./
dockerfile: ./nginx.dockerfile
ports:
- 80:80
- 443:443
phpserver:
build:
context: ./
dockerfile: ./phpserver.dockerfile
working_dir: /var/www/public
mysqlserver:
image: mysql
environment:
[redacted]
volumes:
- mysqldata:/var/lib/mysql
php[tek] 2017 157
docker-compose.yml
version: '2'
volumes:
mysqldata:
driver: local
services:
nginx:
image: nginx
volumes:
- ./output_dev:/var/www/public:ro
- ./app/nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./ssl:/etc/nginx/ssl/
phpserver:
build:
context: ./
dockerfile: ./phpserver.dockerfile
working_dir: /var/www/public
volumes:
- ./app:/var/www/
- ./vendor:/var/www/vendor
mysqlserver:
image: mysql
environment:
[redacted]
volumes:
- mysqldata:/var/lib/mysql
php[tek] 2017 158
docker-compose.dev.yml
When doing development
docker-compose \
–f docker-compose.yml \
–f docker-compose.dev.yml \
up -d
php[tek] 2017 159
Other Alternative – Variable Substitution
• Docker Compose allows variable substitution inside the file• Wrap variables in ${}• image: ${DEPLOY_VERSION}_php
php[tek] 2017 161
What is Swarm?
• Docker-supplied clustering• Define a series of services that can be deployed
php[tek] 2017 164
docker-compose.yml
version: '3'
services:
phpserver:
image: php:apache
ports:
- 80:80
php[tek] 2017 168
Deploy the stack
$ docker stack deploy -c docker-compose.yml myapp
Creating network myapp_default
Creating service myapp_phpserver
php[tek] 2017 169
docker-compose.yml
version: '3'
services:
phpserver:
image: php:apache
ports:
- 80:80
php[tek] 2017 170
Deploy the stack
$ docker stack deploy -c docker-compose.yml myapp
Creating network myapp_default
Creating service myapp_phpserver
php[tek] 2017 171
docker-compose.yml
version: '3'
services:
phpserver:
image: php:apache
ports:
- 80:80
php[tek] 2017 172
docker-compose.yml
version: '3'
services:
phpserver:
image: php:apache
ports:
- 80:80
php[tek] 2017 173
docker stack ps myappID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
72mud5othsjf myapp_phpserver.1 nginx:latest node2 Running Running 8 minutes ago
wsf3m32u9vcr \_ myapp_phpserver.1 php:apache manager1 Shutdown Shutdown 11 minutes ago
xf3wyh289bec myapp_phpserver.2 nginx:latest node1 Running Preparing 20 seconds ago
fehf1vdx4m0r myapp_phpserver.3 nginx:latest manager1 Running Preparing 20 seconds ago
pwnq65e6w7ew myapp_phpserver.4 nginx:latest manager1 Running Preparing 20 seconds ago
roxtanjughq8 myapp_phpserver.5 nginx:latest node2 Running Running 20 seconds ago
php[tek] 2017 174
php[tek] 2017
Thank You!
• Software Engineer for InQuest• Author of “Docker for Developers”• https://leanpub.com/dockerfordevs
• Co-Host of “Jerks Talk Games”• http://jerkstalkgames
• http://ctankersley.com• [email protected]• @dragonmantank
175