# 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): ```hcl 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): ```hcl 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: ```bash cd terraform/hetzner/test terraform apply ``` ## 2. DB Node'u Swarm'a Ekleme **iklim-app-01 uzerinde** join token al: ```bash docker swarm join-token worker ``` **iklim-db-01 uzerinde** Swarm'a katil: ```bash docker swarm join --token 10.10.10.11:2377 ``` **iklim-app-01 uzerinde** node'u etiketle: ```bash docker node update --label-add role=db iklim-db-01 docker node ls ``` ## 3. StorageBox Dizin Yapisi **iklim-db-01 uzerinde:** ```bash 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: ```yaml 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`: ```yaml 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): ```env DATABASE_POSTGRES_ROOT_USER= POSTGRES_PASSWORD= MONGO_ROOT_PASSWORD= ``` ## 5. Deploy ```bash # 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: ```bash docker stack deploy \ --compose-file <(docker-compose -f /opt/iklimco/stacks/db.yml config) \ iklim-db ``` Kontrol: ```bash 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:@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.