← Все статьи
· 9 мин чтения

PowerDNS с PostgreSQL бэкендом в Docker: от нуля до продакшена

Поднимаем полноценный DNS сервер на PowerDNS с хранением зон в PostgreSQL. Docker Compose, автоматические миграции и PowerDNS-Admin в комплекте.


Почему PowerDNS + PostgreSQL

BIND хорош, но управлять зонами через текстовые файлы в 2025 году — боль. PowerDNS с SQL бэкендом даёт:

  • API для управления зонами
  • Веб-интерфейс через PowerDNS-Admin
  • Удобный бэкап (просто дамп БД)
  • Кластеризацию без ручной синхронизации файлов

Структура проекта

powerdns/
├── docker-compose.yml
├── pdns.conf
└── init/
    └── schema.sql

docker-compose.yml

version: '3.8'

services:
  postgres:
    image: postgres:16-alpine
    environment:
      POSTGRES_DB: pdns
      POSTGRES_USER: pdns
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./init/schema.sql:/docker-entrypoint-initdb.d/schema.sql
    restart: unless-stopped

  pdns:
    image: powerdns/pdns-auth-48:latest
    depends_on:
      - postgres
    ports:
      - "53:53/tcp"
      - "53:53/udp"
      - "8081:8081"
    volumes:
      - ./pdns.conf:/etc/powerdns/pdns.conf
    restart: unless-stopped

  pdns-admin:
    image: ngoduykhanh/powerdns-admin:latest
    depends_on:
      - pdns
    ports:
      - "9191:80"
    environment:
      - SQLALCHEMY_DATABASE_URI=postgresql://pdns:${POSTGRES_PASSWORD}@postgres/pdnsadmin
    restart: unless-stopped

volumes:
  pgdata:

Конфигурация pdns.conf

# Бэкенд
launch=gpgsql
gpgsql-host=postgres
gpgsql-dbname=pdns
gpgsql-user=pdns
gpgsql-password=${POSTGRES_PASSWORD}

# API
api=yes
api-key=${PDNS_API_KEY}
webserver=yes
webserver-address=0.0.0.0
webserver-port=8081
webserver-allow-from=0.0.0.0/0

Запуск

cp .env.example .env
# Редактируем .env — задаём POSTGRES_PASSWORD и PDNS_API_KEY

docker compose up -d

Через 30 секунд PowerDNS-Admin доступен на http://localhost:9191.

Создаём первую зону через API

curl -X POST http://localhost:8081/api/v1/servers/localhost/zones \
  -H "X-API-Key: ${PDNS_API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "example.com.",
    "kind": "Native",
    "nameservers": ["ns1.example.com.", "ns2.example.com."]
  }'

Зона создана. Добавляем A запись аналогичным образом через API или через веб-интерфейс.

Итог

Полноценный DNS сервер с веб-интерфейсом поднимается за 10 минут. Бэкап — просто pg_dump, восстановление — pg_restore на новом сервере и docker compose up.