Настройка сетей в Docker: как связать контейнеры между собой.

Использование Docker и контейнеризации уже давно является неотъемлемой частью практически любой инфраструктуры. Но редко когда все ограничивается отдельными контейнерами.

Одним из важных аспектов работы с Docker является настройка сетевого взаимодействия между ними. В этой статье мы подробно расскажем, как связать два контейнера в одну подсеть.

В качестве примера  мы запустим один контейнер с сервером базы данных MariaDB, а другой на основе образа с Alpine Linux, который будет общаться с базой.

Почему важно правильно настраивать сетевые соединения в Docker

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

Шаг 1: Создание пользовательской сети в Docker

Для удобства и безопасности рекомендуется создавать отдельную пользовательскую сеть. Это позволяет легко управлять связью контейнеров и избегать конфликтов с другими сетями Docker.

Создадим сеть database_network с помощью команды network create:

[root@waky ~]# docker network create database_network
2d6c22a4626a9a956ad2f83815361f7242808bb631d01965d56cc119bb057f67
[root@waky ~]# docker network list
NETWORK ID     NAME               DRIVER    SCOPE
8f3fd2da4acb   bridge             bridge    local
2d6c22a4626a   database_network   bridge    local
602c54ccfb29   host               host      local
b2794e5ceb20   none               null      local
[root@waky ~]#

network list выводит список существующих сетей. Наша новая сеть успешно создалась. По умолчанию сеть имеет тип bridge. О том какие еще бываю типы сетей в Docker и чем они отличаются мы рассмотрели в отдельной статье.

Шаг 2: Запуск контейнера с MariaDB

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

[root@waky ~]# docker run -d --name mariadb_container  --network database_network  -e MYSQL_ROOT_PASSWORD=some_password mariadb:latest
Unable to find image 'mariadb:latest' locally
latest: Pulling from library/mariadb
4b3ffd8ccb52: Pull complete
7854007237e1: Pull complete
8ed1b5271813: Pull complete
402f4c7dd065: Pull complete
2295facceabc: Pull complete
eece26ecda4b: Pull complete
4c2e197f6cb0: Pull complete
6499e85d8558: Pull complete
Digest: sha256:5b6a1eac15b85b981a61afb89aea2a22bf76b5f58809d05f0bcc13ab6ec44cb8
Status: Downloaded newer image for mariadb:latest
a31e04bb7725e9dedf4e667c7f41481707021511b54829cd158247c5ea04317e
[root@waky ~]#

Использованные аргументы:

-d — запуск в фоновом режиме
–name — задаем имя контейнера
–network — подключение к указанной сети
-e — задаем переменные окружения, например, пароль для пользователя root
mariadb:latest — образ из которого создается контейнер

Шаг 3: Запуск контейнера на базе Alpine Linux

Теперь запускаем второй контейнер, который будет подключаться к базе данных. Не забудьте указать сеть, в которой будет работать контейнер:

[root@waky ~]# docker run -d -it --name alpine_app  --network database_network  alpine:latest sh
b01829ba0fba60c6261a7256cc1f559d8468696b2d9ff6d704b2bbb9e654b8fa

Использованные аргументы:

-it — интерактивный режим
alpine:latest – используемый образ

На данном этапе у нас работают два контейнера:

[root@waky ~]# docker ps
CONTAINER ID   IMAGE            COMMAND                  CREATED          STATUS          PORTS      NAMES
b01829ba0fba   alpine:latest    "sh"                     13 seconds ago   Up 12 seconds              alpine_app
a31e04bb7725   mariadb:latest   "docker-entrypoint.s…"   7 minutes ago    Up 7 minutes    3306/tcp   mariadb_container
[root@waky ~]#

Шаг 4: Подключение второго контейнера к базе данных

Зайдем в консоль контейнера. Находясь внутри контейнера alpine_app, вы можете установить необходимые инструменты и подключиться к базе данных MariaDB. Например, установим mariadb-client:

[root@waky ~]# docker exec -it alpine_app sh
/ # apk add mariadb-client
fetch https://dl-cdn.alpinelinux.org/alpine/v3.22/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.22/community/x86_64/APKINDEX.tar.gz
(1/6) Installing mariadb-common (11.4.8-r0)
(2/6) Installing libgcc (14.2.0-r6)
(3/6) Installing ncurses-terminfo-base (6.5_p20250503-r0)
(4/6) Installing libncursesw (6.5_p20250503-r0)
(5/6) Installing libstdc++ (14.2.0-r6)
(6/6) Installing mariadb-client (11.4.8-r0)
Executing busybox-1.37.0-r19.trigger
OK: 49 MiB in 22 packages
/ #

Затем подключаемся к базе данных, указав имя контейнера с MariaDB как хост:

/ # mariadb -h mariadb_container -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 10
Server version: 12.0.2-MariaDB-ubu2404 mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>

Использованные аргументы:

-h – имя хоста, на котором работает база данных
-u – пользователь, который осуществляет подключение
-p – использование пароля

Мы подключились к серверу MariaDB. Далее в консоли мы можем выполнять стандартные команды. Создадим новую базу данных:

MariaDB [(none)]> CREATE DATABASE MY_APP_DATABASE;
Query OK, 1 row affected (0.003 sec)
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| MY_APP_DATABASE    |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.011 sec)
MariaDB [(none)]>

Проверим, что база создана не локально (хоть это и очевидно, в данном контейнере есть только клиент базы, но не сервер).

Выйдем из контейнера с alpine и подключимся к контейнеру с сервером MariaDB. Убедимся, что созданная нами база на месте.

