Stefano Morandi | Cristian Pavan
2019-10-26
PNLUG, Linuxday 2019
I’m Stefano and I’m DevOps @uomorando.
I’m Cristian and I’m Developer @tux_eithel.
We work at AKQA.
And we ❤️ GNU/Linux!
most common, but not the only one
The Open Container Initiative is a lightweight, open governance structure for the express purpose of creating open industry standards around container formats and runtime.
isolate process
manage resource
DEV environment, not production
An image is a read-only template with instructions for creating a Docker container. Often, an image is based on another image, with some additional customization.
A container is a runnable instance of an image.
A Docker registry stores Docker images.
docker hub
gitlab
from docker.com
https://docs.docker.com/install/linux/docker-ce/ubuntu/
sudo apt-get remove docker docker-engine docker.io \ containerd runc sudo apt-get update sudo apt-get install \ apt-transport-https \ ca-certificates \ curl \ gnupg-agent \ software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - echo "deb [arch=amd64] https://download.docker.com/linux/ubuntu \ $(lsb_release -cs) \ stable" > /etc/apt/sources.list.d/docker.list sudo apt-get update sudo apt-get install docker-ce docker-ce-cli containerd.io sudo usermod -aG docker <username>
from docker.com
https://hub.docker.com/editions/community/docker-ce-desktop-mac
via brew
brew cask install docker
from https://docs.docker.com/compose/install/
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
docker run hello-world
Hello from Docker! This message shows that your installation appears to be working correctly. ...
docker pull busybox
Using default tag: latest latest: Pulling from library/busybox 7c9d20b9b6cd: Pulling fs layer 7c9d20b9b6cd: Download complete 7c9d20b9b6cd: Pull complete Digest: sha256:fe301db49df08c384001ed752dff6d52b4305a73a7f608f21528048e8a08b51e Status: Downloaded newer image for busybox:latest
docker pull busybox
Using default tag: latest latest: Pulling from library/busybox Digest: sha256:fe301db49df08c384001ed752dff6d52b4305a73a7f608f21528048e8a08b51e Status: Image is up to date for busybox:latest
no download
docker run busybox echo "ciao, mondo!"
ciao, mondo!
docker info | grep Version
Server Version: 19.03.3 Kernel Version: 4.15.0-65-generic
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE morandz/emacs-reveal latest 6e4b5827afc5 46 hours ago 759MB busybox latest 19485c79a9bb 2 weeks ago 1.22MB registry.gitlab.com/oer/docker/emacs-reveal 3.3 26559340ea1a 4 months ago 759MB
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 830947d3c078 busybox "echo 'ciao, mondo!'" 3 minutes ago Exited (0) 3 minutes ago jovial_mirzakhani
docker container rm jovial_mirzakhani
jovial_mirzakhani
docker run --rm busybox echo "ciao, mondo!"
ciao, mondo!
docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
setup docker webserver for a static website
https://hub.docker.com/_/httpd
Official Images => DOCKER Official
docker pull httpd:2.4
2.4: Pulling from library/httpd b8f262c62ec6: Pulling fs layer ... 60812fa1ab4c: Pull complete Digest: sha256:39d7d9a3ab93c0ad68ee7ea237722ed1b0016ff6974d80581022a53ec1e58797 Status: Downloaded newer image for httpd:2.4
docker run --rm httpd:2.4
curl -I http://127.0.0.1
curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused
docker network ls
NETWORK ID NAME DRIVER SCOPE 5f90a017d066 bridge bridge local 146c0e76bc9a host host local 1acf502fece9 none null local
docker run --rm -p80:80 httpd:2.4
curl -I http://127.0.0.1
HTTP/1.1 200 OK Date: Thu, 19 Sep 2019 14:58:09 GMT Server: Apache/2.4.41 (Unix) Last-Modified: Mon, 11 Jun 2007 18:53:14 GMT ETag: "2d-432a5e4a73a80" Accept-Ranges: bytes Content-Length: 45 Content-Type: text/html
publish local files
we need to know where the documentroot is
RTFM! :-D
https://hub.docker.com/_/httpd
/usr/local/apache2/htdocs/
mkdir -p docker-101/htdocs cd docker-101 echo "Hello, World!" > htdocs/index.html ls -l htdocs/
total 8 -rw-r--r-- 1 stefano.morandi wheel 14 Sep 19 17:21 index.html
docker run --rm -p80:80 -v `pwd`/htdocs:/usr/local/apache2/htdocs httpd:2.4
curl http://localhost
Hello, World!
docker run -d --rm -p80:80 -v `pwd`/htdocs:/usr/local/apache2/htdocs httpd:2.4
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 2692286141e0 httpd:2.4 "httpd-foreground" About a minute ago Up About a minute 0.0.0.0:80->80/tcp practical_pascal
docker container stop practical_pascal
practical_pascal
docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
docker run -d --rm -p80:80 -v `pwd`/htdocs:/usr/local/apache2/htdocs httpd:2.4
docker container ls -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4e8c60f15f8c httpd:2.4 "httpd-foreground" 59 seconds ago Up 57 seconds 0.0.0.0:80->80/tcp suspicious_banach
docker logs -f suspicious_banach
publish docker image with all html code
FROM: httpd:2.4 COPY ./htdocs/ /usr/local/apache2/htdocs/
docker build -t pnlug/apache:2.4 . -f Dockerfile
Sending build context to Docker daemon 10.24kB Step 1/2 : FROM httpd:2.4 ---> 66a97eeec7b8 Step 2/2 : COPY ./htdocs/ /usr/local/apache2/htdocs/ ---> 9c7d1671e6b9 Successfully built 9c7d1671e6b9 Successfully tagged pnlug/apache:2.4
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE pnlug/apache 2.4 9c7d1671e6b9 13 seconds ago 154MB morandz/emacs-reveal latest 5f712f35769b 2 minutes ago 1.03GB httpd 2.4 66a97eeec7b8 3 days ago 154MB registry.gitlab.com/oer/docker/emacs-reveal 5.9.0 4dd7a8c319b3 5 days ago 1.03GB
docker run -d --rm -p80:80 pnlug/apache:2.4
2fa1a7bc7c64e75296b426029ba262154bde65c55541c6e5debf138cf1a28aea
curl http://localhost
ciao
webserver with node
https://hub.docker.com/_/node/
docker pull node:10-alpine
10-alpine: Pulling from library/node e7c96db7181b: Pulling fs layer 50958466d97a: Pulling fs layer ... 56174ae7ed1d: Pull complete 284842a36c0d: Pull complete Digest: sha256:77c898d0da5e7bfb6e05c9a64de136ba4e03889a72f3c298e95df822a38f450d Status: Downloaded newer image for node:10-alpine
const http = require('http'); const hostname = '0.0.0.0'; const port = 3000; const server = http.createServer((req, res) => { res.statusCode = 200; res.setHeader('Content-Type', 'text/plain'); res.end('Hello World\n'); }); server.listen(port, hostname, () => { console.log(`Server running at http://${hostname}:${port}/`); });
docker run --rm -d -p 3000:3000 -v `pwd`:/app -w /app node:10-alpine hello.js
curl http://127.0.0.1:3000 Hello World
CMD instruction allows you to set a default command, which will be executed only when you run container without specifying a command.
ENTRYPOINT command and parameters are not ignored when Docker container runs with command line parameters.
FROM alpine:3.9 CMD ["/bin/echo", "Hello, Linuxday"]
docker build -t pnlug/cmd-ent -f Dockerfile-cmd .
Sending build context to Docker daemon 10.75kB Step 1/2 : FROM alpine:3.9 ---> 055936d39205 Step 2/2 : CMD ["echo", "Hello, Linuxday"] ---> Running in 230fc0ce264f Removing intermediate container 230fc0ce264f ---> 5086350c1695 Successfully built 5086350c1695 Successfully tagged pnlug/cmd-ent:latest
docker run --rm pnlug/cmd-ent
Hello, Linuxday
docker run --rm pnlug/cmd-ent echo "Ciao Mondo"
Ciao Mondo
FROM alpine:3.9 ENTRYPOINT ["echo", "Hello World!"]
docker build -t pnlug/cmd-ent -f Dockerfile-cmd .
Sending build context to Docker daemon 10.75kB Step 1/2 : FROM alpine:3.9 ---> 055936d39205 Step 2/2 : ENTRYPOINT ["/bin/echo", "Hello World!"] ---> Running in 151e663170bb Removing intermediate container 151e663170bb ---> b189906342d6 Successfully built b189906342d6 Successfully tagged pnlug/cmd-ent:latest
docker run --rm pnlug/cmd-ent
Hello World!
docker run --rm pnlug/cmd-ent echo "Ciao Mondo"
Hello World! echo Ciao Mondo
FROM alpine:3.9 ENTRYPOINT ["echo", "Hello"] CMD ["Linuxday"]
docker build -t pnlug/cmd-ent -f Dockerfile-cmd .
Sending build context to Docker daemon 10.75kB Step 1/3 : FROM alpine:3.9 ---> 055936d39205 Step 2/3 : ENTRYPOINT ["echo", "Hello"] ---> Running in 833e2c1a0dc9 Removing intermediate container 833e2c1a0dc9 ---> 4b1114d48437 Step 3/3 : CMD ["Linuxday"] ---> Running in c38f57bb098a Removing intermediate container c38f57bb098a ---> 1901b09dfad4 Successfully built 1901b09dfad4 Successfully tagged pnlug/cmd-ent:latest
docker run --rm pnlug/cmd-ent
Hello Linuxday
docker run --rm pnlug/cmd-ent "Mondo"
Hello Mondo
node:10-alpine dockerfile
ENTRYPOINT ["docker-entrypoint.sh"] CMD [ "node" ]
docker run --rm -p 3000:3000 -v `pwd`:/app -w /app node:10-alpine --version
v10.16.3
docker run --rm -p 3000:3000 -v `pwd`:/app -w /app node:10-alpine npm --version
6.9.0
SHELL:=/bin/bash LOCAL_DIR=$(shell pwd) IMAGE_NODE=node:10-alpine pull-image: @docker pull ${IMAGE_NODE} run: @docker run --rm -d -p 3000:3000 -v ${LOCAL_DIR}:/app -w /app ${IMAGE_NODE} node hello.js
in your .bashrc / .zshrc
node10(){ docker run --rm -p 3000:3000 -v `pwd`:/app -w /app node:10-alpine $@ }
Build a website with nodejs (version 12)
setup minimal a php page with mysql interaction
docker pull php:7.2-apache docker pull mariadb:10.1
7.2-apache: Pulling from library/php b8f262c62ec6: Already exists a98660e7def6: Pulling fs layer ... 638370de0271: Pull complete Digest: sha256:24299b59ee1f0bf81ed09fb295d206da52d2587ff8fd99945c4d798970b87e93 Status: Downloaded newer image for php:7.2-apache 10.1: Pulling from library/mariadb 5667fdb72017: Pulling fs layer d83811f270d5: Pulling fs layer ... 3f8dcde4fb2b: Pull complete 336764d78786: Pull complete 8d4d93194de3: Pull complete Digest: sha256:82889ab2b6a04d253a0c2285a39ae14afbf4f031b09e00250830c6f72e542d59 Status: Downloaded newer image for mariadb:10.1
MySQL needs some variables:
MYSQL_ROOT_PASSWORD MYSQL_DATABASE MYSQL_USER MYSQL_PASSWORD
Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. While bind mounts are dependent on the directory structure of the host machine, volumes are completely managed by Docker
docker volume create mysql-test
export MYSQL_ROOT_PASSWORD=passwd export MYSQL_DATABASE=db docker run --name db --rm -d -v mysql-test:/var/lib/mysql \ -eMYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD \ -eMYSQL_DATABASE=$MYSQL_DATABASE mariadb:10.1
cba671f87cb880d0c3181021693c3d8e926d30f039cf146c97064c4a0685f35b
docker run --name apache --rm -d -p80:80 -v `pwd`/htdocs:/var/www/html/ --link db php:7.2-apache
f2fb78a71c17abc2a5647b8e08951af9899f08f8b36ef73f22d29901015eabf3
docker exec -it apache /bin/bash
apt update && apt install iputils-ping
ping -c1 db
exit
// htdocs/index.php <?php $dbhost = "db"; $dbuser = "root"; $dbpass = "password"; $dbname = "test"; try { $conn = new PDO("mysql:host=$dbhost;dbname=$dbname", $dbuser, $dbpass); // set the PDO error mode to exception $conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); echo "Connected successfully"; } catch(PDOException $e) { echo "Connection failed: " . $e->getMessage(); } ?>
curl http://localhost/index.php Connection failed: could not find driver
Dockerfile-php
FROM php:7.2-apache RUN apt-get update RUN docker-php-ext-install -j "$(nproc)" \ pdo pdo_mysql
docker stop apache
docker build . -f Dockerfile-php -t pnlug/php:7.2-apache
Sending build context to Docker daemon 119.8MB Step 1/3 : FROM php:7.2-apache ---> 2aefc00193b5 Step 2/3 : RUN apt-get update ---> Running in b8507ac92ded Get:1 http://security-cdn.debian.org/debian-security buster/updates InRelease [39.1 kB] ... Step 3/3 : RUN docker-php-ext-install -j "$(nproc)" pdo pdo_mysql ---> Running in ae875eb770cd Configuring for: PHP Api Version: 20170718 ...
docker run --name apache --rm -d -p80:80 -v `pwd`/htdocs:/var/www/html/ --link db pnlug/php:7.2-apache
90c9694a039ee7ec7e3f2e60143a907a3a8108501d74b587847a23db0703014c
curl http://localhost/index.php Connected successfully
docker stop apache docker stop db docker container ls -a
apache db CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
docker image rm pnlug/php:7.2-apache docker image rm mariadb:10.1
Untagged: pnlug/php:7.2-apache Deleted: sha256:601a713f0b2b75ca4198722eee6213c8536e871a892796eb0407fe2adbf0713a ... Deleted: sha256:11b2e249c2e0c0be9a9dfd5545303c7d4384dd8f4ff1b936ed9391db03db46ba Untagged: mariadb:10.1 Untagged: mariadb@sha256:92e3a5650ed15df2455fa3aa7e2a5370b7c1ba0fdaba33aa2eeb218e6a30d1d2 ... Deleted: sha256:b9997ded97a1c277d55be0d803cf76ee6e7b2e8235d610de0020a7c84c837b93 Deleted: sha256:a090697502b8d19fbc83afb24d8fb59b01e48bf87763a00ca55cfff42423ad36
version: '3.1' services: apache: container_name: apache build: context: . dockerfile: Dockerfile-php image: pnlug/php:7.2-apache volumes: - ./htdocs/:/var/www/html/ depends_on: - db ports: - 80:80 db: container_name: db image: mariadb:10.1 environment: MYSQL_DATABASE: test MYSQL_USER: test MYSQL_PASSWORD: test MYSQL_RANDOM_ROOT_PASSWORD: '1' volumes: - mysql-test:/var/lib/mysql volumes: mysql-test
docker-compose build
docker-compose up
docker-compose down
Stopping apache ... done Stopping db ... done Removing apache ... done Removing db ... done Removing network examples_default
Build a Wordpress project
“docker 101” © 2019 di Stefano Morandi | Cristian Pavan
pubblicato con licenza Creative Commons license CC BY-SA 4.0.