Bismillah
Ini postingan pertama di tahun 2026. Semoga bisa konsisten untuk update blog ini. hehe, aamiin.
CloudPanel adalah panel kontrol hosting open-source yang ringan dan mudah digunakan. CloudPanel mendukung PHP, Node.js, Python, dan Ruby. CloudPanel juga mendukung MySQL, PostgreSQL, dan MongoDB. CloudPanel juga mendukung Redis, Memcached, dan RabbitMQ. CloudPanel juga mendukung Docker, Kubernetes, dan OpenShift. CloudPanel juga mendukung Let's Encrypt, Cloudflare, dan Google Cloud DNS. CloudPanel juga mendukung Fail2ban, ModSecurity, dan Nginx.
Itulah yang didapat dari Penjelasan di Website CloudPanel. Sekarang gw akan bahas, apa yang gw manfaatin dari cloudpanel ini, karena sebelumnya pake aaPanel terlalu overkill menurut gw kalo cuman buat service whatsapp. Pada postingan sebelumnya gw pernah nulis tentang configurasi server dan configurasi whatsapp, silahkan dibaca karena disana secara detail gw jelaskan.
Untuk Postingan kali ini gw akan bahas tentang install cloudpanel dan configurasi cloudpanel untuk service whatsapp, dengan memanfaatkan teknologi docker. Berikut Ini langkah yang harus dilakukan. Ini spek server yang gw pake.
Untuk install cloudpanel bisa mengikuti tutorial di website resminya
Update Server Dahulu
Sesuaikan dengan OS Masing masing, kali ini gw pake Server Debian 13 yang terkenal ringan.
Install CloudPanel
Jika proses install berhasil, maka bisa dilanjut untuk install docker, kali ini gw pake Dockge sebagai interface untuk mengelola docker yang ringan.
Install Dockge
Untuk install dockge bisa mengikuti tutorial di website resminya
Dah selesai ... untuk service whatsapp, gw pake 8 service yang opensource. Berikut ini adalah service yang gw pake:
- Baileys-API ❌
- WPP-Connect ✅
- Wa-Gateway ✅
- Wuzz-API ✅
- wwebjs-api ❌
- Go-Whatsapp-Device ❌
- Evolution-API ✅
- Chattery-API ✅
Dari beberapa service diatas, gw cuman pake yang 3,4,7,8 yang berjalan di dockge-cloudpanel. Ups, ada bonus neh docker compose yang gw pake.
👇 Klik Detail
# compose.yaml
services:
wppconnect:
container_name: wpp-server
restart: unless-stopped
build:
context: .
volumes:
- ./config.ts:/usr/src/wpp-server/config.ts
- ./wppconnect_tokens:/usr/src/wpp-server/tokens
ports:
- 5002:21465
volumes:
wppconnect_tokens: {}
networks: {}# compose.yaml
services:
wa-gateway:
container_name: wa-gateway
restart: unless-stopped
image: mimamch/wa-gateway:latest
volumes:
- ./wa_credentials:/app/wa_credentials
- ./media:/app/media
ports:
- 5001:5001
environment:
- KEY=changeyoursupersecretkey# compose.yaml
services:
wuzapi-server:
build:
context: .
dockerfile: Dockerfile
ports:
- ${WUZAPI_PORT:-8080}:8080
environment:
- WUZAPI_ADMIN_TOKEN=${WUZAPI_ADMIN_TOKEN}
- WUZAPI_GLOBAL_ENCRYPTION_KEY=${WUZAPI_GLOBAL_ENCRYPTION_KEY}
- WUZAPI_GLOBAL_HMAC_KEY=${WUZAPI_GLOBAL_HMAC_KEY:-}
- WUZAPI_GLOBAL_WEBHOOK=${WUZAPI_GLOBAL_WEBHOOK:-}
- DB_USER=${DB_USER:-wuzapi}
- DB_PASSWORD=${DB_PASSWORD:-wuzapi}
- DB_NAME=${DB_NAME:-wuzapi}
- DB_HOST=db
- DB_PORT=${DB_PORT:-5432}
- TZ=${TZ:-America/Sao_Paulo}
- WEBHOOK_FORMAT=${WEBHOOK_FORMAT:-json}
- SESSION_DEVICE_NAME=${SESSION_DEVICE_NAME:-WuzAPI}
# RabbitMQ configuration Optional
- RABBITMQ_URL=amqp://wuzapi:wuzapi@rabbitmq:5672/
- RABBITMQ_QUEUE=whatsapp_events
depends_on:
db:
condition: service_healthy
rabbitmq:
condition: service_healthy
networks:
- wuzapi-network
restart: on-failure
db:
image: postgres:16
environment:
POSTGRES_USER: ${DB_USER:-wuzapi}
POSTGRES_PASSWORD: ${DB_PASSWORD:-wuzapi}
POSTGRES_DB: ${DB_NAME:-wuzapi}
# ports:
# - "${DB_PORT:-5432}:5432" # Uncomment to access the database directly from your host machine.
volumes:
- db_data:/var/lib/postgresql/data
networks:
- wuzapi-network
healthcheck:
test:
- CMD-SHELL
- pg_isready -U ${DB_USER:-wuzapi}
interval: 5s
timeout: 5s
retries: 5
restart: always
rabbitmq:
image: rabbitmq:3-management
hostname: rabbitmq
environment:
RABBITMQ_DEFAULT_USER: wuzapi
RABBITMQ_DEFAULT_PASS: wuzapi
RABBITMQ_DEFAULT_VHOST: /
ports:
- 5672:5672 # AMQP port
- 15672:15672 # Management UI port
volumes:
- rabbitmq_data:/var/lib/rabbitmq
networks:
- wuzapi-network
healthcheck:
test:
- CMD
- rabbitmq-diagnostics
- ping
interval: 10s
timeout: 5s
retries: 5
restart: always
networks:
wuzapi-network:
driver: bridge
volumes:
db_data: null
rabbitmq_data: null# compose.yaml
services:
evolution-api:
image: evoapicloud/evolution-api:latest
restart: always
# Menambahkan dependency agar API tidak jalan sebelum DB & Redis siap
depends_on:
evolution-postgres:
condition: service_healthy
evolution-redis:
condition: service_started
volumes:
- evolution-instances:/evolution/instances
# Membuka port agar bisa diakses (sesuaikan jika perlu port lain)
ports:
- 5010:8080
environment:
- SERVER_URL=${SERVER_URL}
- AUTHENTICATION_TYPE=${AUTHENTICATION_TYPE}
- AUTHENTICATION_API_KEY=${AUTHENTICATION_API_KEY}
- AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES=${AUTHENTICATION_EXPOSE_IN_FETCH_INSTANCES}
- LANGUAGE=${LANGUAGE}
- CONFIG_SESSION_PHONE_CLIENT=${CONFIG_SESSION_PHONE_CLIENT}
- CONFIG_SESSION_PHONE_NAME=${CONFIG_SESSION_PHONE_NAME}
- TELEMETRY=${TELEMETRY}
- DATABASE_ENABLED=${DATABASE_ENABLED}
- DATABASE_PROVIDER=${DATABASE_PROVIDER}
- DATABASE_CONNECTION_URI=${DATABASE_CONNECTION_URI}
- DATABASE_SAVE_DATA_INSTANCE=${DATABASE_SAVE_DATA_INSTANCE}
- DATABASE_SAVE_DATA_NEW_MESSAGE=${DATABASE_SAVE_DATA_NEW_MESSAGE}
- DATABASE_SAVE_MESSAGE_UPDATE=${DATABASE_SAVE_MESSAGE_UPDATE}
- DATABASE_SAVE_DATA_CONTACTS=${DATABASE_SAVE_DATA_CONTACTS}
- DATABASE_SAVE_DATA_CHATS=${DATABASE_SAVE_DATA_CHATS}
- DATABASE_SAVE_DATA_LABELS=${DATABASE_SAVE_DATA_LABELS}
- DATABASE_SAVE_DATA_HISTORIC=${DATABASE_SAVE_DATA_HISTORIC}
- CACHE_REDIS_ENABLED=${CACHE_REDIS_ENABLED}
- CACHE_REDIS_URI=${CACHE_REDIS_URI}
- CACHE_REDIS_PREFIX_KEY=${CACHE_REDIS_PREFIX_KEY}
- CACHE_REDIS_SAVE_INSTANCES=${CACHE_REDIS_SAVE_INSTANCES}
evolution-postgres:
image: postgres:16-alpine
restart: always
volumes:
- evolution-postgres-data:/var/lib/postgresql/data
environment:
- POSTGRES_DB=${POSTGRES_DATABASE}
- POSTGRES_USER=${POSTGRES_USERNAME}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
# Healthcheck memastikan database benar-benar siap menerima koneksi
healthcheck:
test:
- CMD-SHELL
- pg_isready -U ${POSTGRES_USERNAME} -d ${POSTGRES_DATABASE}
interval: 10s
timeout: 5s
retries: 5
evolution-redis:
image: redis:alpine
restart: always
command: redis-server --appendonly yes # Menambah persistensi data
volumes:
- evolution-redis-data:/data
volumes:
evolution-instances: null
evolution-postgres-data: null
evolution-redis-data: null
networks: {}# compose.yaml
services:
chatery:
build:
context: .
dockerfile: Dockerfile
container_name: chatery-whatsapp-api
restart: unless-stopped
ports:
- ${PORT:-3000}:3000
environment:
- NODE_ENV=production
- PORT=3000
- CORS_ORIGIN=${CORS_ORIGIN:-*}
- DASHBOARD_USERNAME=${DASHBOARD_USERNAME:-admin}
- DASHBOARD_PASSWORD=${DASHBOARD_PASSWORD:-admin123}
- API_KEY=${API_KEY:-}
volumes:
- chatery_sessions:/app/sessions
- chatery_media:/app/public/media
- chatery_store:/app/store
healthcheck:
# Logika baru: Membuat file penanda waktu saat container jalan pertama kali
# Jika umur file > 172800 detik (48 jam), status jadi unhealthy -> autoheal restart
test:
- CMD-SHELL
- >
if [ ! -f /tmp/container_start ]; then touch /tmp/container_start; fi;
uptime_seconds=$$(($(date +%s) - $(date -r /tmp/container_start
+%s))); if [ "$$uptime_seconds" -gt 172800 ]; then
echo "Restart period reached (48h)"; exit 1;
fi; wget --no-verbose --tries=1 --spider http://localhost:3000/ || exit 1
interval: 60s # Cek setiap 1 menit
timeout: 10s # Batas waktu respon wget
retries: 3 # Gagal 3x baru dianggap Unhealthy
start_period: 60s # Memberi waktu 1 menit untuk loading WhatsApp sessions
labels:
- autoheal=true
logging:
driver: json-file
options:
max-size: 10m
max-file: "3"
networks:
- chatery-network
autoheal:
image: willfarrell/autoheal:latest
container_name: autoheal
restart: always
environment:
- AUTOHEAL_CONTAINER_LABEL=autoheal
- AUTOHEAL_INTERVAL=60
- DOCKER_SOCK=/var/run/docker.sock
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- chatery-network
volumes:
chatery_sessions:
driver: local
chatery_media:
driver: local
chatery_store:
driver: local
networks:
chatery-network:
driver: bridgeJangan lupa buat .env file juga ya. sesuaikan dengan object yang dibutuhkan.
Done ya, Have a nice day!
Sumber: