Environment_Infrastructure/setup/04-test-db-docker-kurulum.md
Murat ÖZDEMİR b115a4cbdf Implement Hetzner sizing report recommendations and detailed DB setups
- Add `hetzner-sizing-report.md` defining data-driven server type recommendations for test and prod environments.
- Update Terraform configurations to align with the recommended `CPX` server types and refine firewall rules for Docker Swarm and database interactions.
- Introduce comprehensive documentation and stack files for:
    - Single-node PostgreSQL/MongoDB deployment on a test DB worker node.
    - High-availability 3-node MongoDB replica set and Patroni+etcd PostgreSQL cluster for production.
- Enhance Ansible bootstrap roles with SELinux disabling, fail2ban configuration, and StorageBox SSH key management for CI/CD.
- Reorganize and rename setup documentation files for improved structure and clarity.
2026-05-11 14:54:09 +03:00

6.8 KiB

08 - Test DB Docker Kurulumu (Swarm)

Bu asamanin amaci iklim-db-01 node'unu Swarm'a worker olarak eklemek ve PostgreSQL ile MongoDB'yi Swarm servisi olarak calistirmaktir. Veri kaliciligini StorageBox saglar.

DB yazilimi Ansible tarafindan kurulmaz; bu belge DB node uzerinde elle veya ayri bir Ansible role ile uygulanir. 03-test-ansible-bootstrap.md tamamlandiktan sonra baslayiniz.

Mimari

iklim-app-01  (Swarm manager, 10.10.10.11)
    |
    |-- iklimco-net (overlay)
    |
iklim-db-01   (Swarm worker, 10.10.20.11) [role=db]
    |-- postgresql-v17  (Swarm service, placement: role=db)
    |-- mongo-v8        (Swarm service, placement: role=db)
    |
    /mnt/storagebox/test/db/
        postgresql/data/
        mongodb/data/
        mongodb/log/
        mongodb/config/

On Kosullar

  • 03-test-ansible-bootstrap.md her iki node'da tamamlanmis olmali.
  • StorageBox /mnt/storagebox olarak her iki node'da mount edilmis olmali.
  • Docker iklim-db-01 uzerinde kurulu olmali (bootstrap role bunu yapar).

1. Firewall Guncellemesi

iklim-db-01'in Swarm'a katilabilmesi icin ek kurallara ihtiyac var. terraform/hetzner/test/firewall.tf dosyasina asagidaki kurallari ekle:

