Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

Docker for Developers

90 views

Published on

Thanks to tools like Vagrant, Puppet/Chef, and Platform as a Service services like Heroku, developers are extremely used to being able to spin up a development environment that is the same every time. What if we could go a step further and make sure our development environment is not only using the same software, but 100% configured and set up like production. Docker will let us do that, and so much more.

Docker is fast becoming an important part of many developers toolkits. Not only are more developers using it day-to-day, but it is also becoming an important tool for deployments. We'll look at what Docker is, why you should consider using it, and all of the features developers can take advantage of.

Published in: Technology
  • Be the first to comment

  • Be the first to like this

Docker for Developers

  1. 1. Docker for PHP Developers Chris Tankersley @dragonmantank php[tek] 2018 1
  2. 2. php[tek] 2018 Setup! WIFI: “Sheraton Meeting”, code is `phptek2018` Example App: https://github.com/learningcontainers/dockerfordevs Lunch: Around 12:30pm Breaks: Every so often 2
  3. 3. php[tek] 2018 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.” 3 https://www.docker.com/whatisdocker/
  4. 4. php[tek] 2018
  5. 5. php[tek] 2018 What is a Container? 5
  6. 6. php[tek] 2018 Normal Bare-Metal Server 6 CPU RAM HD Network Operating System nginx PHP DB
  7. 7. php[tek] 2018 Normal Bare-Metal Server 7 CPU RAM HD Network Operating System nginx PHP DB
  8. 8. php[tek] 2018 Virtual Machines 8 CPU RAM HD Network Operating System nginx PHP DB Operating System nginx PHP DB Operating System Hypervisor
  9. 9. php[tek] 2018 Containers 9 CPU RAM HD Network Operating System nginxnginx PHP DB PHP DB
  10. 10. php[tek] 2018 Containers vs VMs
  11. 11. php[tek] 2018 Containers Are Not New • LXC (Linux Containers) • OpenVZ • Systemd-nspawn • BSD Jails • Solaris Zones • chroot 11
  12. 12. php[tek] 2018 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
  13. 13. php[tek] 2018 What is Docker? 13
  14. 14. php[tek] 2018 Docker is an Ecosystem 14 Docker Engine
  15. 15. php[tek] 2018 Docker is an Ecosystem 15 Docker ComposeDocker Machine Docker Swarm
  16. 16. php[tek] 2018 How does it work? 16 Uses a variety of existing Container technologies Server Containers Hyper-V Containers xhyve Virtualization
  17. 17. php[tek] 2018 Sorry OSX < 10.10 and Windows < 10 Users Docker Toolbox 17
  18. 18. php[tek] 2018 Let’s use Docker 18
  19. 19. php[tek] 2018 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
  20. 20. php[tek] 2018 Running a simple shell 20
  21. 21. php[tek] 2018 Running a simple shell 21
  22. 22. php[tek] 2018 Running a simple shell 22
  23. 23. php[tek] 2018 What’s Going On? 23 Ubuntu Kernel / + bin/ + etc/ + dev/ + home/ + usr/ + var/ + lib/ + … nginx bash / + bin/ + etc/ + dev/ + home/ + usr/ + var/ + lib/ + … php
  24. 24. php[tek] 2018 Running Two Webservers 24
  25. 25. php[tek] 2018 Running Two Webservers 25
  26. 26. php[tek] 2018 Running Two Webservers 26
  27. 27. php[tek] 2018 Running Two Webservers 27
  28. 28. php[tek] 2018 Running Two Webservers 28
  29. 29. php[tek] 2018 Running Two Webservers 29
  30. 30. php[tek] 2018 Running Two Webservers 30
  31. 31. php[tek] 2018 Running Two Webservers 31
  32. 32. php[tek] 2018 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
  33. 33. php[tek] 2018 Volumes 33
  34. 34. php[tek] 2018 Modifying a running container • `docker exec` can run a command inside of an existing container • Use Volumes to share data 34
  35. 35. php[tek] 2018 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
  36. 36. php[tek] 2018 Mounting from the host machine 36
  37. 37. php[tek] 2018 Mounting from the host machine 37
  38. 38. php[tek] 2018 Mounting from the host machine 38
  39. 39. php[tek] 2018 Mounting from the host machine 39
  40. 40. php[tek] 2018 Mounting from the host machine 40
  41. 41. php[tek] 2018 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
  42. 42. php[tek] 2018 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
  43. 43. php[tek] 2018 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
  44. 44. php[tek] 2018 Mounting Data Volumes 44
  45. 45. php[tek] 2018 Mounting Data Volumes 45
  46. 46. php[tek] 2018 Mounting Data Volumes 46
  47. 47. php[tek] 2018 Mounting Data Volumes 47
  48. 48. php[tek] 2018 Mounting Data Volumes 48
  49. 49. php[tek] 2018 Mounting Data Volumes 49
  50. 50. php[tek] 2018 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
  51. 51. php[tek] 2018 Networking 51
  52. 52. php[tek] 2018 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
  53. 53. php[tek] 2018 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
  54. 54. php[tek] 2018 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
  55. 55. php[tek] 2018 Create a network 55
  56. 56. php[tek] 2018 Attach to a network 56
  57. 57. php[tek] 2018 Ping the web container 57
  58. 58. php[tek] 2018 Add another web and kill web1 58
  59. 59. php[tek] 2018 BREAK TIME! WOO! 59
  60. 60. php[tek] 2018 Other Helpful Commands 60
  61. 61. php[tek] 2018 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
  62. 62. php[tek] 2018 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
  63. 63. php[tek] 2018 Containerizing An Application 63
  64. 64. php[tek] 2018 Our Goals • Not change our workflow (much) • Run PHP 7, Unit Tests, and webserver • Deploy “easily” 64
  65. 65. php[tek] 2018 Just try and run it docker run -d --name d4dapp -v C:dragoProjectsdockerfordevs-app:/var/www/ -p 8080:80 php:apache 65
  66. 66. php[tek] 2018 66
  67. 67. php[tek] 2018 Checking Logs • Containers log to stdout/stderr • Docker aggregates the logs • Can be viewed with docker logs 67
  68. 68. php[tek] 2018 Oops 68
  69. 69. php[tek] 2018 Custom Images • PHP images are pretty bare • Lots of times need to install extensions 69
  70. 70. php[tek] 2018 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
  71. 71. php[tek] 2018 docker/Dockerfile FROM php:apache RUN a2enmod rewrite 71
  72. 72. php[tek] 2018 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
  73. 73. php[tek] 2018 Build it docker build -t d4dapp docker/ 73
  74. 74. php[tek] 2018 74
  75. 75. php[tek] 2018 Use the new image docker run -d --name d4dapp -v C:dragoProjectsdockerfordevs-app:/var/www/ -p 8080:80 d4dapp 75
  76. 76. php[tek] 2018 Use the new image 76
  77. 77. php[tek] 2018 Slightly better 77
  78. 78. php[tek] 2018 Install Dependencies 78
  79. 79. php[tek] 2018 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
  80. 80. php[tek] 2018 Better! 80
  81. 81. php[tek] 2018 Look at queues! 81
  82. 82. php[tek] 2018 docker/Dockerfile FROM php:apache RUN a2enmod rewrite && docker-php-ext-install pdo_mysql 82
  83. 83. php[tek] 2018 Rebuild the image docker build -t d4dapp docker/ 83
  84. 84. php[tek] 2018 Rebuild the container $ docker rm -f d4dapp $ docker run -d --name d4dapp -v C:dragoProjectsdockerfordevs-app:/var/www/ -p 8080:80 d4dapp 84
  85. 85. php[tek] 2018 Progress! 85
  86. 86. php[tek] 2018 Docker Compose 86
  87. 87. php[tek] 2018 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
  88. 88. php[tek] 2018 Sample docker-compose.yml version: '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
  89. 89. php[tek] 2018 No longer use docker run $ docker rm –f d4dapp $ docker-compose up -d 89
  90. 90. php[tek] 2018 Now we have 2 containers 90
  91. 91. php[tek] 2018 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', ], ];
  92. 92. php[tek] 2018 Yay! 92
  93. 93. php[tek] 2018 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
  94. 94. php[tek] 2018 Set up phinx docker run --rm -v C:UsersdragoProjectsdockerfordevs-app:/app -w /app php:cli php vendor/bin/phinx init 94
  95. 95. php[tek] 2018 Run the migration docker run --rm -v C:UsersdragoProjectsdockerfordevs-app:/app -w /app --network dockerfordevsapp_default php:cli php vendor/bin/phinx migrate 95
  96. 96. php[tek] 2018 Oops 96
  97. 97. php[tek] 2018 Let’s use the existing container docker-compose run --rm -v C:UsersdragoProjectsdockerfordevs-app:/app -w /app d4dapp php vendor/bin/phinx migrate 97
  98. 98. php[tek] 2018 Good… 98
  99. 99. php[tek] 2018 It Lives! 99
  100. 100. php[tek] 2018 Unit Testing docker run --rm -v C:UsersdragoProjectsdockerfordevs-app:/app -w /app d4dapp php vendor/bin/phpunit -c . 100
  101. 101. php[tek] 2018 Running the tests
  102. 102. php[tek] 2018 Build a service service: testrunner: build: ./docker/ volumes: - ./:/app working_dir: /app command: vendor/bin/phpunit -c . 102
  103. 103. php[tek] 2018 Run the tests with the service docker-compose run --rm testrunner 103
  104. 104. php[tek] 2018 Running the tests
  105. 105. Docker Machine ZendCon, October 2016 105
  106. 106. 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
  107. 107. 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
  108. 108. Let’s make a machine! php[tek] 2017 108
  109. 109. Let’s Connect! php[tek] 2017 109
  110. 110. php[tek] 2018 BREAK TIME AGAIN! WOO! 110
  111. 111. Production Considerations 111
  112. 112. 12 Factor Applications php[tek] 2017 112
  113. 113. 1. Codebase One codebase tracked in revision control, many deploys php[tek] 2017 113
  114. 114. Repo Tips • Keep everything in your repository • Tag releases • Never move tags php[tek] 2017 114
  115. 115. 2. Dependencies Explicitly declare and isolate dependencies php[tek] 2017 115
  116. 116. Dependencies • Commit both composer.json and composer.lock files • Commit Dockerfiles to the same repo as the codebase php[tek] 2017 116
  117. 117. 3. Config Store config in the environment php[tek] 2017 117
  118. 118. 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
  119. 119. Use Environment Vars • Can specify them one-by-one – docker run ­e VAR_NAME=value • Can specify a file – docker run ­­env­file=filename • Can specify in docker-compose.yml php[tek] 2017 119
  120. 120. 4. Backing Services Treat backing services as attached resources php[tek] 2017 120
  121. 121. 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
  122. 122. 5. Build, release, run Strictly separate build and run stages php[tek] 2017 122
  123. 123. 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
  124. 124. 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
  125. 125. 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
  126. 126. 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
  127. 127. Sample usage docker build --no-cache –f docker/php/phpserver.dockerfile –t prod_php /opt/builds/20161010 php[tek] 2017 127
  128. 128. phpserver.dockerfile FROM php:fpm RUN docker-php-ext-install pdo pdo_mysql COPY ./ /var/www php[tek] 2017 128
  129. 129. 6. Processes Execute the app as one or more stateless processes php[tek] 2017 129
  130. 130. 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
  131. 131. 7. Port Binding Export services via port binding php[tek] 2017 131
  132. 132. 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
  133. 133. 8. Concurrency Scale out via the process model php[tek] 2017 133
  134. 134. How well does your app handle scaling? php[tek] 2017 134
  135. 135. 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
  136. 136. 9. Disposability Maximize robustness with fast startup and graceful shutdown php[tek] 2017 136
  137. 137. 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
  138. 138. 10. Dev/prod Parity Keep development, staging, and production as similar as possible php[tek] 2017 138
  139. 139. 11. Logs Treat logs as event streams php[tek] 2017 139
  140. 140. Logging in Docker • Various logging options built in – JSON file (default) – Fluentd – Syslog – Journald – Gelf – Splunk – Aws – Etwlogs – Gcplogs php[tek] 2017 140
  141. 141. 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
  142. 142. Setting up fluentd services:   d4dapp:     build: ./docker/d4dapp     depends_on:       ­ fluentd     volumes:       ­ ./:/var/www/     ports:       ­ 8080:80     logging:       driver: "fluentd"       options:         fluentd­address: 127.0.0.1:24224         tag: apache.access php[tek] 2017 142
  143. 143. Setting up fluentd services:   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
  144. 144. Setting up fluentd FROM fluent/fluentd RUN ["gem", "install", "fluent­plugin­elasticsearch", "­­no­rdoc", "­­no­ri", "­­version",  "1.9.2"] php[tek] 2017 144
  145. 145. Setting up fluentd [See Config File in repo] php[tek] 2017 145
  146. 146. Setting up ElasticSearch and Kibana services:   elasticsearch:     image: elasticsearch     expose:       ­ 9200     ports:       ­ 9200:9200   kibana:     image: kibana     depends_on:       ­ elasticsearch     ports:       ­ 5601:5601 php[tek] 2017 146
  147. 147. Viewing Logs php[tek] 2017 147
  148. 148. 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
  149. 149. 12. Admin Processes Run admin/management tasks as one-off processes php[tek] 2017 149
  150. 150. php[tek] 2018 BREAK TIME AGAIN! WOO! 150
  151. 151. Deployment using Docker Compose php[tek] 2017 151
  152. 152. Very Good for Small Deployments • Can be used to augment your dev environment • Works well with Docker Machine php[tek] 2017 152
  153. 153. Create a machine docker-machine create --driver digitalocean --digital-ocean-access-token [token] phpworld2017 php[tek] 2017 153
  154. 154. SunshinePHP 2017 154
  155. 155. Switch to the remote node • Run docker-machine env phpworld2017 & "C:Program FilesDockerDockerResourcesbindocker- machine.exe" env phpworld2017 | Invoke-Expression eval $(docker-machine env phpworld2017) php[tek] 2017 155
  156. 156. 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
  157. 157. 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
  158. 158. 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
  159. 159. When doing development docker-compose –f docker-compose.yml –f docker-compose.dev.yml up -d php[tek] 2017 159
  160. 160. When doing a deployment docker-compose up -d php[tek] 2017 160
  161. 161. Other Alternative – Variable Substitution • Docker Compose allows variable substitution inside the file • Wrap variables in ${} • image: ${DEPLOY_VERSION}_php php[tek] 2017 161
  162. 162. When doing a deployment DEPLOY_VERSION=20180525 docker-compose up -d php[tek] 2017 162
  163. 163. Docker Swarm php[tek] 2017 163
  164. 164. What is Swarm? • Docker-supplied clustering • Define a series of services that can be deployed php[tek] 2017 164
  165. 165. Setup php[tek] 2017 165 Manager Node 2Node 1
  166. 166. Register a node as a Manager docker swarm init ----advertise--addr 172.16.0.245 php[tek] 2017 166
  167. 167. Add nodes docker swarm join --token [token] 172.16.0.245:2377 php[tek] 2017 167
  168. 168. docker-compose.yml version: '3' services: phpserver: image: php:apache ports: - 80:80 php[tek] 2017 168
  169. 169. Deploy the stack $ docker stack deploy -c docker-compose.yml myapp Creating network myapp_default Creating service myapp_phpserver php[tek] 2017 169
  170. 170. docker-compose.yml version: '3' services: phpserver: image: php:apache ports: - 80:80 php[tek] 2017 170
  171. 171. Deploy the stack $ docker stack deploy -c docker-compose.yml myapp Creating network myapp_default Creating service myapp_phpserver php[tek] 2017 171
  172. 172. docker-compose.yml version: '3' services: phpserver: image: php:nginx ports: - 80:80 php[tek] 2017 172
  173. 173. docker-compose.yml version: '3' services: phpserver: image: php:apache ports: - 80:80 php[tek] 2017 173
  174. 174. docker stack ps myapp ID 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
  175. 175. php[tek] 2018 Thank You! • Software Engineer for InQuest • Author of “Docker for Developers” • https://leanpub.com/dockerfordevs • Co-Host of “Jerks Talk Games” • http://jerkstalkgames.com • http://ctankersley.com • chris@ctankersley.com • @dragonmantank 175

×