Coba inget-inget, udah berapa kali kamu ngetik urutan command yang sama abis push kode ke Gitea? Build image, jalanin test, terus restart container manual lewat SSH. Ngebosenin, dan gampang kelewatan satu langkah pas buru-buru. Di titik inilah CI/CD jadi penting – bukan buat perusahaan besar doang, tapi buat siapa aja yang capek ngulang-ngulang proses deploy manual. Woodpecker CI ngasih solusi yang pas buat self-hoster: ringan, container-native, dan terintegrasi langsung sama Gitea. Tinggal push, sisanya jalan sendiri. Di artikel ini saya bakal bahas cara install Woodpecker CI di VPS pakai Docker dari nol, lengkap dengan penjelasan detail di setiap langkahnya.
Apa Itu Woodpecker CI
Buat yang belum familiar, CI/CD itu singkatan dari Continuous Integration / Continuous Deployment. Intinya: setiap kali kamu push kode, sistem otomatis nge-build, nge-test, dan nge-deploy tanpa kamu harus jalanin command manual satu-satu.
Woodpecker CI adalah engine CI/CD yang ringan dan container-native. Awalnya ini fork dari Drone CI yang muncul setelah Drone berubah jadi produk komersial. Setiap step pipeline dijalanin di container Docker terpisah, jadi environment-nya bersih dan gampang direproduksi. Konfigurasinya cukup satu file YAML per repo.
Woodpecker terdiri dari dua komponen utama:
- Woodpecker Server: Otak dari sistem. Dia yang nangani web UI, API, nyimpen data pipeline, nerima webhook dari Gitea, dan nge-assign job ke agent. Data pipeline disimpen di SQLite (default), jadi gak perlu database tambahan buat skala kecil-menengah
- Woodpecker Agent: Eksekutor yang beneran ngerjain step-step pipeline di dalam container Docker. Agent nerima instruksi dari server lewat gRPC (port 9000), lalu jalanin setiap step di container terpisah. Kamu bisa jalanin beberapa agent sekaligus kalau butuh parallel builds
Cara kerjanya simpel: kamu push kode ke Gitea, Gitea ngirim webhook ke Woodpecker Server, server nge-assign job ke agent, agent jalanin step-step pipeline di container, hasilnya dilaporin balik ke dashboard.

Bedanya Woodpecker Sama GitHub Actions, Jenkins, dan Drone
Karena CI/CD tools banyak pilihannya, ini perbandingan singkat biar jelas posisi masing-masing:
GitHub Actions cocok kalau repo kamu emang di GitHub. Tapi begitu kamu pindah ke Gitea yang self-hosted, Actions otomatis gak relevan lagi. Gitea punya Gitea Actions sendiri, tapi masih relatif baru dan ekosistemnya belum selengkap Woodpecker.
Jenkins itu veteran di dunia CI/CD, fiturnya lengkap banget. Tapi resource-nya berat (butuh Java runtime), maintenance plugin-nya makan waktu, dan setup-nya jauh lebih kompleks. Buat VPS kecil, Jenkins kebesaran.
Drone CI itu “kakak” Woodpecker – codebase aslinya sama. Tapi Drone udah berubah jadi produk komersial dengan lisensi yang lebih ketat. Woodpecker tetep full open source dan community-driven.
Kapan pilih Woodpecker: kalau kamu pakai Gitea (atau Forgejo) self-hosted, butuh CI/CD yang ringan, dan gak mau ribet setup Jenkins atau bayar lisensi Drone.
Prasyarat Sebelum Install Woodpecker CI di VPS
Woodpecker emang ringan, tapi ada beberapa hal yang wajib disiapin dulu biar instalasinya lancar.
1. VPS dengan Spesifikasi Minimum
Woodpecker sendiri gak berat, tapi agent-nya bakal nge-build image Docker yang bisa makan resource lumayan. Spek minimum:
- RAM: Minimal 2GB. Server Woodpecker cuma makan sekitar 100-200MB, tapi agent butuh lebih buat build container
- CPU: Minimal 2 vCPU. Build Docker image itu CPU-intensive
- Storage: Minimal 20GB kosong. Docker image dan build cache bisa makan space lumayan
- OS: Ubuntu 22.04 atau 24.04 LTS
Cara cek spek VPS kamu:
free -h # cek RAM tersedia
df -h # cek disk space
nproc # cek jumlah CPU
lsb_release -a # cek versi OS
2. Docker dan Docker Compose Sudah Terinstall
Woodpecker jalan sepenuhnya di atas container Docker. Kalau belum terinstall, ikutin dulu panduan Cara Install Docker di Ubuntu VPS. Verifikasi:
docker --version
docker compose version
3. Instance Gitea yang Sudah Jalan
Woodpecker butuh “forge” (platform Git) buat nerima webhook dan autentikasi user. Di artikel ini kita pakai Gitea yang self-hosted. Pastiin Gitea kamu udah jalan dan bisa diakses lewat HTTPS. Bisa di server yang sama atau server lain yang satu jaringan.
Verifikasi Gitea bisa diakses:
curl -I https://gitea.domainmu.com
4. Domain atau Subdomain
Woodpecker butuh domain/subdomain yang udah diarahin ke VPS karena OAuth callback dan webhook cuma jalan mulus lewat HTTPS. Siapin subdomain kayak woodpecker.domainmu.com dan pastiin A record-nya udah ngarah ke IP VPS.
Verifikasi DNS:
dig woodpecker.domainmu.com +short
5. Port yang Dibutuhin
Woodpecker pakai dua port utama:
- Port 8000 – Web UI dan webhook endpoint. Ini yang diakses user lewat browser dan Gitea buat ngirim webhook
- Port 9000 – gRPC komunikasi internal antara server dan agent. Jangan buka port ini ke publik
Cek apakah port masih kosong:
sudo lsof -i :8000
sudo lsof -i :9000
Cara Install Woodpecker CI di VPS Step by Step
Sekarang masuk ke bagian inti. Ikutin langkah-langkah di bawah ini satu per satu.