MariaDB [(none)]> exit
Bye
/ # exit
[root@waky ~]# docker exec -it mariadb_container sh
# mariadb -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 11
Server version: 12.0.2-MariaDB-ubu2404 mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| MY_APP_DATABASE    |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.001 sec)
MariaDB [(none)]> exit
Bye
# exit
[root@waky ~]#

Отлично, база на месте, контейнеры связаны по сети. Но вы же не хотите каждый раз настраивать все вручную?

Удалим контейнеры созданные вручную, прежде чем перейти к следующей главе:

[root@waky my-app]# docker stop alpine_app mariadb_container
alpine_app
mariadb_container
[root@waky my-app]# docker rm alpine_app mariadb_container
alpine_app
mariadb_container
[root@waky my-app]#

Шаг 5: Автоматизируем создание контейнеров и сети через Docker Compose

Хотя можно запускать контейнеры отдельно с помощью команд, рекомендуется использовать Docker Compose для автоматизации запуска и связи контейнеров.

Если вы еще не знакомы с Docker Compose, у нас про него есть отдельная статья.

Создадим отдельную директорию, и перейдем в нее:

[root@waky ~]# mkdir my-app/
[root@waky ~]# cd my-app/

Создаем Dockerfile для базы данных MariaDB

Подробнее об использовании Dockerfile можно узнать в статье посвященной образам в Docker. Создадим директорию MariaDB и Dockerfile в ней:

[root@waky my-app]# mkdir ./MariaDB
[root@waky my-app]# touch ./MariaDB/Dockerfile
[root@waky my-app]#

С помощью текстового редактора заполним ./MariaDB/Dockerfile следующим содержанием:

FROM mariadb:latest
ENV MYSQL_ROOT_PASSWORD=some_password

Этот Dockerfile основан на официальном образе MariaDB и задает пароль для root.

Создаем Dockerfile для Alpine Linux контейнера

Создадим директорию AlpineAppи Dockerfile в ней:

[root@waky my-app]# mkdir ./AlpineApp
[root@waky my-app]# touch ./AlpineApp/Dockerfile
[root@waky my-app]#

Заполним ./AlpineApp/Dockerfile:

FROM alpine:latest
RUN apk add --no-cache mariadb-client
CMD ["sleep", "infinity"]

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

Создание и запуск контейнеров с помощью Docker Compose

Подготовим файл docker-compose.yml следующего содержания:

services:
  db:
    build: ./MariaDB
    container_name: mariadb_container
    environment:
      MYSQL_ROOT_PASSWORD: some_password
    networks:
      - my_network
  app:
    build: ./AlpineApp
    container_name: alpine_app
    networks:
      - my_network
    depends_on:
      - db
networks:
  my_network:
    driver: bridge

Здесь указано, что оба контейнера строятся из Dockerfile и подключены к одной сети my_network. Это упрощает запуск и управление.

После создания этих Dockerfile и файла docker-compose.yml, осталось только выполнить команду docker compose up:

[root@waky my-app]# docker compose up -d --build
[+] Building 1.3s (14/14) FINISHED
 => [internal] load local bake definitions
0.0s
 => => reading from stdin 871B
0.0s
 => [app internal] load build definition from Dockerfile
0.1s
 => => transferring dockerfile: 180B
0.0s
 => [db internal] load build definition from Dockerfile
0.1s
 => => transferring dockerfile: 156B
0.0s
 => [app internal] load metadata for docker.io/library/alpine:latest
0.0s
 => [app internal] load .dockerignore
0.1s
 => => transferring context: 2B
0.0s
 => [db internal] load metadata for docker.io/library/mariadb:latest
0.0s
 => [db internal] load .dockerignore
0.1s
 => => transferring context: 2B
0.0s
 => [app 1/2] FROM docker.io/library/alpine:latest
0.0s
 => CACHED [app 2/2] RUN apk add --no-cache mariadb-client
0.0s
 => CACHED [db 1/1] FROM docker.io/library/mariadb:latest
0.0s
 => [app] exporting to image
0.1s
 => => exporting layers
0.0s
 => => writing image sha256:40549ff53dc25982ad29950aa115bc792eaec30b7b248daef99e552e2b852f1c
0.0s
 => => naming to docker.io/library/my-app-app
0.0s
 => [db] exporting to image
0.1s
 => => exporting layers
0.0s
 => => writing image sha256:787ab2e04399ec08e81a0741377d9bacaa1bf63178b31310bd5d40e49f53f501
0.0s
 => => naming to docker.io/library/my-app-db
0.0s
 => [db] resolving provenance for metadata file
0.0s
 => [app] resolving provenance for metadata file
0.0s
[+] Running 5/5
 ✔ my-app-db                    Built
0.0s
 ✔ my-app-app                   Built
0.0s
 ✔ Network my-app_my_network    Created
0.5s
 ✔ Container mariadb_container  Started
0.8s
 ✔ Container alpine_app         Started
1.5s
[root@waky my-app]#

Это автоматически соберет образы и запустит контейнеры, подключенные к одной подсети. Теперь ваш Alpine контейнер сможет подключаться к базе данных MariaDB в соседнем контейнере.

Проверим это:

[root@waky my-app]# docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED         STATUS         PORTS      NAMES
5ef2689ded0e   my-app-app   "sleep infinity"         5 minutes ago   Up 5 minutes              alpine_app
4ea742c85c36   my-app-db    "docker-entrypoint.s…"   5 minutes ago   Up 5 minutes   3306/tcp   mariadb_container
[root@waky my-app]# docker exec -it alpine_app sh
/ # mariadb -h mariadb_container -u root -p
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 3
Server version: 12.0.2-MariaDB-ubu2404 mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]>

Все работает, как задумано.

Заключение

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

На примере MariaDB и Alpine, мы показали, как быстро связать базу данных с приложением, запущенным в другом контейнере.

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