Това ще е едно много подробно ръководство за взаимодействието на много контейнери помежду си.
Работим чрез root. Обновяваме хранилищата и системата.
apt update && apt upgrade -y reboot
Обнови се ядрото затова след като завърши процеса, рестартирахме системата. Инсталираме Docker и Docker compose.
apt install docker.io docker-compose -y
Дефинираме потребител работещ с Docker и имащ права sudo.
apt install sudo usermod -aG sudo,docker cccp groups cccp cccp : cccp cdrom floppy sudo audio dip video plugdev users netdev docker
За начало излизаме от потребителя root и влизаме като cccp. Имаме инсталиран Docker и Docker Compose. Да създадем папки в която ще работим с Docker и Docker compose.
sudo mkdir -p ~/docker-project/www sudo mkdir -p ~/docker-project/mysql-data sudo mkdir -p ~/docker-project/images/php
Да започнем с първия контейнер. Стартираме контейнер NGINX от образ. Ако образа не съществува той се изтегля от Docker HUB.
docker run nginx Unable to find image 'nginx:latest' locally latest: Pulling from library/nginx 0c8d55a45c0d: Pull complete 46bf3a120c8e: Pull complete 4f4efe02d542: Pull complete 7b6cb8ccac7b: Pull complete f73400a233fd: Pull complete 47cd406a84ef: Pull complete bae5a1799a80: Pull complete Digest: sha256:341bf0f3ce6c5277d6002cf6e1fb0319fa4252add24ab6a0e262e0056d313208 Status: Downloaded newer image for nginx:latest /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration ....................... и така нататък
Образа е изтеглен и контейнера стартира. В случая конзолата не може да се ползва защото е заета от пуснатия контейнер. Прекъсваме работата на контейнера с Ctrl+c, за да се освободи конзолата. Да пуснем контейнера във фонов режим ще използваме следната команда:
docker run -d nginx 8be6e73ce0674c468f1a9005c90a8f050f903339ccda09d2aff8db20f5716794
Да проверим контейнера дали се е стартирал.
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8be6e73ce067 nginx "/docker-entrypoint.…" About a minute ago Up About a minute 80/tcp distracted_agnesi
Контейнера стартира но ако се пробваме да го достъпим чрез браузър ще получим отрицателен отговор. Това е така защото контейнера работи в капсулован режим. За да може да го ползваме ще се наложи да прехвърлим порт 80/tcp от контейнера към хоста с който работим. Да спрем контейнера и го стартираме с друга опция. Контейнера може да се управлява по име и по ID. Във втория случай не е необходимо да се изписва целия номер, а може да се ползват само първите три символа.
docker stop 8be docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
Нямаме стартирал контейнер. Да стартираме контейнера с прехвърляне на порт 80 към хоста пак на порт 80
docker run -d -p 80:80 nginx
Може да се пробваме да отворим браузъра. http://192.168.11.44/. IP адреса 192.168.11.44 това е адреса на хоста. Отваря се вътрешна страница от контейнера, която ни казва, че NGINX работи.
Много неудобно е да се редактират html страници вътре в контейнера. По-добра практика е контейнера да работи с външни файлове. Изграждаме си сайта на хоста, а контейнера ще ги ползва като свои. За разнообразие няма да спираме този контейнер. Ще пуснем нов пак от образа nginx. Видяхме, че NGINX отваря собствена страница по подразбиране. За да отваря наши страници ще се наложи да създадем файл наречен виртуален хост. Той ще се намира на локалната ни машина.
sudo nano ~/docker-project/vhost.conf server { listen 80; server_name localhost; index index.html; root /var/www/public_html; }
Сега по логиката на прехвърляне на портове ще прехвърлим папки и файлове.
docker run -d -p 80:80 -v ~/docker-project/vhost.conf:/etc/nginx/conf.d/default.conf nginx 0b419c3e3f6cb906c8b9aa812e259ec607a95f47b4d89a686b312d92f5139b38 docker: Error response from daemon: driver failed programming external connectivity on endpoint sad_kapitsa (2067f14beff2f57e37678a37284693851bcc36bae36f3f783690cad1e4a776fe): Bind for 0.0.0.0:80 failed: port is already allocated.
Нарочно направих тази грешка. Порт 80 е зает от предния контейнер и няма как да пуснем новия на същия порт. Или трябва да спрем предния контейнер или да пуснем новия на нов порт. Още една особеност! Всеки път когато пускате docker run не се препокриват контейнерите а се пуска нов. Да спрем стария контейнер.
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a0bb5e872cc3 nginx "/docker-entrypoint.…" 28 minutes ago Up 28 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp optimistic_keldysh docker stop a0b a0b
Наново да пуснем контейнера с прехвърляне на папки и файлове.
docker run -d -p 80:80 -v ~/docker-project/vhost.conf:/etc/nginx/conf.d/default.conf nginx f61dc68464a64b18585e78f39135edcb10543af2c14b505e6a046ec26db4821b
Наново да се пробваме да отворим страницата http://192.168.11.44/. Връща отговор 404 Not Found. Това означава, че vhost.conf е прехвърлен от хоста към контейнера. WEB сървъра е прехвърлил файла дефиниращ виртуалните хостове но не може да открие страници за показване. Да създадем някаква страница за показване през NGINX.
sudo nano ~/docker-project/www/index.html hello world!
Не забравяме да спрем стария контейнер.
docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f61dc68464a6 nginx "/docker-entrypoint.…" 8 minutes ago Up 8 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp quirky_shockley docker stop f61dc68464a6
Сега ще прехвърлим цялата папка а не един файл, както беше предния пример.
docker run -d -p 80:80 -v ~/docker-project/vhost.conf:/etc/nginx/conf.d/default.conf -v ~/docker-project/www:/var/www/public_html nginx
Забележете, прехвърлихме освен файла vhost.conf, също така цялата папка www. Да обновим страницата в браузъра http://192.168.11.44/. Появи се надписа hello world!. Значи правилно сме прехвърлили и папката. Сега няма да ни се налага да променяме файла index.html вътре в контейнера, а ще променяме този който е на хоста и промените ще влизат в контейнера. Между другото когато променяте съдържанието на index.html в хоста не се налага да рестартирате контейнера, промените автоматично ще влизат в сила.