Мой первый Docker!

Опубликовано admin - ср, 07/06/2022 - 22:21

Docker

Сколько статей, но не из всех из них у меня получилось собрать более -менее рабочий Docker

Итак. Для чего он нужен. Он необходим для быстрого развертывания однообразного окружения для разработки разных приложений, к примеру на php и mysql. 

В результате прочтения Вас будет полностью настроенный Docker для php, symfony, mysql. 

Для начала его использования необходим установить. У меня Ubuntu (команда uname -a):

Linux alex-X470 5.13.0-52-generic #59~20.04.1-Ubuntu SMP Thu Jun 16 21:21:28 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Устанавливаем Docker.

Подробно об этом сказано  на официальном сайте https://docs.docker.com/engine/install/ubuntu/.

Приведём основные команды и поясним их.

Для начала удалим предыдущие версии Docker:

sudo apt-get remove docker docker-engine docker.io containerd runc

Далее устанавливаем через дополнительные пакеты необходимы для работы Docker:

 sudo apt-get update
 sudo apt-get install \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

и репозиторий:

sudo mkdir -p /etc/apt/keyrings
 curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
 echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

Без Doсker Engine работать не будет:

 sudo apt-get update
 sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Эти команды устанавливают "Docker Engine".

Помимо этого, нам нужен Docker Compose. Подробно об этом написано в Install Docker Compose.

После это у Вас будет доступна информация о Docker:

$ docker -v
Docker version 19.03.8, build afacb8b
$ docker-compose -v
docker-compose version 1.25.4, build 8d51620a

Если Вы собираетесь устанавливать Docker Desktop, то при его установке Docker compose устанавливается самостоятельно.

Далее с чего начать. Это с создания директории в которой будут запускаться и создаваться контейнеры Docker. В моем случае это директория docker-test/.

Имя директории используется в Docker, поэтому выберите что-нибудь попроще (сразу скажу оно необходимо для связывания сетей в Docker). 

Наша структура будет выглядеть следующим образом:

Docker

 

Nginx

Код из nginx/default.conf:

server {

    listen 80;
    index index.php;
    server_name localhost;
    root /var/www/docker-test/public;
    error_log /var/log/nginx/project_error.log;
    access_log /var/log/nginx/project_access.log;

    location / {
        try_files $uri /index.php$is_args$args;
    }

    location ~ ^/index\\.php(/|$) {
        fastcgi_pass php:9000;
        fastcgi_split_path_info ^(.+\\.php)(/.*)$;
        include fastcgi_params;

        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;

        fastcgi_buffer_size 128k;
        fastcgi_buffers 4 256k;
        fastcgi_busy_buffers_size 256k;

        internal;
    }

    location ~ \\.php$ {
        return 404;
    }

}

Код файла php/Dockerfile:

FROM php:8.0-fpm

RUN apt update \
    && apt install -y zlib1g-dev g++ git libicu-dev zip libzip-dev libmagickwand-dev libmagickcore-dev \
        libfreetype6-dev \
        libjpeg62-turbo-dev \
        libpng-dev \
    && docker-php-ext-configure gd --with-freetype --with-jpeg \
    && docker-php-ext-install intl opcache pdo pdo_mysql gd \
    && pecl install apcu \
    && docker-php-ext-enable apcu \
    && docker-php-ext-configure zip \
    && docker-php-ext-install zip \
    && docker-php-ext-install exif \
    && pecl install imagick \
    && docker-php-ext-enable imagick

RUN cd /usr/local/etc/php/conf.d/ && \
  echo 'memory_limit = -1' >> /usr/local/etc/php/conf.d/docker-php-ram-limit.ini
RUN apt-get update && apt-get install -y nodejs \
    -y npm \
    && npm install --global yarn

WORKDIR /var/www/docker-test

RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

