Untuk membuat arsitektur High Availability (HA) menggunakan Docker Compose secara murni pada satu host (untuk kebutuhan development/staging yang meniru produksi), kita perlu menduplikasi service Odoo dan menggunakan sistem replikasi untuk PostgreSQL.
Di bawah ini adalah rancangan Docker Compose yang menggunakan:
- Load Balancer (Nginx): Mengatur beban lalu lintas ke beberapa instance Odoo.
- Odoo Cluster: Dua instance Odoo (Odoo 1 dan Odoo 2) yang berbagi storage untuk data filestore.
- PostgreSQL HA (Bitnami Pgpool-II + Replication): Menggunakan image Bitnami untuk membuat PostgreSQL Master-Slave dengan Pgpool-II sebagai load balancer khusus database (mengatur read/write splitting).
Arsitektur Folder
Sebelum menjalankan Docker Compose, buat struktur folder berikut untuk menyimpan data persistent:
Plaintext
mini-ha-odoo/ ├── docker-compose.yml ├── nginx.conf ├── odoo_data/ └── odoo_addons/
1. Konfigurasi Nginx (nginx.conf)
Buat file nginx.conf untuk membagi beban kerja ke dua kontainer Odoo.
Nginx
events { worker_connections 1024; }
http {
upstream odoo_instances {
# Mengarah ke nama service di docker-compose
server odoo_app_1:8069;
server odoo_app_2:8069;
}
upstream odoo_chat {
server odoo_app_1:8072;
server odoo_app_2:8072;
}
server {
listen 80;
# Proxy untuk longpolling (Chat/Live Notification)
location /longpolling {
proxy_pass http://odoo_chat;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Proxy untuk Traffic Utama Odoo
location / {
proxy_pass http://odoo_instances;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Sangat penting untuk Odoo HA: aktifkan session stickiness jika diperlukan,
# atau pastikan filestore tersinkronisasi dengan benar.
}
# Common optimization
client_max_body_size 128M;
proxy_read_timeout 30000s;
proxy_connect_timeout 3000s;
proxy_send_timeout 3000s;
}
}
2. File Docker Compose (docker-compose.yml)
YAML
version: '3.8'
services:
# -------------------------------------------------------------------
# DATABASE LAYER (HA Postgres via Bitnami Primary/Standby + Pgpool)
# -------------------------------------------------------------------
pg-primary:
image: bitnami/postgresql:15
environment:
- POSTGRESQL_POSTGRES_PASSWORD=primary_master_pass
- POSTGRESQL_USERNAME=odoo
- POSTGRESQL_PASSWORD=odoo_secure_pass
- POSTGRESQL_DATABASE=odoo_db
- POSTGRESQL_REPLICATION_MODE=primary
- POSTGRESQL_REPLICATION_USER=repl_user
- POSTGRESQL_REPLICATION_PASSWORD=repl_password
volumes:
- pg_primary_data:/bitnami/postgresql
pg-standby:
image: bitnami/postgresql:15
depends_on:
- pg-primary
environment:
- POSTGRESQL_POSTGRES_PASSWORD=primary_master_pass
- POSTGRESQL_MASTER_HOST=pg-primary
- POSTGRESQL_MASTER_PORT_NUMBER=5432
- POSTGRESQL_REPLICATION_MODE=standby
- POSTGRESQL_REPLICATION_USER=repl_user
- POSTGRESQL_REPLICATION_PASSWORD=repl_password
volumes:
- pg_standby_data:/bitnami/postgresql
pgpool:
image: bitnami/pgpool:4
ports:
- "5432:5432"
depends_on:
- pg-primary
- pg-standby
environment:
- PGPOOL_BACKEND_NODES=0:pg-primary:5432,1:pg-standby:5432
- PGPOOL_SR_CHECK_USER=odoo
- PGPOOL_SR_CHECK_PASSWORD=odoo_secure_pass
- PGPOOL_SR_CHECK_DATABASE=odoo_db
- PGPOOL_ENABLE_LDAP=no
- PGPOOL_POSTGRES_USERNAME=postgres
- PGPOOL_POSTGRES_PASSWORD=primary_master_pass
- PGPOOL_ADMIN_USERNAME=admin
- PGPOOL_ADMIN_PASSWORD=admin_pass
# -------------------------------------------------------------------
# APPLICATION LAYER (Odoo Cluster)
# -------------------------------------------------------------------
odoo_app_1:
image: odoo:16.0
depends_on:
- pgpool
environment:
- HOST=pgpool
- PORT=5432
- USER=odoo
- PASSWORD=odoo_secure_pass
volumes:
- odoo_shared_data:/var/lib/odoo
- ./odoo_addons:/mnt/extra-addons
odoo_app_2:
image: odoo:16.0
depends_on:
- pgpool
environment:
- HOST=pgpool
- PORT=5432
- USER=odoo
- PASSWORD=odoo_secure_pass
volumes:
- odoo_shared_data:/var/lib/odoo # Berbagi filestore agar session & dokumen sinkron
- ./odoo_addons:/mnt/extra-addons
# -------------------------------------------------------------------
# LOAD BALANCER LAYER (Nginx)
# -------------------------------------------------------------------
nginx_lb:
image: nginx:alpine
ports:
- "80:80"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf:ro
depends_on:
- odoo_app_1
- odoo_app_2
volumes:
pg_primary_data:
pg_standby_data:
odoo_shared_data: # Diperlukan agar filestore Odoo 1 dan Odoo 2 sama
Catatan Penting untuk Skala Produksi Nyata (Multi-Node):
Meskipun arsitektur di atas memberikan simulasi HA yang sangat baik di dalam satu Docker Compose, untuk lingkungan produksi yang sesungguhnya (multi-server), Anda perlu memperhatikan beberapa poin ini:
- Shared Filestore (odoo_shared_data): Pada compose di atas, kita menggunakan Docker Volume lokal yang dibagikan antar kontainer karena mereka berada di satu mesin yang sama. Jika Anda memindahkan kontainer ke server yang berbeda (misal menggunakan Swarm atau Kubernetes), Anda harus mengganti volume ini dengan Network File System (NFS) atau cloud storage seperti AWS S3 (menggunakan modul tambahan Odoo).
- Session Loss: Secara default, Odoo menyimpan sesi pengguna di filestore. Menggunakan shared volume di atas sudah menyelesaikan masalah ini. Namun, untuk performa HA yang lebih instan, Anda disarankan menambahkan Redis sebagai session store manager.
- Database Failover: Pgpool-II mengelola load balancing query (Baca ke Standby, Tulis ke Primary). Jika pg-primary mati, Pgpool perlu dikonfigurasi lebih lanjut dengan failover script untuk mengangkat pg-standby menjadi primary yang baru.