On Github socketwench / rideTheWhale
socketwench.github.io/rideTheWhale
No Sandboxing.
...stays on your system forever
Files, configuration, old binaries
Requires discipline and time to find, delete
Bash aliases, symlinks, multiple network ports
Works around assumed OS best practices
NOM NOM NOM Resources
And you'll probably need more than one
UnionFS only uses the space needed
Even across containers
"Build tool? You mean this Word doc?"
Because humans are fallible
Because it was built by hand
Eats productivity, harder to on-ramp, creates weird bugs
Puppet, Chef, Ansible are powerful
They also have a steeper learning curve
Consistent dev environments each time
No need to install anything else
Enterprise ready tech
Maintained by Red Hat, Google, IBM and others
Docker is free and open source!
Easiest way to install on Mac and Windows
docker.com/products/docker-toolbox
Includes Virtualbox
Provides a Docker Host on a VM
Replaces boot2docker
Docker's native environment
No need for a VM
Use your distro's package manager
Starts default docker machine
Sets $DOCKER_HOST environment variable
In ~/.bashrc
docker-machine start default eval $(docker-machine env default)
May slow down terminal startup
You rarely build a container from scratch
Online registry of pre-made containers
Vetted and regularly updated
MySQL, PHP, Apache, many Linux Distros
Good for demos...but limited for development
Where image_name is the name on Docker Hub
$ docker pull debian
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS $
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS $
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS $
Not exactly true, but close
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS 0c6142a4488a debian "/bin/bash" 8 seconds ago Exited
The starting container
Who maintains this file
Other commands & config
What to run when ready
Basis of Docker's build system
<your_project_root> └── Dockerfile
Always create a project directory!
FROM debian:wheezy MAINTAINER your_email@example.com
FROM debian:wheezy MAINTAINER your_email@example.com
All containers are build on top of another container
Parent of all Docker containers
Just an empty *.tar.gz file
Version is optional, defaults to "latest"
docker build /path/to/Dockerfile
$ docker build . Sending build context to Docker daemon 2.048 kB Step 1 : FROM debian:wheezy ---> 4c82789231a5 Step 2 : MAINTAINER your_email@example.com ---> Running in 908f461e93e4 ---> c9c74cdf1e1d Removing intermediate container 908f461e93e4 Successfully built c9c74cdf1e1d $
It's one big blob of stuff
They have layers!
Each line in the Dockerfile is like a commit
$ docker build . Sending build context to Docker daemon 2.048 kB Step 1 : FROM debian:wheezy ---> 4c82789231a5 Step 2 : MAINTAINER your_email@example.com ---> Running in 908f461e93e4 ---> c9c74cdf1e1d Removing intermediate container 908f461e93e4 Successfully built c9c74cdf1e1d $
$ docker history c9c74cdf1e1d IMAGE CREATED CREATED BY SIZE COMMENT c9c74cdf1e1d 42 hours ago /bin/sh -c #(nop) MAINTAINER your_email@examp 0 B 4c82789231a5 10 days ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0 B <missing> 10 days ago /bin/sh -c #(nop) ADD file:add5fc8cb18678647f 84.93 MB
(You'll almost never need this.)
Running an image creates a new container!
Exists as long as container exists
Must be commited to an image
$ docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE 64b0d7e8eef9 1 minutes ago 85.02 MB debian wheezy 60c52dbe9d91 4 weeks ago 85.02 MB debian latest 9a61b6b1315e 4 weeks ago 125.2 MB
We didn't need it any longer
So we threw them away
It's just an image
Usually whatever image you start with
$ docker run -i -t c9c /bin/bash root@71724ddf264b:/# cat /etc/issue Debian GNU/Linux 7 \n \l
It lets the container decide!
Debian and Ubuntu use apt-get
Cent OS uses yum
Debian and Ubuntu use apt-get
Cent OS uses yum
Debian and Ubuntu use apt-get
Cent OS uses yum
Runs the specified command in the container
FROM debian:wheezy MAINTAINER your_email@example.com RUN apt-get update RUN apt-get install -y apache2
Just use docker build!
$ docker build . Sending build context to Docker daemon 2.048 kB Sending build context to Docker daemon Step 0 : FROM debian:wheezy ---> 60c52dbe9d91 Step 1 : MAINTAINER your_email@example.com ---> Using cache ---> 64b0d7e8eef9 Step 2 : RUN apt-get update ---> Running in 8652b461d629 Get:1 http://security.debian.org wheezy/updates Release.gpg [1554 B] ... Fetched 8438 kB in 7s (1094 kB/s) Reading package lists... ---> eefa2fcb15e7 Removing intermediate container 8652b461d629 Step 3 : RUN apt-get install -yq apache2 ---> Running in ef474ef3a976 Reading package lists... Building dependency tree... Reading state information... … Setting up libswitch-perl (2.16-2) ... ---> aa084388ac30 Removing intermediate container ef474ef3a976 Successfully built aa084388ac30(scroll down for more)
$docker images REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE aa084388ac30 2 minutes ago 145 MB debian wheezy 60c52dbe9d91 4 weeks ago 85.02 MB debian latest 9a61b6b1315e 4 weeks ago 125.2 MB
Software can require input on installation
Will cause docker build to hang or fail
"headless", "scripted", or "unattended installation"
-yq switch
"Yes to all questions, use Quiet installation."
apachectl command
apachectl command
$ docker run -i -t aa0 apachectl start apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.7 for ServerName $
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS 9d0eab0934fe aa0 "apachectl start" 2 minutes ago Exited (0) 2 minutes ago(Scroll right.)
apachectl started apache as a background process
Then returned 0
A container runs as long as it's process does
Apache switch, not Docker
'd' for 'daemon'
$ docker run -d aa0 apachectl -D FOREGROUND 86414f5548dcecb83d80dec4ec9351a7697b23d11664738f8668167a127ec70e
In a new terminal session:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS 86414f5548dc aa0 "apachectl -D FOREGR 36 seconds ago Up 34 seconds(Scroll right.)
$ docker kill 864 864 $
CMD [“apachectl”, “-D”, “FOREGROUND”]
Actual executable run in container
docker run command passed as a parameter
May be overridden by your base image!
CMD [“-D”, “FOREGROUND”] ENTRYPOINT [“apachectl”]
Use CMD to pass parameters
The ENTRYPOINT can be any command, even a script!
Avoid too much automation in your containers
FROM debian:latest MAINTAINER your_email@example.com RUN apt-get update RUN apt-get install -yq apache2 CMD ["-D", "FOREGROUND"] ENTRYPOINT ["apachectl"]
$ docker build . Sending build context to Docker daemon 2.048 kB Sending build context to Docker daemon Step 0 : FROM debian:latest ---> 60c52dbe9d91 Step 1 : MAINTAINER your_email@example.com ---> Using cache ---> 64b0d7e8eef9 Step 2 : RUN apt-get update ---> Using cache ---> eefa2fcb15e7 Step 3 : RUN apt-get install -y apache2 ---> Using cache ---> aa084388ac30 Step 4 : CMD -D FOREGROUND ---> Running in 32b9f66cf1e3 ---> 239ae06b7d68 Removing intermediate container 32b9f66cf1e3 Step 5 : ENTRYPOINT apachectl ---> Running in 6ac785739695 ---> 72b3cac68438 Removing intermediate container 6ac785739695 Successfully built 72b3cac68438(Scroll down for more.)
$ docker run -d 72b 988bf0c8cdfdf88c42e3673a65597f78693c07b14070cd535962b13b36884560 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS 988bf0c8cdfd 72b "apachectl -D FOREGR 4 seconds ago Up 3 seconds
Typically the third-to-last line in your Dockerfile
$ docker-machine ip 192.168.59.103
192.168.59.103 docker.dev
Machine IP may change on restart!
Contains must be run with a port mapping!
x is the port on your machine
y is the port in the container
$ docker run -d -p 80:80 802 2f4126401306277841aa173794e17703caaa38c8a30709747e4bd0577ba3a44d
Lets you build multiple containers at once
Included out-of-the-box, replaces Docker Fig
Descriptive, rather than instructive
Indentation is significant!
Section headers end in a full colon (:)
List items start with a hyphen (-)
-d for daemon
$ cd /your/project/directory $ docker-compose up -d Creating dockerthingy_web_1 $ docker ps CONTAINER ID COMMAND STATUS NAMES 245fbb0bf255 "apachectl -D FOREGR Up 18 secs dockerthingy_web_1
$ cd /your/project/directory $ docker-compose up -d Creating dockerthingy_web_1 $ docker ps CONTAINER ID COMMAND STATUS NAMES 245fbb0bf255 "apachectl -D FOREGR Up 18 secs dockerthingy_web_1
/home/tess/dockerthingy ├── docker-compose.yml └── Dockerfile
$ docker-compose ps Name Command State Ports ----------------------------------------------------------------------- dockerthingy_web_1 apachectl -D FOREGROUND Up 80/tcp, 9000/tcp
version: '2' services: web: build: . ports: - “80:80”
Compose always overrides Dockerfiles
Use it instead of build
<your_project_dir> ├── .docker │ ├── db │ └── web │ └── Dockerfile ├── docker-compose.yml └── docroot └── index.html
Just one possibility, do what works for you
version: '2' services: web: build: .docker/web ports: - "80:80" db: image: mysql ports: - "3306:3306"
$ docker-compose kill $ docker-compose rm
Acts only on containers in docker-compose.yml.
Directories and wildcards accepted
FROM debian:latest MAINTAINER your_email@example.com RUN apt-get update RUN apt-get install -yq apache2 COPY docroot/index.html /var/www/html CMD ["-D", "FOREGROUND"] ENTRYPOINT ["apachectl"]
$ docker-compose up -d $ curl docker.dev <html> <body> <h1>Behold, my amazing page!</h1> <p>Okay, yeah, it sucks. Sorry.</p> </body> </html>
Mounts one or more directories into a container
- local/file/path:/path/on/containerversion: '2' services: web: build: .docker/web ports: - "80:80" volumes: - ./docroot:/var/www/html db: image: mysql ports: - "3306:3306"
Bake it into the container
Mount config files via volumes
Set environment variables
environment section
- ENV_VAR_NAME=VALUEversion: '2' services: web: build: .docker/web ports: - "80:80" volumes: - ./docroot:/var/www/html db: image: mysql ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=drupal8 - MYSQL_USER=drupal - MYSQL_PASSWORD=thisisawesome(Scroll down.)
Download, extract to docroot/
Create files directory and settings.php as normal
There's no PHP on our web container!
We could update it, but it'd be more to maintain.
There's no PHP on our web container!
We could update it, but it'd be more to maintain.
FROM php:apache MAINTAINER your_email@example.com RUN apt-get update && apt-get install -y \ libfreetype6-dev \ libjpeg62-turbo-dev \ libmcrypt-dev \ libpng12-dev \ libicu-dev RUN docker-php-ext-install gd json intl pdo pdo_mysql mbstring opcache
You may need to docker-compose rm
Network connections created on build
Always be willing to jump containers
Different versions & configuration of PHP
Drush versions may be significant
volumes_from mounts all volumes from another container
Volumes not unmounted from other containers
services: web: build: .docker/web ports: - "80:80" volumes: - ./docroot:/var/www/html db: image: mysql ports: - "3306:3306" environment: - MYSQL_ROOT_PASSWORD=root - MYSQL_DATABASE=drupal8 - MYSQL_USER=drupal - MYSQL_PASSWORD=thisisawesome drush: image: drush/drush volumes_from: - web(Scroll down.)
Beware! Creates a (tiny) new container each time
$ docker-compose run drush --root=/var/www/html --uri=http://web/ status Drupal version : 8.1.3 Site URI : http://web/ Database driver : mysql Database hostname : db Database port : 3306 Database username : drupal Database name : drupal8 Drupal bootstrap : Successful PHP OS : Linux Install profile : standard Drupal root : /var/www/html Drupal Settings File : sites/default/settings.php Site path : sites/default File directory path : sites/default/files Temporary file directory path : /tmp
Persistent CLI container with multiple tools
Helper scripts to make things easy
Docker from Scratch, Part 6 on deninet.comMulti-project Drupal site development
github.com/blinkreaction/drudeRequires a system-wide one time setup
Includes the Drude Shell Helper (dsh)
Mac and Windows performance enhancements
Multiple simultaneous sites
Documentation
Drop in D8 module development
github.com/socketwench/dropwhaleSelf-contained in a .docker/ directory
Installs Drupal 8 dev, Drush, Console, XDebug
Lightweight containers, simple Dockerfiles
Helper scripts named for verbs (start, build, drush)
Build your own!
socketwench.github.io/rideTheWhale