Использование Docker и контейнеризации уже давно является неотъемлемой частью практически любой инфраструктуры. Но редко когда все ограничивается отдельными контейнерами.
Одним из важных аспектов работы с Docker является настройка сетевого взаимодействия между ними. В этой статье мы подробно расскажем, как связать два контейнера в одну подсеть.
В качестве примера мы запустим один контейнер с сервером базы данных MariaDB, а другой на основе образа с Alpine Linux, который будет общаться с базой.
- Шаг 1: Создание пользовательской сети в Docker
- Шаг 2: Запуск контейнера с MariaDB
- Шаг 3: Запуск контейнера на базе Alpine Linux
- Шаг 4: Подключение второго контейнера к базе данных
- Шаг 5: Автоматизируем создание контейнеров и сети через Docker Compose
Почему важно правильно настраивать сетевые соединения в 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, у нас про него есть отдельная статья.
- Создаем Dockerfile для базы данных MariaDB
- Создаем Dockerfile для Alpine Linux контейнера
- Создание и запуск контейнеров с помощью 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, мы показали, как быстро связать базу данных с приложением, запущенным в другом контейнере.
В будущем вы сможете расширить этот подход, подключая больше контейнеров и создавая сложные сетевые структуры для своих проектов.