Step 1 – Buat Folder Project
Login ke VPS lewat SSH, lalu bikin folder khusus buat Woodpecker:
mkdir -p /opt/woodpecker
cd /opt/woodpecker
Step 2 – Generate Agent Secret
Server dan agent perlu shared secret yang sama persis biar bisa saling percaya. Generate pakai OpenSSL:
openssl rand -hex 32
Catat hasilnya. Ini bakal dipakai di file environment nanti.
Step 3 – Setup OAuth di Gitea
Sebelum bikin docker-compose, kita perlu bikin OAuth2 application di Gitea dulu biar Woodpecker bisa autentikasi user lewat Gitea. Ini bagian yang paling sering bikin bingung, jadi ikutin dengan teliti:
Di Gitea:
- Login ke Gitea sebagai admin
- Masuk ke Site Administration > Applications
- Klik Create a new OAuth2 Application
- Isi Application Name:
Woodpecker CI - Isi Redirect URI:
https://woodpecker.domainmu.com/authorize
Penting banget soal Redirect URI:
- Harus pakai
https://, bukanhttp:// - Domain harus sama persis dengan yang bakal kamu set di
WOODPECKER_HOST - Path harus
/authorize(bukan/authatau/callback) - Jangan ada trailing slash di akhir
- OAuth itu strict banget soal exact match URL – beda satu karakter aja bikin gagal
Setelah application dibuat, Gitea bakal ngasih Client ID dan Client Secret. Catat kedua nilai ini.
Step 4 – Buat File Environment (.env)
Bikin file .env buat nyimpen semua credential:
nano .env
Paste isi berikut dan ganti nilainya:
WOODPECKER_AGENT_SECRET=hasil-openssl-rand-hex-32-tadi
WOODPECKER_GITEA_CLIENT=client-id-dari-gitea
WOODPECKER_GITEA_SECRET=client-secret-dari-gitea
Penjelasan setiap variabel:
- WOODPECKER_AGENT_SECRET: Shared secret buat komunikasi server-agent. Harus sama persis di kedua service. Beda satu karakter aja bikin handshake gagal diam-diam
- WOODPECKER_GITEA_CLIENT: Client ID dari OAuth2 application yang baru dibikin di Gitea
- WOODPECKER_GITEA_SECRET: Client Secret dari OAuth2 application yang sama
Simpan file dengan Ctrl+O lalu Enter, keluar dengan Ctrl+X.
Step 5 – Buat File docker-compose.yml
Masih di folder /opt/woodpecker, bikin file Docker Compose:
nano docker-compose.yml
Paste isi berikut:
services:
woodpecker-server:
image: woodpeckerci/woodpecker-server:v3
container_name: woodpecker-server
restart: always
ports:
- "8000:8000"
volumes:
- woodpecker-server-data:/var/lib/woodpecker/
environment:
- WOODPECKER_OPEN=false
- WOODPECKER_HOST=https://woodpecker.domainmu.com
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
- WOODPECKER_GITEA=true
- WOODPECKER_GITEA_URL=https://gitea.domainmu.com
- WOODPECKER_GITEA_CLIENT=${WOODPECKER_GITEA_CLIENT}
- WOODPECKER_GITEA_SECRET=${WOODPECKER_GITEA_SECRET}
woodpecker-agent:
image: woodpeckerci/woodpecker-agent:v3
container_name: woodpecker-agent
command: agent
restart: always
depends_on:
- woodpecker-server
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- woodpecker-agent-config:/etc/woodpecker
environment:
- WOODPECKER_SERVER=woodpecker-server:9000
- WOODPECKER_AGENT_SECRET=${WOODPECKER_AGENT_SECRET}
volumes:
woodpecker-server-data:
woodpecker-agent-config:
Penjelasan setiap environment variable di server:
- WOODPECKER_OPEN=false: Matiin registrasi terbuka. Cuma user yang udah ada di Gitea yang bisa login. Kalau di-set
true, siapa aja yang punya akun Gitea bisa akses Woodpecker - WOODPECKER_HOST: URL publik Woodpecker kamu. Harus sama persis dengan Redirect URI yang di-set di Gitea OAuth. Pakai HTTPS
- WOODPECKER_AGENT_SECRET: Shared secret buat komunikasi server-agent. Diambil dari file
.env - WOODPECKER_GITEA=true: Aktifin Gitea sebagai forge (platform Git)
- WOODPECKER_GITEA_URL: URL Gitea kamu. Harus bisa diakses dari container Woodpecker
- WOODPECKER_GITEA_CLIENT dan SECRET: Credential OAuth dari Gitea. Diambil dari file
.env
Penjelasan komponen agent:
- WOODPECKER_SERVER=woodpecker-server:9000: Alamat server yang dikonek agent lewat gRPC. Pakai nama service Docker Compose, bukan IP
- /var/run/docker.sock: Mount Docker socket dari host ke agent. Ini yang bikin agent bisa jalanin container buat setiap step pipeline. Perhatian: mount ini praktis ngasih akses setara root ke host – nanti dibahas di bagian keamanan
- depends_on: Agent baru start setelah server udah jalan
Ganti woodpecker.domainmu.com dan gitea.domainmu.com dengan domain kamu yang sebenarnya.
Step 6 – Jalankan Container
Jalanin Woodpecker:
docker compose up -d
Cek status container:
docker compose ps
Kamu harusnya liat dua container running:
- woodpecker-server – status Up
- woodpecker-agent – status Up
Kalau salah satu terus-terusan restart, cek log-nya:
docker compose logs woodpecker-server --tail 50
docker compose logs woodpecker-agent --tail 50
Penyebab paling umum restart: typo di environment variable atau WOODPECKER_AGENT_SECRET gak sama antara server dan agent.
Step 7 – Login ke Dashboard Woodpecker
Kalau kamu udah setup reverse proxy (Traefik atau Nginx) di depan port 8000, buka dashboard lewat domain:
https://woodpecker.domainmu.com
Kalau belum setup reverse proxy, bisa akses langsung lewat IP dan port:
http://ip-vps-kamu:8000
Kamu bakal diarahin ke halaman login Gitea (OAuth). Login pakai akun Gitea kamu, lalu authorize Woodpecker buat akses. Setelah authorize, kamu bakal di-redirect balik ke dashboard Woodpecker dan liat list repository dari Gitea kamu.
Kalau redirect gagal atau error: Cek ulang Redirect URI di Gitea OAuth application. Harus sama persis dengan WOODPECKER_HOST + /authorize.
Bikin Pipeline Pertama
Step 8 – Buat File .woodpecker.yml di Repo
Pipeline Woodpecker dikonfigurasi lewat file .woodpecker.yml yang diletakkan di root repository. File ini otomatis kedetek tiap ada push atau pull request.
Di Gitea, buka salah satu repo kamu (pilih yang kecil dulu buat testing). Bikin file baru .woodpecker.yml di root repo:
steps:
- name: test
image: alpine
commands:
- echo "Hello from Woodpecker CI!"
- echo "Build triggered at $(date)"
- echo "Pipeline is working!"
Ini pipeline paling sederhana – cuma nge-print pesan buat verifikasi Woodpecker beneran jalan. Penjelasan:
- steps: List langkah-langkah yang dijalanin pipeline
- name: test: Nama step (bebas)
- image: alpine: Docker image yang dipakai buat jalanin step ini. Alpine itu image Linux yang super ringan
- commands: Command yang dijalanin di dalam container
Contoh pipeline yang lebih realistis buat proyek yang di-deploy lewat Docker:
steps:
- name: build
image: docker:cli
commands:
- docker build -t myapp:latest .
- name: test
image: myapp:latest
commands:
- npm test
- name: deploy
image: docker:cli
commands:
- docker push registry.domainmu.com/myapp:latest
when:
branch: main
Step deploy di atas cuma push image baru ke registry, bukan langsung SSH terus restart container. Ini sengaja. Kalau server produksi kamu udah pakai Watchtower, dia bakal narik image baru itu dan restart container-nya otomatis. Pemisahan tanggung jawab kayak gini bikin pipeline-nya lebih simpel dan gak perlu nyimpen credential SSH produksi di dalam Woodpecker.
Step 9 – Aktifkan Repo di Dashboard Woodpecker
Sebelum pipeline bisa jalan, kamu harus aktifin repo-nya dulu di dashboard Woodpecker:
- Buka dashboard Woodpecker
- Klik Add repository atau cari repo kamu di list
- Klik repo yang mau diaktifin
- Klik Enable
Begitu repo diaktifin, Woodpecker otomatis bikin webhook di Gitea. Setiap push ke repo itu bakal nge-trigger pipeline.
Step 10 – Test Push dan Verifikasi Pipeline
Sekarang test apakah semuanya berfungsi. Push perubahan ke repo yang udah diaktifin:
# di local machine kamu
git add .woodpecker.yml
git commit -m "test: add woodpecker pipeline"
git push origin main
Setelah push, buka dashboard Woodpecker. Kamu harusnya liat pipeline baru yang running atau udah selesai. Klik pipeline-nya buat liat detail setiap step:
- Status hijau (success): Pipeline berhasil. Semua step jalan tanpa error
- Status merah (failure): Ada step yang gagal. Klik step-nya buat liat log error
- Status kuning (pending): Pipeline nunggu agent. Cek apakah agent container running
Kalau pipeline pertama kamu berhasil (status hijau) dengan output “Hello from Woodpecker CI!”, selamat – CI/CD kamu udah berfungsi. Setiap push ke repo ini bakal otomatis nge-trigger pipeline.
Yang Perlu Diperhatiin Setelah Install Woodpecker CI
Ada beberapa masalah yang sering muncul dan tips penting yang perlu kamu tau.
Pipeline Stuck di Pending dan Gak Pernah Mulai
Ini biasanya karena agent belum konek ke server. Cek log agent-nya:
docker compose logs woodpecker-agent --tail 30
Penyebab paling umum:
- WOODPECKER_AGENT_SECRET gak sama: Nilai secret di server dan agent harus identik. Beda satu karakter aja bikin handshake gagal diam-diam tanpa error yang jelas
- Agent gak bisa reach server: Pastiin
WOODPECKER_SERVER=woodpecker-server:9000bener. Kalau agent jalan di server terpisah, ganti dengan IP/domain server Woodpecker - Port 9000 di-block: Kalau agent di server terpisah, pastiin port 9000 terbuka di firewall server Woodpecker
Webhook dari Gitea Gak Nge-trigger Pipeline
Kalau push ke repo gak nge-trigger pipeline sama sekali, masalahnya ada di webhook. Cek beberapa hal:
- Redirect URI salah: Cek ulang di Gitea OAuth application. Harus sama persis:
https://woodpecker.domainmu.com/authorize - Webhook gak terkirim: Di Gitea, masuk ke repo > Settings > Webhooks. Cek apakah webhook Woodpecker ada dan statusnya success (centang hijau). Kalau ada X merah, klik buat liat error detail
- ALLOWED_HOST_LIST di Gitea: Kalau Gitea dan Woodpecker jalan di jaringan internal (Docker network), Gitea mungkin nge-block webhook ke alamat internal. Edit
app.iniGitea dan tambahin alamat Woodpecker keALLOWED_HOST_LISTdi section[webhook] - Repo belum diaktifin: Pastiin kamu udah enable repo di dashboard Woodpecker (Step 9)
Error Permission Docker Socket
Kalau build gagal dengan error permission soal Docker socket, biasanya user di dalam image agent belum punya akses cukup ke docker.sock yang di-mount. Solusi:
# cek permission docker.sock di host
ls -la /var/run/docker.sock
# kalau perlu, tambahin permission
sudo chmod 666 /var/run/docker.sock
Warning: chmod 666 itu solusi cepat tapi kurang aman buat production. Solusi yang lebih proper adalah jalanin agent dengan user yang masuk ke group docker.
Keamanan – Docker Socket dan Endpoint
Ada dua hal keamanan yang penting banget buat Woodpecker:
1. Docker Socket Mount: Agent mount /var/run/docker.sock yang praktis ngasih akses setara root ke host. Dampaknya bisa ke seluruh server, bukan cuma ke container Woodpecker. Kalau memungkinkan, jalanin agent di VPS terpisah yang khusus buat build. Jangan jalanin agent di server produksi yang nyimpen data sensitif.
2. Web Endpoint: Port 8000 (web UI dan webhook) memang harus bisa diakses dari luar biar Gitea bisa ngirim webhook. Tapi jangan expose port 8000 mentah-mentah ke publik. Taruh Traefik atau reverse proxy di depannya biar traffic lewat HTTPS. Port 9000 (gRPC server-agent) jangan dibuka ke publik – cukup jalan di jaringan internal Docker Compose.
Woodpecker vs Cronicle – Beda Fungsi
Kalau server kamu udah punya Cronicle buat jadwalin job rutin, penting misahin dua jenis otomasi ini:
- Cronicle: Buat kerjaan yang jadwalnya pasti (time-based). Misalnya backup tiap jam 2 pagi, cleanup log tiap minggu, atau health check tiap 5 menit
- Woodpecker: Buat kerjaan yang react ke event (event-based). Yaitu push kode, yang timingnya gak nentu. Build langsung jalan begitu ada push masuk
Yang sering ketauan di lapangan: ada yang pakai Cronicle buat jadwalin git pull terus build tiap sejam sekali. Padahal itu nutupin celah yang harusnya diisi CI beneran. Masalahnya, delay antara push dan deploy bisa sampai hampir sejam. Kalau pakai Woodpecker, build langsung jalan begitu push masuk. Jadi keduanya saling melengkapi, bukan saling gantiin.
Kesimpulan
Woodpecker CI ngasih kemampuan CI/CD yang proper buat self-hoster tanpa kompleksitas Jenkins atau ketergantungan ke platform cloud. Ringan, container-native, dan terintegrasi langsung sama Gitea. Setiap push otomatis nge-trigger build, test, dan deploy tanpa kamu harus SSH manual ke server.
Tips buat yang baru mulai: gak perlu langsung migrasiin semua repo sekaligus. Coba dulu satu repo kecil biar kamu ngerti alur push sampai deploy-nya, baru pelan-pelan tambahin repo lain begitu udah yakin pipeline-nya stabil. Mulai dari pipeline sederhana (echo test), lalu gradually tambahin step build, test, dan deploy.
Kalau digabungin sama Watchtower buat auto-pull image baru, kamu punya pipeline end-to-end yang fully automated: push kode ke Gitea, Woodpecker build dan push image ke registry, Watchtower detect image baru dan restart container di production. Semua jalan otomatis tanpa satu pun SSH manual.

