RUN curl -sS https://get.symfony.com/cli/installer | bash
RUN mv /root/.symfony/bin/symfony /usr/local/bin/symfony
RUN git config --global user.email "eap1985@rambler.ru" \
    && git config --global user.name "eap1985"

Обратите внимание на WORKDIR /var/www/docker-test и команды RUN. Последние две строки заменить своими данными. Данный код является стандартным, он размещен в https://hub.docker.com/_/php. Дополнительно вы можете указать следующий с настройками php для библиотеки GD:

FROM php:7.4-fpm
RUN apt-get update && apt-get install -y \
		libfreetype6-dev \
		libjpeg62-turbo-dev \
		libpng-dev \
	&& docker-php-ext-configure gd --with-freetype --with-jpeg \
	&& docker-php-ext-install -j$(nproc) gd

Директории app (создается для symfony, указано ниже), mysql, docker создаются самостоятельно при запуске команды sudo docker-compose up: 

Код файла docker-compose.yml:

version: '3.2'

services:
  database:
    container_name: database
    image: mysql
    command: --default-authentication-plugin=mysql_native_password
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: my-secret-pw
      MYSQL_ROOT_HOST: "%"
      MYSQL_DATABASE: symfony_docker
      MYSQL_USER: symfony
      MYSQL_PASSWORD: symfony
    ports:
      - '4306:3306'
    volumes:
      - /data/mysql:/var/lib/mysql
      - ./container-my.cnf:/etc/my.cnf
    networks:
      - docker-test_default
  php:
    container_name: php
    build:
      context: ./php
    ports:
      - '9000:9000'
    volumes:
      - ./app:/var/www/docker-test
    depends_on:
      - database
    links:
      - database
    networks:
      - docker-test_default

  nginx:
    container_name: nginx
    image: nginx:stable-alpine
    ports:
      - '8081:80'
    volumes:
      - ./app:/var/www/docker-test
      - ./nginx/default.conf:/etc/nginx/conf.d/default.conf
      - phpmyadmin_data:/var/www/html/:ro
    networks:
      - docker-test_default
    depends_on:
      - database
      - phpmyadmin

  # phpMyAdmin container
  phpmyadmin:
    # Use phpmyadmin/phpmyadmin:5.0.2 image
    image: phpmyadmin/phpmyadmin:5.0.2
    # Connect to "my-network" network, as defined below
    networks:
      - docker-test_default
    # Map port 8080 on the host to port 80 inside the container
    # Syntax is: "HOST_PORT:CONTAINER_PORT"
    ports:
      - "8085:80"
    # Pass a list of environment variables to the container
    environment:
      PMA_HOST: database
    # Wait for "mysql" container to start first
    depends_on:
      - database

networks:
  docker-test_default:

volumes:
  phpmyadmin_data:

Файл содержит четыре контейнера с соответствующими настройками:

  1. database
  2. docker-test_phpmyadmin_1
  3. php
  4. nginx

Также обратите внимание на секции volumes.

Volumes are the preferred mechanism for persisting data generated by and used by Docker containers

Другими словами они сохраняют информацию и заполняют ею при запуске контейнера наш Docker.

При наличии данного файла можно попробовать запустить наш Docker, командой:

sudo docker-compose up

запуск сопровождается следующим:

alex@alex-X470:/var/www/docker-test$ sudo docker-compose up --force-recreate
Creating network "docker-test_docker-test_default" with the default driver
Creating database ... done
Creating docker-test_phpmyadmin_1 ... done
Creating php                      ... done
Creating nginx                    ... done
Attaching to database, docker-test_phpmyadmin_1, php, nginx
database      | 2022-07-06 16:58:22+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1.el8 started.
php           | [06-Jul-2022 16:58:23] NOTICE: fpm is running, pid 1
database      | 2022-07-06 16:58:22+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
nginx         | /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
nginx         | /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
php           | [06-Jul-2022 16:58:23] NOTICE: ready to handle connections
nginx         | /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
database      | 2022-07-06 16:58:22+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.29-1.el8 started.
nginx         | 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
phpmyadmin_1  | phpMyAdmin not found in /var/www/html - copying now...
database      | '/var/lib/mysql/mysql.sock' -> '/var/run/mysqld/mysqld.sock'
phpmyadmin_1  | Complete! phpMyAdmin has been successfully copied to /var/www/html
....................................

