Skip to content

Docker

Установка Docker

  • Для начала необходимо перейти на сайт разработчика.

  • Далее открываем терминал и поэтапно прописываем команды в разделе Install using the apt repository.

  • После чего переходим по https://docs.docker.com/desktop/install/ubuntu/, скачиваем и устанавливаем десктоп версию.

  • Docker установлен.

ПРИМЕЧАНИЕ! Докер команды не буду запускаться без прав root, поэтому для удобства внесем свою учетку в группу Docker. Для этого пропишем команды:


sh
	$ sudo usermod -aG docker ${USER}

Теперь перелогинимся


sh
	$ su - ${USER}

Что такое докер

Работа с Dockerfile

Если вы прочитали статью выше, то у вас есть представление о работе Docker. В таком случае давайте познакомимся с Docker-файлом, который отвечает за сборку вашего приложения для дальнейшей эксплуатации. При создании файл так и должен называться - Dockerfile.

Рассмотрим работу с файлом на примере данной документации, образ которой собирается с помощью этого метода.

Как мы знаем, при формировании образа, Docker образует контейнер, в который помещается наше приложение. В Dockerfile мы указываем, каким образом наше приложение будет себя вести в контейнере - это происходит за счет команд, которые мы впишем.

  • Первое, что необходимо сделать, это задать image, благодаря которому будут доступны те или иные команды. Учитывая, что вначале мы используем базовые команды нашей ОС, то образ берется соответствующий:
docker
FROM ubuntu:22.04
Все образы берутся из DockerHub.
  • Далее в контейнере мы создаем рабочую директорию, с помощью команды WORKDIR. Командой COPY мы помещаем все локальные файлы в созданную директорию в контейнере, которая обозначается точкой.

INFO

В Dockerfile мы можем использовать несколько образов, так как определенные этапы выполняются определенными программами.

  • Так как разворачивать наше приложение мы будем на базе nginx, то и образ мы берем соответствующий.
docker
FROM nginx:1.23.4
  • RUN выполняет команду внутри контейнера и сохраняет результат. В данном примере мы очистили папку nginx от дефолтного контента

  • И заключительным этапом является копирование релультата предыдущего stage с образом ubuntu в папку nginx

Сборка рабочего образа приложения

После того, как мы закончили с Dockerfile, мы можем собрать образ приложения, который в дальнейшем можно использовать. Для этого пропишем внутри нашего проекта команду:

sh
$ docker build -t NAME:TAG .

Флагом -t мы определяем тэг и название нашей сборки. Если не указать тэг, Docker по дефолту проставит latest.

Контейнер с образом запускается с помощью команды:

sh
$ docker run --rm -p 8080:80 IMAGE_ID
  • --rm удалить контейнер после его остановки;
  • -p задает, на каком порту будет раполагаться наше приложение, в нашем случае это localhost:8080;

Также можно добавить флаг -d (detach), чтобы после запуска контейнера вам не пришлось открывать еще один терминал для команд. Но для первичного запуска все же рекомендую этого не делать, чтобы посмотреть логи на возможные ошибки.

Docker Compose

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

Docker Compose используется для одновременного управления несколькими контейнерами, входящими в состав приложения. Этот инструмент предлагает те же возможности, что и Docker, но позволяет работать с более сложными приложениями.

Рассмотрим работу Docker compose на примере развертывания базы данны данных, используя Postgresql и Nexus

Для работы на необходимо создать файл: docker-compose.yml. Данный файл представляет собой ту же конфигурацию, что мы можем указать при запуске одиночного контейнера.

Разберем скрин выше:

Version указывает версию docker compose;

Network - опция, которая отвечает за конфигурацию сети, которую мы будем использовать. Более подробно поговорим об это ниже;

Services - раздел, в котором мы описываем приложения, с которыми собираемся работать;

Network

Контейнеры в процессе работы, как правило, общаются между собой. Для этого они должны находиться в одной сети.

Типы сетей, которые успользуются в docker следующие:

  1. bridge;

  2. overlay;

  3. host;

  4. none;

  5. macvlan;

Об назначени всех сетей смотреть здесь

Мы будем использовать сеть bridge, чтобы наши контейнеры общались в пределах нашей машины.

Чтобы посмотреть информацию о сети, используется команда:

bash
docker network inspect NETWORK_NAME

Здесь же мы увидим, какие контейнеры подключены к нашей сети и какие у них адреса.

Чтобы создать сеть в docker compose, используется следующая конфигурация:

yml
Network:
    mynet: # Имя сети.
        driver: bridge # Тип сети.
        ipam:
            config:
                subnet: 172.28.0.0/16 # Адрес сети, который можно назначить в ручную.

