Deploy manual lewat protokol SSH tengah malam picu downtime tak terduga. Margin error tinggi. Biaya managed cloud Kubernetes melambung tanpa utilisasi komputasi penuh. Tim rekayasa terjebak rilis rapuh dan tagihan infrastruktur bengkak.
Solusi tepat: pipeline GitHub Actions otomatis target server bare-metal via self-hosted runner. Gandeng arsitektur container Docker dan reverse proxy Nginx blue-green. Hasilnya nol downtime, pangkas biaya cloud 70%, rilis stabil hitungan detik.
Pelajari cetak biru teknis, konfigurasi pipeline, dan automasi rilis tingkat produksi berikut.
Daftar Isi
- Kelemahan Deploy Manual dan Solusi Bare-Metal
- Komparasi Biaya dan Performa: Bare-Metal vs Managed Cloud
- Persiapan Server dan Instalasi Self-Hosted Runner
- Strategi Zero-Downtime: Docker Compose Blue-Green
- Penyusunan Workflow Pipeline GitHub Actions
- Protokol Rollback Otomatis dan Observabilitas Sistem
- Checklist Implementasi Deployment Bare-Metal
- Tanya Jawab Seputar CI/CD Bare-Metal (FAQ)
- Referensi & Tautan Berguna
Kelemahan Deploy Manual dan Solusi Bare-Metal
Eksekusi git pull manual di server produksi timbulkan risiko fatal inkonsistensi environment. Human error picu konfigurasi environment rusak. Downtime aplikasi ganggu retensi pengguna.
Managed container service cloud publik kuras anggaran lewat biaya resource idle. Server bare-metal tawarkan performa I/O raw CPU dan memori penuh tanpa markup biaya virtualisasi.
Automasi via CI/CD hilangkan celah kelalaian operator. Setiap commit masuk pipeline teruji, terisolasi dalam container image deterministik, lalu rilis instan tanpa intervensi manual rentan error.
Komparasi Biaya dan Performa: Bare-Metal vs Managed Cloud
Pilihan arsitektur wajib hitung rasio cost-to-performance riil jangka panjang. Managed cloud tawarkan kemudahan operasional awal, tetapi biaya melonjak tajam saat throughput data dan kebutuhan memori naik.
Bare-metal hadirkan resource komputasi dedicated tanpa noise neighbor. Ketiadaan lapisan hypervisor ekstra pastikan utilisasi core CPU dan transfer disk NVMe sentuh kapasitas hardware maksimal.
| Metrik Evaluasi | Server Bare-Metal Dedicated | Managed Cloud (AWS ECS/EKS) |
|---|---|---|
| Biaya Operasional Bulanan | Tetap dan Terprediksi (Flat Low Cost) | Variabel Tinggi (Beban CPU, RAM, Network Egress) |
| Performa CPU dan Memori I/O | 100% Dedicated Hardware murni | Virtualisasi Bersama (Shared Hypervisor) |
| Kontrol Pipeline Runner | Self-Hosted Runner di Private Network | Cloud Hosted Runner (Limit Menit & Jaringan Publik) |
| Tingkat Kompleksitas Setup | Menengah (Butuh Fondasi OS & Docker) | Tinggi (Konfigurasi IAM, VPC, K8s Overlay) |
Panduan ini komponen inti ekosistem Panduan Lengkap DevOps & Deployment Modern: Mengelola Server, Container, SSL, dan CI/CD dari Nol terpadu untuk efisiensi infrastruktur modern.
Persiapan Server dan Instalasi Self-Hosted Runner
Server bare-metal butuh Docker Engine mutakhir dan user isolasi non-root. Runner GitHub Actions self-hosted hindari kebutuhan buka port SSH server ke internet global. Komunikasi runner tarik job via HTTPS outbound port 443.
Masuk server bare-metal via SSH, jalankan setup user runner dan instal Docker runtime:
# Buat user runner dedicated dan berikan izin docker
sudo useradd -m -s /bin/bash runner
sudo usermod -aG docker runner
sudo su - runner
# Unduh paket runner resmi GitHub Actions
mkdir actions-runner && cd actions-runner
curl -o actions-runner-linux-x64-2.314.1.tar.gz -L https://github.com/actions/runner/releases/download/v2.314.1/actions-runner-linux-x64-2.314.1.tar.gz
tar xzf ./actions-runner-linux-x64-2.314.1.tar.gz
# Registrasi runner via token dari Repository Settings > Actions > Runners
./config.sh --url https://github.com/ORGANISASI/REPO --token TOKEN_DARI_GITHUB
# Pasang dan aktifkan systemd service background
sudo ./svc.sh install
sudo ./svc.sh start
Service runner systemd pastikan agen deploy otomatis aktif paska server reboot. Runner siap terima payload build langsung dari antrean repositori GitHub aman.
Strategi Zero-Downtime: Docker Compose Blue-Green
Zero-downtime mustahil diraih jika container lama dimatikan sebelum container baru siap layani trafik. Pola blue-green deploy selesaikan kendala ini lewat skema dua container identik aktif bergantian.
Satu container aktif terima request produksi (Blue). Container baru deploy di port terpisah (Green). Script health check verifikasi container Green siap, lalu Nginx reload config secara halus tanpa drop koneksi aktif.
Simpan konfigurasi docker-compose.yml berikut di direktori /opt/app/docker-compose.yml:
version: '3.8'
services:
app_blue:
image: ghcr.io/organisasi/web-app:${IMAGE_TAG}
container_name: app_blue
restart: always
ports:
- "127.0.0.1:8081:8080"
environment:
- ENV=production
app_green:
image: ghcr.io/organisasi/web-app:${IMAGE_TAG}
container_name: app_green
restart: always
ports:
- "127.0.0.1:8082:8080"
environment:
- ENV=production
Trafik masuk diatur Nginx upstream. Reload konfigurasi Nginx cuma butuh waktu milidetik via perintah nginx -s reload tanpa matikan socket HTTP.
Penyusunan Workflow Pipeline GitHub Actions
File workflow otomatisasi bangun image container, push ke registry aman, lalu trigger container reload langsung pada server bare-metal via self-hosted runner.
Buat file .github/workflows/deploy.yml pada repositori proyek:
name: CI/CD Bare-Metal Pipeline
on:
push:
branches: [ "main" ]
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build-and-push:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
outputs:
image_tag: ${{ steps.meta.outputs.version }}
steps:
- name: Checkout Code
uses: actions/checkout@v4
- name: Log in to Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract Metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: type=sha,format=short
- name: Build and Push Image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
deploy:
needs: build-and-push
runs-on: self-hosted
steps:
- name: Log in to GitHub Container Registry
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
- name: Execute Blue-Green Deployment
env:
IMAGE_TAG: ${{ needs.build-and-push.outputs.image_tag }}
run: |
cd /opt/app
export IMAGE_TAG=$IMAGE_TAG
docker compose pull
ACTIVE_APP=$(curl -s http://127.0.0.1:80/health-check-target || echo "blue")
if [ "$ACTIVE_APP" = "blue" ]; then
TARGET_SERVICE="app_green"
TARGET_PORT="8082"
OLD_SERVICE="app_blue"
else
TARGET_SERVICE="app_blue"
TARGET_PORT="8081"
OLD_SERVICE="app_green"
fi
docker compose up -d $TARGET_SERVICE
# Verifikasi health check container baru
sleep 5
curl --fail http://127.0.0.1:$TARGET_PORT/health || exit 1
# Switch upstream Nginx dan reload
sed -i "s/127.0.0.1:[0-9]*/127.0.0.1:$TARGET_PORT/" /etc/nginx/conf.d/upstream.conf
sudo nginx -s reload
# Nonaktifkan instance lama
docker compose stop $OLD_SERVICE
Pipeline di atas pastikan container lama tetap layani user sampai health check container baru lolos. Gagal health check gagalkan pipeline instan tanpa ganggu traffic aktif.
Protokol Rollback Otomatis dan Observabilitas Sistem
Deploy andal wajib punya mekanisme rollback otomatis jika runtime error lolos tahap testing awal. Skrip bash pipeline di atas membatalkan reload Nginx jika health check container target bernilai non-200.
Logging terpusat jadi fondasi observabilitas. Manfaatkan Docker logging driver bawaan (systemd journald atau local driver) batasi ukuran file log container cegah kapasitas storage bare-metal penuh.
Aktifkan pruning resource Docker berkala via cron job mingguan pada server runner. Bersihkan dangling image dan container layer kadaluarsa:
# Jalankan maintenance storage tiap Minggu jam 02:00 pagi
0 2 * * 0 /usr/bin/docker system prune -af --volumes
Checklist Implementasi Deployment Bare-Metal
- Instalasi Docker Engine, Compose plugin, dan Nginx reverse proxy di host bare-metal.
- Pembuatan user sistem
runnernon-root dengan hak akses socket Docker. - Registrasi GitHub Actions self-hosted runner via systemd service background.
- Penyusunan file
docker-compose.ymlskema Blue-Green dual binding port. - Pemisahan file upstream Nginx untuk kemudahan automasi via
sed. - Implementasi workflow
deploy.ymlterintegrasi GHCR dan health check testing. - Konfigurasi cron pruning image Docker kadaluarsa penghemat disk space.
Tanya Jawab Seputar CI/CD Bare-Metal (FAQ)
Apakah aman menjalankan self-hosted runner GitHub Actions di server produksi?
Sangat aman untuk repositori privat. Pastikan repositori bukan publik cegah eksekusi pull request tak dikenal. Jalankan runner via user sistem non-root terisolasi dan hindari inject credential root langsung di runner workspace.
Bagaimana cara Nginx me-reload konfigurasi tanpa memutus koneksi client?
Perintah nginx -s reload spawn proses worker baru baca konfigurasi anyar tanpa bunuh proses lama. Worker lama tuntaskan request koneksi aktif sebelum terminasi graceful.
Mengapa memilih GitHub Packages (GHCR) dibanding Docker Hub publik?
GHCR beri integrasi token native GitHub Actions via GITHUB_TOKEN tanpa secret eksternal. Batas rate limit transfer GHCR jauh lebih tinggi dibanding free tier Docker Hub.
Referensi & Tautan Berguna
- Dokumentasi GitHub Actions Self-Hosted Runners: https://docs.github.com/en/actions/hosting-your-own-runners
- Dokumentasi Resmi Docker Engine: https://docs.docker.com/engine/install/
- Panduan Zero Downtime Reload Nginx: https://nginx.org/en/docs/control.html