Сейчас по адресу http://localhost:8081/ станет доступным сервер php, а по адресу http://localhost:8085 phpMyAdmin. Ура 🎉!

Дополнительные команды, которые Вам понадобятся:

Команда выводит все контейнеры Docker:

sudo docker ps

Команда удаляет все контейнеры Docker:

sudo docker container prune

 Команда запускает контейнеры разом:

sudo docker-compose up --force-recreate

  Команда останавливает контейнеры разом:

sudo docker-compose down

  Команда для запуска в образ:

docker-compose exec php /bin/bash 

Типичные ошибки при сборке первого Docker.

mysqli::real_connect(): php_network_getaddresses: getaddrinfo failed: Temporary failure in name resolution  mysqli::real_connect(): (HY000/2002):

Эта ошибка возникала у меня при запуске phpMyAdmin. Связна она, по мнению многих, с не указанием директивы networks в файле docker-compose.yml.

networks:
      - docker-test_default

 Ошибка с синтаксисом файла:

ERROR: The Compose file './docker-compose.yml' is invalid because:
services.nginx.networks contains an invalid type, it should be an array, or an object

 Команда docker-compose exec php ......

Данная команда очень существенная для разработки. Документация по ней имеется на сайте docs.dokcer.com

Через нее происходит выполнение команд внутри контейнера.

docker-compose exec php /bin/bash

К примеру, в этом случае у вас имеется доступ к php, где мы можем запустить symfony cli:

symfony check:requirements

Если все в порядке, то дальше можно перейти к установке приложения symfony:

symfony new .

После чего можно увидеть по адресу рабочий стол symfony:

Docker Symfony

Другой разновидностью может выступать команда:

docker-compose exec database /bin/bash

 С ее помощью мы получаем доступ к контейнеру database.  А внутри его к mysql.

Например:

mysql -u root -p symfony_docker

Таким образом мы настроили первый Docker.

Сохранение данных в Docker

Сохранение данных в Docker является не очень простым делом как оказалось. Осуществляется оно через volumes.

Если Вы внимательно посмотрите на четыре предыдущих контейнера, то в каждом из них имеется директива volumes. К примеру в секции mysql:

    volumes:
      - ./data/mysql:/var/lib/mysql

Это означает, что данные сохраняются из var/lib/mysq в ./data/mysql. Это необходимо знать, так как без этого, не сохраните и не замените то, что вы наработали в mysql.

Для сохранения можно воспользоваться командой: docker run --rm --volumes-from $container ubuntu tar -zcvf- /var/lib/mysql > /tmp/backup.tar.gz Замените $container на имя или ID вашего контейнера.

Для сохранения базы из Docker используйте следующую команду:

docker exec CONTAINER_id /usr/bin/mysqldump -uusername --password=yourpassword databasename> backup.sql

Для импорта в windows у меня не совсем подошла команда, хотя она вполне работает:

Get-Content backup.sql | docker exec -i database mysql -uroot -pmy-secret-pw symfony_docker

Лучше сперва скопировать данные:

docker container cp .\backup.sql database:/backup.sql

 а затем использовать:

mysql -uroot -pmy-secret-pw symfony_docker < backup.sql

В следующей статье я расскажу как сохранять данные с помощью официального сайта Docker.

Взаимосвязанные материалы

# 1. Мой первый Docker! (среда, июля 6, 2022 - 22:21 ),
Итак. Для чего он нужен. Он необходим для быстрого развертывания однообразного окружения для разработки разных приложений, к примеру на php и mysql о чем мы будем говорить далее. читать...
На разработку сайта! Скидки до 20%!