hcloud_firewall.swarm icine (DB subnet'ten Swarm portlarina erisim):

rule {
  direction   = "in"
  protocol    = "tcp"
  port        = "2377"
  source_ips  = [local.db_subnet_cidr]
  description = "Docker Swarm control plane from DB subnet"
}

rule {
  direction   = "in"
  protocol    = "tcp"
  port        = "7946"
  source_ips  = [local.db_subnet_cidr]
  description = "Docker Swarm node discovery (TCP) from DB subnet"
}

rule {
  direction   = "in"
  protocol    = "udp"
  port        = "7946"
  source_ips  = [local.db_subnet_cidr]
  description = "Docker Swarm node discovery (UDP) from DB subnet"
}

rule {
  direction   = "in"
  protocol    = "udp"
  port        = "4789"
  source_ips  = [local.db_subnet_cidr]
  description = "Docker Swarm VXLAN overlay from DB subnet"
}

hcloud_firewall.db icine (app subnet'ten Swarm portlarina erisim):

rule {
  direction   = "in"
  protocol    = "tcp"
  port        = "2377"
  source_ips  = [local.app_subnet_cidr]
  description = "Docker Swarm control plane from app subnet"
}

rule {
  direction   = "in"
  protocol    = "tcp"
  port        = "7946"
  source_ips  = [local.app_subnet_cidr]
  description = "Docker Swarm node discovery (TCP) from app subnet"
}

rule {
  direction   = "in"
  protocol    = "udp"
  port        = "7946"
  source_ips  = [local.app_subnet_cidr]
  description = "Docker Swarm node discovery (UDP) from app subnet"
}

rule {
  direction   = "in"
  protocol    = "udp"
  port        = "4789"
  source_ips  = [local.app_subnet_cidr]
  description = "Docker Swarm VXLAN overlay from app subnet"
}

Sonra uygula:

cd terraform/hetzner/test
terraform apply

2. DB Node'u Swarm'a Ekleme

iklim-app-01 uzerinde join token al:

docker swarm join-token worker

iklim-db-01 uzerinde Swarm'a katil:

docker swarm join --token <TOKEN> 10.10.10.11:2377

iklim-app-01 uzerinde node'u etiketle:

docker node update --label-add role=db iklim-db-01
docker node ls

3. StorageBox Dizin Yapisi

iklim-db-01 uzerinde:

mkdir -p /mnt/storagebox/test/db/postgresql/data
mkdir -p /mnt/storagebox/test/db/mongodb/data
mkdir -p /mnt/storagebox/test/db/mongodb/log
mkdir -p /mnt/storagebox/test/db/mongodb/config

4. PostgreSQL Stack

mongod.conf

/mnt/storagebox/test/db/mongodb/config/mongod.conf dosyasini olustur:

processManagement:
  pidFilePath: "/data/db/mongod.pid"
net:
  port: 27017
storage:
  engine: "wiredTiger"
  dbPath: "/data/db"
  directoryPerDB: true
systemLog:
  verbosity: 0
  timeStampFormat: "iso8601-local"
  destination: file
  path: "/data/log/mongo.log"
  logAppend: true
  logRotate: rename
security:
  authorization: enabled

Stack Dosyasi

/opt/iklimco/stacks/db.yml:

version: "3.8"

networks:
  iklimco-net:
    external: true

services:
  postgresql:
    image: postgis/postgis:17-3.5
    environment:
      POSTGRES_USER: "${DATABASE_POSTGRES_ROOT_USER}"
      POSTGRES_PASSWORD: "${POSTGRES_PASSWORD}"
      POSTGRES_DB: postgres
      PGDATA: /var/lib/postgresql/data/pgdata
      TZ: "Europe/Istanbul"
    volumes:
      - /mnt/storagebox/test/db/postgresql/data:/var/lib/postgresql/data
      - /opt/iklimco/init/postgresql:/docker-entrypoint-initdb.d:ro
    networks:
      - iklimco-net
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.role == db
      restart_policy:
        condition: on-failure

  mongodb:
    image: mongo:8
    environment:
      MONGO_INITDB_ROOT_USERNAME: mongo-root
      MONGO_INITDB_ROOT_PASSWORD: "${MONGO_ROOT_PASSWORD}"
    volumes:
      - /mnt/storagebox/test/db/mongodb/data:/data/db
      - /mnt/storagebox/test/db/mongodb/log:/data/log
      - /mnt/storagebox/test/db/mongodb/config:/data/configdb
    networks:
      - iklimco-net
    command: ["--config", "/data/configdb/mongod.conf"]
    deploy:
      replicas: 1
      placement:
        constraints:
          - node.labels.role == db
      restart_policy:
        condition: on-failure

.env Dosyasi

/opt/iklimco/stacks/.env (repo'ya commit edilmez):

DATABASE_POSTGRES_ROOT_USER=<kullanici-adi>
POSTGRES_PASSWORD=<guclu-sifre>
MONGO_ROOT_PASSWORD=<guclu-sifre>

5. Deploy

# iklim-app-01 uzerinde (Swarm manager)
docker stack deploy --compose-file /opt/iklimco/stacks/db.yml \
  --with-registry-auth \
  $(set -a; source /opt/iklimco/stacks/.env; set +a; echo "") \
  iklim-db

Alternatif olarak env-file destegi icin:

docker stack deploy \
  --compose-file <(docker-compose -f /opt/iklimco/stacks/db.yml config) \
  iklim-db

Kontrol:

docker stack services iklim-db
docker service logs iklim-db_postgresql
docker service logs iklim-db_mongodb

6. App Servislerinden Erisim

Overlay network (iklimco-net) uzerinden servis adlariyla erisim:

Servis Host (overlay DNS) Port
PostgreSQL iklim-db_postgresql 5432
MongoDB iklim-db_mongodb 27017

Spring Boot vb. uygulama konfigurasyon ornegi:

spring.datasource.url=jdbc:postgresql://iklim-db_postgresql:5432/iklimdb
spring.data.mongodb.uri=mongodb://mongo-root:<sifre>@iklim-db_mongodb:27017/iklimdb?authSource=admin

Kabul Kriterleri

  • docker stack services iklim-db her iki servisi 1/1 olarak gosterir.
  • iklim-app-01 uzerinden postgresql servisine TCP 5432 overlay ile ulasilabilir.
  • iklim-app-01 uzerinden mongodb servisine TCP 27017 overlay ile ulasilabilir.
  • /mnt/storagebox/test/db/postgresql/data/ dizininde veri dosyalari olusur.
  • Servis yeniden baslatildiginda veri korunur.
  • 5432 ve 27017 portlari public internet'ten kapalidir.