Обратите внимание на раздел ipam. В нем мы можем сами назначить адрес сети. Исходя из этого, адерса контейнеров будут 172.28.0.*/16. Звездочка в данном случае, индивидуальное число у каждого контейнера.

Services

В этом разделе описываются непосредственно контейнеры, с которыми предстоит работать.

Описание одного из контейнеров, например, postgres, будет состоять из следующих значений:

yml
postgres:
    container_name: postgres-container
    image: postgres:15.2
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=pg123
    hostname: postgres
    volumes:
      - ./init_db.sql:/docker-entrypoint-initdb.d/init_db.sql
      - ./postgresql:/var/lib/postgresql/data/
      - ./backup:/var/lib/postgresql/data/postgres/backup/
    ports:
      - "5432:5432"
    networks:
      - mynet
    restart: unless-stopped
    command: -c "max_connections=1000"

Что мы имеем?

  • Имя контейнера, которое мы используем для связи с контейнером nexus, так как сеть bridge поддерживает передачу с другим контейнером не только по адресу, но и по его имени;

  • Версию приложения, которая будет скачена с Dockerhub автоматически;

  • Переменные окружения, в нашем случае это логин и пароль от админки ПГ. Обратите внимание, что данные переменные имеют названия по умолчанию.

  • Устанавливаем имя хоста, который в последующем отметим в контейнере nexus для определенной задачи;

  • Далее мы указываем, какие папки, файлы мы хотим поместить в контейнер перед его запуском.

    • Например, у нас стоит задача, снять бекап с рабочей базы и развернуть её локально, у нас на компьютере. Для этого мы помещаем файл с данными бекапа в папку backup, которая располагается, в данном примере, в одной директории с файлом Docker compose и указываем, что эти данные после старта контейнера буду также находить в папке /var/lib/postgresql/data/postgres/backup/.

    • Помимо передачи данных в контейнер, мы можем передавать конфигурационные файлы, которые сработают, как только мы запустим контейнер. Например, нам нужно создать пользователя для контейнера nexus, чтобы у него было возможность подключиться к нашей БД. Для это существует директория /docker-entrypoint-initdb.d, куда мы и помещаем конфигурационный файл.

    В нем мы создаем БД, пользователя и выдаем ему полные права на данную БД.

  • После того, как мы передали значения в контейнер, назначим ему порт, по которому он будт прослушиваться;

  • Выделим сервису ранее созданную рабочую сеть;

  • Скажем ему производить рестарт после неудачного запуска;

  • Раздел command мы используем, чтобы задать максимальное кол-во подключений к нашей БД;

Сервис Nexus свою очередь также имеет описание:

yml
nexus:
    container_name: nexus_container
    depends_on: # Данное значение указывает, что контейнер не запуститься, пока не запуститься postgres. Здесь как раз используется hostname.
      - postgres
    image: nexus:latest
    environment:
      - NEXUS_DATASTORE_NEXUS_JDBCURL=jdbc:postgresql://postgres-container:5432/nexus_restore # Адрес нашей БД, чтобы нексус смог к ней подключиться.
      - NEXUS_DATASTORE_NEXUS_PASSWORD=nexus123 
      - NEXUS_DATASTORE_NEXUS_USERNAME=nexus
      - NEXUS_SECURITY_RANDOMPASSWORD=false
    volumes:
      - ./nexus:/opt/sonatype/nexus/pgdata
    ports:
      - "8081"
    networks:
      - mynet
    restart: unless-stopped

Обратите внимание, что в адресе нашей БД мы указали название контейнера, так как с помощью сети bridge можно ограничиться только этим.

Запуск контейнеров

Для запуска приложений используется команда:

bash
docker compose up

WARNING

Важный момент! Если вы запустите контейнеры командой выше, то nexus при запуске начнет заполнять своими дефолтными значениями нашу БД. После чего придется их сносить, чтобы загрузить ранее созданный бекап. Чтобы этого избежать, необходимо сначала отдельно запустить Postgres и после всех операций запустить Nexus.

bash
docker compose up SERVICE_NAME

Далее нам необходимо выгрузить в созданную нами БД данные, которые мы сняли с с рабочей базы. Для этого необходимо подключиться к контейнеру Postgres, исполльзуя команду:

bash
docker exec -it CONTAINER_ID bash

Для выгрузки данных в БД в Postgres используется команда pg_restore в сочетании адреса, хоста БД, а также информации о пользователе, под которым будет выполнен вход в БД и совершена выгрузка данных.

Так как мы и так с вами находимся в контейнере, где располагается БД, можно не указывать его адрес при подключении, а ограничиться localhost:

bash
gunzip -c FILE_PATH | psql -h localhost -p 5432 -U postgres -d mydb

После некоторой загрузки, запускаем Nexus-контейнер:

bash
docker compose up nexus

Адрес веба лежит в списке контейнеров докера.