09/2016
Jonathan VUILLEMIN
Docker (practical basics)
Text
What is Docker ?
Wikipedia Definition
Docker is an open-source project that automates the deployment of applications inside software containers, by providing an additional layer of abstraction and automation of operating-system-level virtualization on Linux.
... nice, thanks, and ?
Linux Containers
Docker is based on LXC (Linux Containers) which allows
it to isolate containers from each other.
LXC use mainly two Linux Kernel features to acheave it :
- Namespaces (Isolation of resources)
- Cgroups (Isolation of resource usage, as CPU/RAM)
Docker World
Docker can be split in multiple different parts :
- Docker Engine
- Docker Hub
- Docker Company
How to use Docker ?
Docker can be used natively on Linux (and only Linux, boom) by the simple bash command (here, ubuntu):
$ sudo apt-get install docker-engine
Docker installation requires at least 3.13 Linux Kernel.
How to use Docker ?
Docker uses boot2docker to create a VM with a Tiny Core Linux version including Docker.
How to use Docker ?
Docker now offers Docker Toolbox which contains
Docker-machine.
It also allows to create multiple docker machines.
Container VS VM
Container VS Image
Image
An image is an inert snapshot of a container.
When runned (with a docker run command) it becomes a container.
As images can be quite heavy they are designed to be composed of layers of other images which allows to minimize an image weight, and those layers can be reused between images.
Images are stored (mainly) on Docker Hub.
Container VS Image
Image
An image is built from a Dockerfile. A file describing how the image is supposed to behave, what it extends from, ...
docker images command lists all local images :
➜ image2 git:(master) ✗ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ekkinox/image2 latest 99575a3e62ce 19 minutes ago 126.6 MB
ekkinox/image1 latest e4d90038788c 32 minutes ago 126.6 MB
doclersfbasicworkshop_nginx latest e40e5460d6cb 18 hours ago 183.2 MB
doclersfbasicworkshop_php latest 29c570fb5d03 18 hours ago 392.3 MB
tianon/true latest 2cf9735a9162 19 hours ago 125 B
nazarpc/phpmyadmin latest 5e14ef86056e 44 hours ago 433.5 MB
php 5.6-fpm c90bf43470d1 46 hours ago 362.7 MB
phpmyadmin/phpmyadmin latest de9568a72415 2 days ago 116.2 MB
mysql 5.6 72bb9d97fb75 11 days ago 328.9 MB
nginx stable 5c9792e3619e 2 weeks ago 182.8 MB
ubuntu 16.04 bd3d4369aebc 3 weeks ago 126.6 MB
ubuntu 14.04 4a725d3b3b1c 3 weeks ago 188 MB
Container VS Image
Container
Programmatically speaking, if an image is a class, then a container would be an instance of this class.
So, you can launch multiple containers for the same image (multiple instances).
docker ps command lists all running containers :
➜ image2 git:(master) ✗ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
396fa752515e ekkinox/image2 "/bin/bash" 20 minutes ago Up 20 minutes high_panini
aa60196275a3 ekkinox/image1 "/bin/bash" 29 minutes ago Up 29 minutes reverent_fermi
c7f259822acb ubuntu:16.04 "/bin/bash" 36 minutes ago Up 36 minutes awesome_elion
70ef83fa7097 ubuntu:14.04 "/bin/bash" 37 minutes ago Up 37 minutes silly_mclean
698cd8bd50fe nazarpc/phpmyadmin "/home/entrypoint.sh" 17 hours ago Up 17 hours 0.0.0.0:1234->80/tcp doclersfbasicworkshop_phpmyadmin_1
4c5dd41b5a55 doclersfbasicworkshop_nginx "nginx -g 'daemon off" 18 hours ago Up 18 hours 0.0.0.0:80->80/tcp, 443/tcp doclersfbasicworkshop_nginx_1
e58a4384d27a mysql:5.6 "docker-entrypoint.sh" 18 hours ago Up 18 hours 0.0.0.0:3306->3306/tcp doclersfbasicworkshop_db_1
faf8aba5cd3c doclersfbasicworkshop_php "php-fpm" 18 hours ago Up 18 hours 9000/tcp doclersfbasicworkshop_php_1
Build our first container
$ docker run -itd ubuntu:16.04
To create a container from the official ubuntu image :
To enter into a container with your terminal (logged as root):
$ docker exec -it CONTAINERID bash
To check your running containers and their ids :
$ docker ps
Turn our container in an image
As said before :
An image is a snapshot of a container
Let's take a snapshot of our container :
$ docker commit -m "First commit" CONTAINERID ekkinox/image1
Build a container
You can now create as many container from this image as you want :
$ docker run -dit ekkinox/image1
-d : Daemonized
-it : Allocate TTY
Image name
Dockerfile
This approach is nice but as developers
we highly prefer working in files than terminals, right ?
That's why Docker uses Dockerfiles.
Dockerfile
A Dockerfile is a translation of what the image will be :
FROM ubuntu:16.04
MAINTAINER Jonathan VUILLEMIN <ekkinox@gmail.com>
RUN mkdir -p /home/ekkinox
To build an image from this Dockerfile :
$ docker build -t ekkinox/image2 .
Container
To create a container from our new image :
$ docker run -dit ekkinox/image2
-d : Daemonized
-it : Allocate TTY
Image name
More serious things:
Nginx , Php-fpm & MySQL
Nginx
Dockerfile
FROM debian:jessie
MAINTAINER NGINX Docker Maintainers "docker-maint@nginx.com"
ENV NGINX_VERSION 1.11.4-1~jessie
RUN apt-key adv --keyserver hkp://pgp.mit.edu:80 --recv-keys 573BFD6B3D8FBC641079A6ABABF5BD827BD9BF62 \
&& echo "deb http://nginx.org/packages/mainline/debian/ jessie nginx" >> /etc/apt/sources.list \
&& apt-get update \
&& apt-get install --no-install-recommends --no-install-suggests -y \
ca-certificates \
nginx=${NGINX_VERSION} \
nginx-module-xslt \
nginx-module-geoip \
nginx-module-image-filter \
nginx-module-perl \
nginx-module-njs \
gettext-base \
&& rm -rf /var/lib/apt/lists/*
# forward request and error logs to docker log collector
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
&& ln -sf /dev/stderr /var/log/nginx/error.log
EXPOSE 80 443
CMD ["nginx", "-g", "daemon off;"]
Run a nginx container
$ docker run -dit nginx
-d : Daemonized
-it : Allocate TTY
Image name
Let's check it...
To know the IP of Docker Host :
D.M. Name
D.M. IP
Or, use
$ docker inspect CONTAINERID
Browse our container
Manage ports
To open a port on the Container :
$ docker run -dit -p 8080:80 CONTAINERID
For our nginx container, ports already exposed due to:
EXPOSE 80 443
Php-fpm
#
# NOTE: THIS DOCKERFILE IS GENERATED VIA "update.sh"
#
# PLEASE DO NOT EDIT IT DIRECTLY.
#
FROM debian:jessie
# persistent / runtime deps
ENV PHPIZE_DEPS \
autoconf \
file \
g++ \
gcc \
libc-dev \
make \
pkg-config \
re2c
RUN apt-get update && apt-get install -y \
$PHPIZE_DEPS \
ca-certificates \
curl \
libedit2 \
libsqlite3-0 \
libxml2 \
xz-utils \
--no-install-recommends && rm -r /var/lib/apt/lists/*
ENV PHP_INI_DIR /usr/local/etc/php
RUN mkdir -p $PHP_INI_DIR/conf.d
##<autogenerated>##
ENV PHP_EXTRA_CONFIGURE_ARGS --enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data
##</autogenerated>##
ENV GPG_KEYS 0BD78B5F97500D450838F95DFE857D9A90D90EC1 6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3
ENV PHP_VERSION 5.6.26
ENV PHP_FILENAME php-5.6.26.tar.xz
ENV PHP_SHA256 203a854f0f243cb2810d1c832bc871ff133eccdf1ff69d32846f93bc1bef58a8
RUN set -xe \
&& cd /usr/src \
&& curl -fSL "https://secure.php.net/get/$PHP_FILENAME/from/this/mirror" -o php.tar.xz \
&& echo "$PHP_SHA256 *php.tar.xz" | sha256sum -c - \
&& curl -fSL "https://secure.php.net/get/$PHP_FILENAME.asc/from/this/mirror" -o php.tar.xz.asc \
&& export GNUPGHOME="$(mktemp -d)" \
&& for key in $GPG_KEYS; do \
gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; \
done \
&& gpg --batch --verify php.tar.xz.asc php.tar.xz \
&& rm -r "$GNUPGHOME"
COPY docker-php-source /usr/local/bin/
RUN set -xe \
&& buildDeps=" \
$PHP_EXTRA_BUILD_DEPS \
libcurl4-openssl-dev \
libedit-dev \
libsqlite3-dev \
libssl-dev \
libxml2-dev \
" \
&& apt-get update && apt-get install -y $buildDeps --no-install-recommends && rm -rf /var/lib/apt/lists/* \
\
&& docker-php-source extract \
&& cd /usr/src/php \
&& ./configure \
--with-config-file-path="$PHP_INI_DIR" \
--with-config-file-scan-dir="$PHP_INI_DIR/conf.d" \
\
--disable-cgi \
\
# --enable-ftp is included here because ftp_ssl_connect() needs ftp to be compiled statically (see https://github.com/docker-library/php/issues/236)
--enable-ftp \
# --enable-mbstring is included here because otherwise there's no way to get pecl to use it properly (see https://github.com/docker-library/php/issues/195)
--enable-mbstring \
# --enable-mysqlnd is included here because it's harder to compile after the fact than extensions are (since it's a plugin for several extensions, not an extension in itself)
--enable-mysqlnd \
\
--with-curl \
--with-libedit \
--with-openssl \
--with-zlib \
\
$PHP_EXTRA_CONFIGURE_ARGS \
&& make -j"$(nproc)" \
&& make install \
&& { find /usr/local/bin /usr/local/sbin -type f -executable -exec strip --strip-all '{}' + || true; } \
&& make clean \
&& docker-php-source delete \
\
&& apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false $buildDeps
COPY docker-php-ext-* /usr/local/bin/
##<autogenerated>##
WORKDIR /var/www/html
RUN set -ex \
&& cd /usr/local/etc \
&& if [ -d php-fpm.d ]; then \
# for some reason, upstream's php-fpm.conf.default has "include=NONE/etc/php-fpm.d/*.conf"
sed 's!=NONE/!=!g' php-fpm.conf.default | tee php-fpm.conf > /dev/null; \
cp php-fpm.d/www.conf.default php-fpm.d/www.conf; \
else \
# PHP 5.x don't use "include=" by default, so we'll create our own simple config that mimics PHP 7+ for consistency
mkdir php-fpm.d; \
cp php-fpm.conf.default php-fpm.d/www.conf; \
{ \
echo '[global]'; \
echo 'include=etc/php-fpm.d/*.conf'; \
} | tee php-fpm.conf; \
fi \
&& { \
echo '[global]'; \
echo 'error_log = /proc/self/fd/2'; \
echo; \
echo '[www]'; \
echo '; if we send this to /proc/self/fd/1, it never appears'; \
echo 'access.log = /proc/self/fd/2'; \
echo; \
echo 'clear_env = no'; \
echo; \
echo '; Ensure worker stdout and stderr are sent to the main error log.'; \
echo 'catch_workers_output = yes'; \
} | tee php-fpm.d/docker.conf \
&& { \
echo '[global]'; \
echo 'daemonize = no'; \
echo; \
echo '[www]'; \
echo 'listen = [::]:9000'; \
} | tee php-fpm.d/zz-docker.conf
EXPOSE 9000
CMD ["php-fpm"]
##</autogenerated>##
Dockerfile
How to run PHP code ?
Run container, configured to run script.php as CMD
$ cd sandbox/script
$ docker build -t my-php-script .
$ docker run --rm --name my-running-script my-php-script
Dockerfile:
FROM php:5.6.26-fpm
COPY . /usr/src/myscript
WORKDIR /usr/src/myscript
CMD [ "php", "./script.php" ]
Code changes impacts
Now, try to change script.php behavior and re run the container... Still the same ! But why ?
As my-php-script is an inert image, a modification in my script.php files CAN'T affect this image.
As our my-running-script container is a living my-php-script,
a modification in my local files CAN'T affect this container.
A solution would be to update files directly in the container but it would only update the current container, not all containers related to my-php-script
...you already guess it is not the best solution.
Code changes impacts
A better solution ? using volumes
(The best is data volume containers, we will see that later)
First, remove the COPY directive from our Dockerfile:
FROM php:5.6.26-fpm
WORKDIR /usr/src/myscript
CMD [ "php", "./script.php" ]
And build & run the container with a volume (-v)
$ cd sandbox/script
$ docker build -t my-php-script2 .
$ docker run -v /home/nox/Dev/docker_workshop/php-fpm/script:/usr/src/myscript my-php-script2
And now we can see the changed script.php behavior !
MySQL
Dockerfile
FROM debian:jessie
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN groupadd -r mysql && useradd -r -g mysql mysql
# add gosu for easy step-down from root
ENV GOSU_VERSION 1.7
RUN set -x \
&& apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* \
&& wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" \
&& wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" \
&& export GNUPGHOME="$(mktemp -d)" \
&& gpg --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 \
&& gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu \
&& rm -r "$GNUPGHOME" /usr/local/bin/gosu.asc \
&& chmod +x /usr/local/bin/gosu \
&& gosu nobody true \
&& apt-get purge -y --auto-remove ca-certificates wget
RUN mkdir /docker-entrypoint-initdb.d
# FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
# File::Basename
# File::Copy
# Sys::Hostname
# Data::Dumper
RUN apt-get update && apt-get install -y perl pwgen --no-install-recommends && rm -rf /var/lib/apt/lists/*
# gpg: key 5072E1F5: public key "MySQL Release Engineering <mysql-build@oss.oracle.com>" imported
RUN apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys A4A9406876FCBD3C456770C88C718D3B5072E1F5
ENV MYSQL_MAJOR 5.7
ENV MYSQL_VERSION 5.7.15-1debian8
RUN echo "deb http://repo.mysql.com/apt/debian/ jessie mysql-${MYSQL_MAJOR}" > /etc/apt/sources.list.d/mysql.list
# the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn't have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql)
# also, we set debconf keys to make APT a little quieter
RUN { \
echo mysql-community-server mysql-community-server/data-dir select ''; \
echo mysql-community-server mysql-community-server/root-pass password ''; \
echo mysql-community-server mysql-community-server/re-root-pass password ''; \
echo mysql-community-server mysql-community-server/remove-test-db select false; \
} | debconf-set-selections \
&& apt-get update && apt-get install -y mysql-server="${MYSQL_VERSION}" && rm -rf /var/lib/apt/lists/* \
&& rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld \
&& chown -R mysql:mysql /var/lib/mysql /var/run/mysqld \
# ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime
&& chmod 777 /var/run/mysqld
# comment out a few problematic configuration values
# don't reverse lookup hostnames, they are usually another container
RUN sed -Ei 's/^(bind-address|log)/#&/' /etc/mysql/mysql.conf.d/mysqld.cnf \
&& echo 'skip-host-cache\nskip-name-resolve' | awk '{ print } $1 == "[mysqld]" && c == 0 { c = 1; system("cat") }' /etc/mysql/mysql.conf.d/mysqld.cnf > /tmp/mysqld.cnf \
&& mv /tmp/mysqld.cnf /etc/mysql/mysql.conf.d/mysqld.cnf
VOLUME /var/lib/mysql
COPY docker-entrypoint.sh /usr/local/bin/
RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 3306
CMD ["mysqld"]
Pull it !
Let's use the official mysql repository
$ docker pull mysql
MySQL Container
To run a Container with MySQL :
$ docker run \
--name mysql \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=ekkinox \
-d \
mysql
$ docker exec -it CONTAINERID bash
root@0b1425f8cf45:/# mysql -u root -proot
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.7.15 MySQL Community Server (GPL)
Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| ekkinox |
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
PHP linked to MySQL?
Build and run an php-fpm container, named mysqlphp, with Dockerfile:
FROM php:5.6.26-fpm
RUN apt-get update && apt-get install -y \
libfreetype6-dev \
libmcrypt-dev \
libxml2-dev \
curl \
zlib1g-dev \
libncurses5-dev \
libcurl4-openssl-dev \
&& docker-php-ext-install -j$(nproc) mcrypt pdo_mysql mbstring
COPY . /usr/src/myscript
WORKDIR /usr/src/myscript
CMD [ "php", "./connect.php" ]
We extend here php_fpm image to install some needed PHP extensions.
$ cd sandbox/mysql
$ docker build -t mysqlphp .
PHP linked to MySQL?
If we run:
But if we link (--link) to mysql container:
$ docker run mysqlphp
Warning: PDO::__construct(): php_network_getaddresses: getaddrinfo failed: Name or service not known in /usr/src/myscript/connect.php on line 5
Erreur !: SQLSTATE[HY000] [2002] php_network_getaddresses: getaddrinfo failed: Name or service not known<br/>%
$ docker run --link mysql:mysql mysqlphp
OK, connected !
Let's write a connect.php script:
<?php
try {
$dbh = new PDO('mysql:host=mysql;dbname=ekkinox', 'root', 'root');
echo 'OK, connected !';
} catch (PDOException $e) {
echo "Erreur !: " . $e->getMessage() . "<br/>";
die();
}
PHP linked to Nginx?
Run an php-fpm container, named php:
$ docker run --name php -p 9000:9000 -d php:5.6.26-fpm
Then run a nginx container, linked to php (using --link)
$ docker run -it --link php:php nginx /bin/bash
Once inside nginx container, check php-fpm ENV vars:
root@0e16019721b6:/# env | grep PHP
PHP_ENV_PHP_EXTRA_CONFIGURE_ARGS=--enable-fpm --with-fpm-user=www-data --with-fpm-group=www-data
PHP_ENV_PHP_VERSION=5.6.26
PHP_ENV_GPG_KEYS=0BD78B5F97500D450838F95DFE857D9A90D90EC1 6E4F6AB321FDC07F2C332E3AC2BF0BC433CFC8B3
PHP_PORT=tcp://172.17.0.6:9000
PHP_ENV_PHP_SHA256=203a854f0f243cb2810d1c832bc871ff133eccdf1ff69d32846f93bc1bef58a8
PHP_PORT_9000_TCP_PROTO=tcp
PHP_ENV_PHP_FILENAME=php-5.6.26.tar.xz
PHP_ENV_PHPIZE_DEPS=autoconf file g++ gcc libc-dev make pkg-config re2c
PHP_PORT_9000_TCP_PORT=9000
PHP_ENV_PHP_INI_DIR=/usr/local/etc/php
PHP_PORT_9000_TCP=tcp://172.17.0.6:9000
PHP_NAME=/modest_elion/php
PHP_PORT_9000_TCP_ADDR=172.17.0.6
Docker Hub
Docker Hub contains a lot of images for various purposes.
Docker Hub provides a free storage facility for your public images and a paying storage facility for your private images (GitHub style).
Push on Docker Hub
$ docker push ekkinox/mydockerizedproject
Pull from Docker Hub
$ docker pull ekkinox/mydockerizedproject
Automated Builds
Docker Hub allows you to link a GitHub repository to a Docker Hub repository.
Your GitHub repository should contain a Dockerfile on the root directory.
Each time you push on GitHub, Docker Hub (through webhooks) will pull your repository and build an image into your Docker Hub repository.
Orchestration
So, running all containers by hand can
be really messy and complicated... saw it.
"Damned, i'll never use this Docker stuff..."
Orchestration
For the moment our simple application requires us to do those kind of commands :
$ docker run \
--name mysql \
-e MYSQL_ROOT_PASSWORD=root \
-e MYSQL_DATABASE=ekkinox \
-d \
mysql
$ docker run \
-v /home/nox/Dev/docker_workshop/php-fpm/script:/usr/src/myscript \
my-php-script2
$ ... and more and more pain 0_x !
(and we did not even seen it running on nginx yet, right ?)
Orchestration
Solutions ?
- Put those commands into a README ?
- Put those commands into a bash script ?
No. Bad idea.
The solution is Docker compose
Orchestration
Docker compose works by putting a single yaml file in your project.
Let's build our project step by step ...
... yes we can.
Orchestration
First, we need nginx:
services:
nginx:
build: ./nginx
ports:
- "80:80"
volumes:
- ./logs/nginx/:/var/log/nginx
check with docker ps
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
01c2a83efc66 application_nginx "nginx -g 'daemon off" 44 seconds ago Up 43 seconds 0.0.0.0:80->80/tcp, 443/tcp application_nginx_1
run docker compose up -d
$ docker-compose up -d
Creating network "application_default" with the default driver
Creating application_nginx_1
Orchestration
Then, add some code to nginx using volumes
services:
nginx:
build: ./nginx
ports:
- "80:80"
volumes:
- ./logs/nginx/:/var/log/nginx
- ./src/:/var/www/application
rebuild and restart (only build needed, but shows all commands)
$ docker-compose down
$ docker-compose build
$ docker-compose up -d
Orchestration
Then, we need php-fpm
services:
php:
build: ./php-fpm
rebuild and restart
$ docker-compose down
$ docker-compose build
$ docker-compose up -d
check with docker ps
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
56f6a05b08c9 application_nginx "nginx -g 'daemon off" 4 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, 443/tcp application_nginx_1
dab7a7298c36 application_php "php-fpm" 4 seconds ago Up 2 seconds 9000/tcp application_php_1
Orchestration
Test it : http://192.168.99.100/phpinfo.php
FIle not found !
normal, php-fpm does not know where to find php script:
$ docker-compose down
$ docker-compose build
$ docker-compose up -d
rebuild and restart:
php:
build: ./php-fpm
volumes:
- ./src/:/var/www/application
Now, http://192.168.99.100/phpinfo.php => OK !
Orchestration
Then, we need a mysql :
$ docker-compose up -d
and restart (no build needed here):
mysql:
image: mysql:5.6
expose:
- 3306
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=ekkinox
Now, http://192.168.99.100/index.php=> OK, connected !
Orchestration
As we are lazy, could be nice to have a PhpMyAdmin, right ?
$ docker-compose up -d
and restart (no build needed here):
phpmyadmin:
image: nazarpc/phpmyadmin
ports:
- "1234:80"
links:
- mysql:mysql
check with docker ps
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1b6487cedee9 nazarpc/phpmyadmin "/home/entrypoint.sh" 43 seconds ago Up 42 seconds 0.0.0.0:1234->80/tcp application_phpmyadmin_1
b3a4ea177aed mysql:5.6 "docker-entrypoint.sh" 44 seconds ago Up 43 seconds 0.0.0.0:3306->3306/tcp application_mysql_1
972ea0cf9df9 application_php "php-fpm" 45 seconds ago Up 43 seconds 9000/tcp application_php_1
783be0ad9874 application_nginx "nginx -g 'daemon off" 45 seconds ago Up 44 seconds 0.0.0.0:80->80/tcp, 443/tcp application_nginx_1
Orchestration
Keeping mysql data could be nice, even if containers are killed.
Data volumes to the rescue:
and restart (no build needed here):
mysql:
image: mysql:5.6
expose:
- 3306
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=ekkinox
volumes_from:
- mysql_data
mysql_data:
image: tianon/true
volumes:
- ./mysql/data:/var/lib/mysql
rebuild and restart
Now, http://192.168.99.100/users.php=> OK, persistent !
Orchestration
So, in short (more easy than docker commands, right ?) :
version: '2'
services:
nginx:
build: ./nginx
ports:
- "80:80"
volumes:
- ./logs/nginx/:/var/log/nginx
- ./src/:/var/www/application
php:
build: ./php-fpm
volumes:
- ./src/:/var/www/application
phpmyadmin:
image: nazarpc/phpmyadmin
ports:
- "1234:80"
links:
- mysql:mysql
mysql:
image: mysql:5.6
expose:
- 3306
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=root
- MYSQL_DATABASE=ekkinox
volumes_from:
- mysql_data
mysql_data:
image: tianon/true
volumes:
- ./mysql/data:/var/lib/mysql
Orchestration
Some docker useful commands:
# Stops all containers
$ docker stop $(docker ps -a -q)
# Delete all containers
$ docker rm $(docker ps -a -q)
# Delete all images
$ docker rmi $(docker images -q)
Orchestration
Some docker-compose useful commands:
$ docker-compose up -d
$ docker-compose down
$ docker-compose build
$ docker-compose logs -f
$ docker-compose restart
Scalability
Docker compose allows you to multiply a container by using the scale command :
$ docker-compose scale nginx=5
To allow links to properly function you have to stop and remove your nginx container and relaunch it :
$ docker-compose stop nginx
$ docker-compose rm nginx
$ docker-compose run -d nginx
Thank you ...
and use docker !
...questions ? no ? cool.
About Docker
By Michael PAMBO OGNANA
About Docker
Docker basics
- 627