Мережі та томи в Docker: як контейнери бачать одне одного і де живуть дані
Bridge, host і внутрішні мережі, публікація портів, іменовані томи проти bind-mount і чому дані не повинні жити всередині контейнера.
Контейнер — це ізольований процес: своя файлова система, свій мережевий стек. Два питання виникають у всіх, хто запускає щось складніше за «hello world»: як контейнерам спілкуватися і де зберігати дані, щоб вони не зникли.
Типи мереж
| Драйвер | Що це | Коли використовувати |
|---|---|---|
bridge (за замовчуванням) |
Віртуальна мережа на хості з NAT назовні | Більшість застосунків на одному хості |
Користувацька bridge |
Те саме + DNS за іменами контейнерів | Завжди замість стандартної bridge |
host |
Контейнер використовує мережу хоста напряму | Максимальна мережева продуктивність, Linux |
none |
Без мережі | Пакетні задачі, що не потребують мережі |
overlay |
Мережа між кількома хостами | Swarm, кластери |
Чому стандартна bridge — погана ідея
У стандартній мережі bridge контейнери не знаходять одне одного за іменами. У користувацькій — знаходять через вбудований DNS:
docker network create app-net
docker run -d --name db --network app-net \
-e POSTGRES_PASSWORD=secret postgres:17-alpine
docker run --rm --network app-net postgres:17-alpine \
pg_isready -h db -U postgres
# db:5432 - accepting connectionsDocker Compose створює окрему мережу для кожного проєкту автоматично — тому там імена сервісів працюють «самі».
Ізоляція: внутрішні мережі
База даних не повинна бути доступна ззовні — і бажано, щоб вона сама не ходила в інтернет. Для цього є прапорець internal:
services:
app:
networks: [frontend, backend]
db:
networks: [backend]
networks:
frontend: {}
backend:
internal: true # без виходу назовні і без доступу ззовніЗастосунок бачить і інтернет, і базу; база — лише застосунок.
Публікація портів: обережно з 0.0.0.0
docker run -p 5432:5432 postgres # відкрито на ВСІХ інтерфейсах хоста
docker run -p 127.0.0.1:5432:5432 postgres # лише локальноОбережноDocker сам додає правила в iptables для опублікованих портів і може обійти налаштування фаєрволу на кшталт UFW. Опублікований
-p 5432:5432на сервері з публічною IP-адресою — відкрита в інтернет база, навіть якщо UFW «все блокує». Публікуйте порти лише на127.0.0.1або взагалі не публікуйте, а ходіть через реверс-проксі.
Де живуть дані
Файлова система контейнера тимчасова: видалили контейнер — зникли дані. Для всього, що має пережити перезапуск, є три варіанти:
| Тип | Приклад | Особливості |
|---|---|---|
| Іменований том | -v pgdata:/var/lib/postgresql/data |
Керує Docker, переносний, найкращий для баз |
| Bind-mount | -v ./config:/etc/app:ro |
Папка з хоста; зручно для конфігів і коду в розробці |
| tmpfs | --tmpfs /tmp |
У пам'яті, зникає після зупинки; для тимчасових і чутливих файлів |
docker volume ls
docker volume inspect pgdata # де фізично лежать дані
docker volume rm pgdata # видалити (лише якщо не використовується)
docker system df -v # скільки місця займають томиПорадаМонтуйте конфіги з прапорцем
:ro(лише читання). Якщо застосунок зламають, він не зможе переписати власну конфігурацію.
Права на файлах у bind-mount
Часта проблема: контейнер працює від користувача з UID 1000, а папка на хості належить root — і застосунок не може писати.
# Подивитися, від кого працює процес у контейнері
docker exec app id
# uid=1000(node) gid=1000(node)
# Віддати папку цьому UID на хості
sudo chown -R 1000:1000 ./dataІменовані томи цієї проблеми зазвичай не мають: Docker копіює права з образу при першому монтуванні.
Бекап тому
docker run --rm \
-v pgdata:/data:ro \
-v "$(pwd)":/backup \
alpine tar czf /backup/pgdata-$(date +%F).tar.gz -C /data .УвагаКопіювати файли працюючої бази даних — ризиковано: можна отримати неконсистентну копію. Для PostgreSQL використовуйте
pg_dumpабоpg_basebackup, а файловий бекап робіть при зупиненому контейнері.
Ви запустили nginx з -p 8080:80, а UFW на сервері дозволяє лише 22 і 443. Чи доступний 8080 з інтернету?
Так, найімовірніше доступний. Docker додає власні правила в iptables (ланцюжок DOCKER), які обробляються раніше за правила UFW. Щоб порт був недоступний ззовні, публікуйте його як 127.0.0.1:8080:80 або налаштуйте правила в ланцюжку DOCKER-USER.
Збережіть статтю собі
Увійдіть, щоб імпортувати її у власні нотатки, відмічати вивчене, ставити лайки й питати спільноту. Реєстрація безкоштовна: вхід через Google займає кілька секунд.
Увійти через Google Інші способи входу