# Cara Rollback Deploy Docker di VPS untuk Pemula

> Panduan pemula cara rollback deploy Docker di VPS: tag image unik, simpan versi lama, deploy dengan --wait, kembalikan tag, verifikasi, dan batas rollback.

URL: https://www.matthewswong.com/id/blog/cara-rollback-deploy-docker-di-vps/

- Author: Matthews Wong (https://www.matthewswong.com/id/about/)
- Published: 2026-10-17
- Updated: 2026-10-17
- Category: DevOps

> **Key takeaway:** Cara rollback deploy Docker di VPS: beri setiap image tag unik seperti commit SHA, catat tag yang sedang jalan, lalu saat rilis rusak ganti IMAGE di .env ke tag sebelumnya dan jalankan docker compose up -d --wait. Verifikasi dengan docker compose ps dan curl. Rollback hanya mengembalikan kode, bukan data atau migrasi database.

Kamu baru deploy versi baru, lalu halaman utama menampilkan error. Pengunjung sudah melihatnya, dan di terminal kamu mengetik apa pun yang terlintas: git reset, build ulang, docker compose down. Sebagian besar waktu habis bukan karena rollback itu sulit, melainkan karena tidak ada yang tahu persis versi mana yang dulu berjalan baik, atau versi itu sudah tertimpa tag latest.

Panduan ini adalah langkah rollback saja, bukan panduan mendeteksi masalah: kamu akan menyiapkan sistemnya sebelum rilis (tag unik, catatan versi), lalu memakainya saat rilis rusak. Contoh memakai pola yang sama dengan setup di balik situs ini, ditulis ulang dengan placeholder, dan mengasumsikan kamu sudah punya file Compose production seperti di 

panduan deploy Docker Compose di production

. Setiap flag dicek ke dokumentasi resmi yang tercantum di akhir.

## Ingin paham konsepnya dulu?

Tulisan ini panduan praktik rollback. Lesson gratis kami menjelaskan gambaran besarnya, dari health check sampai backup, dengan diagram interaktif rilis rusak yang di-rollback:

Monitoring, Rollback, dan Backup untuk Server Docker

Lesson itu juga punya kuis singkat dan latihan rollback di laptop.

## Yang kamu butuhkan

Siapkan empat hal ini sebelum rilis berikutnya, bukan saat sudah rusak. Semua nama di bawah adalah placeholder, ganti dengan milikmu.

VPS Linux dengan Docker Engine dan plugin Compose, dan akses SSH sebagai user biasa (di contoh bernama deploy).

Aplikasi yang dijalankan lewat docker-compose.yml di folder /home/deploy/my-app, dengan tag image dibaca dari variabel IMAGE di file .env.

Image yang di-push ke registry (di contoh ghcr.io/example-user/my-app), supaya versi lama selalu bisa ditarik lagi.

Satu health check di file Compose. Tanpa health check, --wait tidak punya patokan untuk menyebut rilis gagal.

## Langkah 1: Beri tag unik pada setiap image, jangan hanya latest

Rollback artinya menjalankan lagi versi sebelumnya yang terbukti baik. Itu hanya cepat kalau versi tersebut punya nama yang menunjuk tepat satu build. Tag latest berpindah setiap kali ada push, jadi setelah rilis rusak, latest justru menunjuk build yang rusak. Pakai commit SHA sebagai tag: tag itu tidak pernah dipakai ulang, jadi selalu berarti build yang sama.

Pipeline situs ini mem-push setiap image dua kali, sebagai latest dan sebagai commit SHA lengkap, lalu langkah deploy menulis tag SHA itu ke file .env di server sebagai IMAGE. Dengan begitu versi yang live selalu satu build yang pasti. Contoh di atas memakai SHA pendek agar mudah diketik; di CI, biarkan pipeline yang menandai image.

Di docker image ls dan di registry, setiap build punya tag sendiri, dan tag lama tidak berubah saat build baru masuk.

## Langkah 2: Catat versi yang sedang berjalan sebelum deploy

Saat panik, tag yang berjalan baik adalah hal pertama yang hilang dari ingatan. Catat sebelum mengganti apa pun. Satu baris di file teks cukup, dan jangan menyalin seluruh .env karena isinya termasuk secret.

Satu baris berbentuk IMAGE=ghcr.io/example-user/my-app dengan tag di belakangnya tampil di terminal dan tersimpan di deploy-history.txt. Baris itu adalah tujuan rollback-mu.

## Langkah 3: Pastikan image sebelumnya masih ada di server

Rollback paling cepat dimulai dari image yang sudah ada di disk. Lihat apa saja yang tersedia. Kolom default docker image ls adalah REPOSITORY, TAG, IMAGE ID, CREATED, dan SIZE, dan --format dengan template Go memungkinkan tampilan lebih ringkas.

Kalau image lama sudah tidak ada, itu belum tentu masalah selama masih tersimpan di registry: docker compose pull akan menariknya lagi, mungkin setelah docker login. Pembersihan di situs ini sengaja kompromi: image yang dibuat dalam 72 jam terakhir dipertahankan, image portofolio dibatasi ke dua terbaru (rilis yang berjalan dan satu untuk rollback), dan rilis yang lebih tua tetap ada di registry. Volume tidak pernah dihapus oleh pembersihan itu.

Tabel berisi beberapa tag dari image aplikasimu, termasuk tag dari Langkah 2. Kalau tag itu tidak muncul, tandai bahwa kamu perlu pull saat rollback.

## Langkah 4: Deploy versi baru dengan --wait

Deploy biasa memakai pola yang sama dengan rollback: ganti IMAGE, tarik image, jalankan ulang. Bedanya, kita pakai --wait. Dokumentasi Docker menjelaskannya sebagai menunggu service running atau healthy, dan --wait-timeout memberi batas waktu dalam detik. Tanpa itu, up -d kembali setelah container dijalankan, tanpa menunggu hasil health check.

Dalam drill di lesson, rilis yang /health-nya menjawab 500 membuat --wait keluar dengan kode 1 setelah sekitar 19 detik, dengan jeda health check 5 detik. Docker menandai container unhealthy setelah retries kali gagal berturut-turut. Perhatikan juga: pengunjung tetap dilayani oleh rilis rusak itu, karena unhealthy hanyalah label.

Kalau rilis sehat, tercetak exit=0. Kalau tidak sehat atau melewati batas waktu, kode keluar bukan nol, dan itulah sinyal untuk lanjut ke Langkah 5.

--wait hanya membuat deploy menyadari kegagalan, ia tidak membatalkan apa pun. Deploy situs ini sendiri menjalankan docker compose up -d tanpa --wait, jadi rilis yang gagal health check tetap membuat workflow selesai hijau. Rollback tetap langkah yang harus kamu lakukan.

## Langkah 5: Rollback dengan mengembalikan tag lama

Inilah seluruh rollback: tulis tag lama dari Langkah 2 kembali ke IMAGE, pastikan Compose membacanya, lalu jalankan up lagi. Karena tag lama menunjuk satu build yang pasti, tidak ada yang perlu di-build ulang. Compose membuat ulang container karena image-nya berbeda dari yang berjalan.

docker compose config mencetak konfigurasi hasil interpolasi, jadi baris image: memperlihatkan tag yang benar-benar akan dipakai. Pemeriksaan kecil ini mencegah rollback yang diam-diam tidak mengubah apa pun, misalnya karena pola sed tidak cocok. Jangan pakai down -v untuk rollback: opsi -v menghapus named volume yang dideklarasikan di file Compose, dan itu berarti data.

docker compose config menampilkan tag lama, lalu up -d --wait selesai dengan exit=0 setelah container versi lama healthy. Dalam drill di lesson, ini memakan sekitar 8 detik.

## Langkah 6: Verifikasi dari dalam dan dari luar

Jangan berhenti di exit=0. Health check berjalan di dalam container, jadi ia tidak melihat DNS, TLS, atau reverse proxy di depannya. Periksa di dua sisi: di server itu sendiri, dan lewat domain publik seperti pengunjung.

Kalau log menunjukkan error, baca dengan cara yang dibahas di 

panduan melihat Docker logs untuk pemula

. Rollback yang berhasil berarti aplikasi lama booting tanpa error baru.

Container berstatus running, dan healthy setelah masa start period lewat. Kedua curl menjawab dengan kode 200 atau pengalihan yang memang kamu harapkan, dan log menunjukkan aplikasi sudah siap.

## Langkah 7: Jadikan rollback permanen lewat git atau pipeline

Mengedit .env di server hanyalah solusi sementara. Pipeline situs ini menulis ulang .env dengan IMAGE milik build terbaru di setiap deploy, jadi deploy berikutnya akan membawa kode rusak itu kembali kalau kodenya belum diperbaiki. Ada dua jalan resmi: git revert commit yang bermasalah lalu push, atau jalankan ulang workflow dari run terakhir yang berhasil.

Dokumentasi GitHub menyebut re-run memakai commit SHA yang sama dengan run aslinya dan bisa dilakukan sampai 30 hari setelah run pertama. Cara git revert lebih lambat tetapi meninggalkan jejak jelas di riwayat. Pipeline lengkapnya dibahas di 

panduan deploy Next.js ke VPS dengan Docker dan GitHub Actions

.

Workflow baru selesai hijau dengan IMAGE yang sehat, dan docker compose ps di server menunjukkan tag yang sama dengan yang kamu harapkan. Setelah itu perbaiki bug-nya dengan tenang dan rilis versi baru.

## Apa yang tidak bisa dibatalkan rollback

Rollback hanya menukar kode. Migrasi database yang sudah dijalankan tetap berlaku, dan data yang ditulis oleh versi baru tetap ada. Kalau versi baru menghapus atau mengubah nama kolom, versi lama yang kembali berjalan bisa error karena skema yang sudah berubah. Dalam kasus itu rollback berhasil tetapi aplikasi tetap rusak.

Cegahnya ada di cara menulis migrasi: ubah skema dalam dua tahap sehingga versi lama dan baru sama-sama bisa berjalan, seperti di 

panduan migrasi zero-downtime dan rolling deploy

. Untuk data, anggap rollback bukan pengganti backup. Ambil backup sebelum rilis yang menyentuh database, dan uji restore-nya, seperti di 

strategi backup 3-2-1 untuk VPS

.

Jangan menjalankan rollback dengan menghapus volume atau memakai docker compose down -v. Itu tidak mengembalikan kode lama, hanya menghapus data aplikasi dan database.

## Error umum dan cara memperbaikinya

Ini yang paling sering terjadi saat rollback pertama kali. Cocokkan gejalamu dengan baris pertama, lalu lihat penyebab dan perbaikannya.

Gejala

Penyebab

Perbaikan

Rollback dijalankan tetapi aplikasi tetap rusak

IMAGE tidak berubah (pola sed tidak cocok, atau salah folder), atau kamu memakai latest yang sudah menunjuk build rusak.

Jalankan grep IMAGE .env dan docker compose config, pastikan tag lama tampil, lalu pakai tag SHA, bukan latest.

Compose gagal menarik image saat rollback

Tag salah ketik, belum login ke registry, atau image itu sudah dihapus dari registry.

Cocokkan tag dengan deploy-history.txt, lakukan docker login ke registry, lalu ulangi docker compose pull.

Image lama tidak ada di disk

Pembersihan seperti docker image prune -a tanpa filter menghapus semua image yang tidak dipakai container.

Tarik lagi dengan docker compose pull. Ke depannya, pakai filter umur seperti until=72h dan jangan prune volume.

Setelah rollback, up -d --wait tetap keluar dengan kode bukan nol

Versi lama ikut tidak sehat: skema database sudah berubah oleh migrasi, atau konfigurasi di .env sudah berbeda.

Baca docker compose logs --tail 50 web. Kalau karena skema, rollback saja tidak cukup; pulihkan dari backup atau rilis perbaikan maju.

Deploy berikutnya membawa kode rusak kembali

Pipeline menulis ulang IMAGE di .env setiap deploy, dan commit rusak itu masih ada di branch.

Lakukan git revert lalu push, atau perbaiki bug-nya sebelum deploy lagi.

Data aplikasi hilang setelah rollback

Rollback dijalankan dengan docker compose down -v, yang menghapus named volume di file Compose.

Restore dari backup terakhir. Untuk rollback, cukup ganti IMAGE dan jalankan up -d --wait, tanpa down -v.

Container healthy tetapi pengunjung masih melihat error

Health check hanya memeriksa di dalam container, jadi masalah di DNS, TLS, atau reverse proxy tidak terlihat.

Jalankan curl ke domain publik, bukan hanya ke 127.0.0.1, dan periksa konfigurasi proxy-nya.

## Checklist sebelum rilis berikutnya

Setiap image di-push dengan tag commit SHA, dan server membaca tag itu dari IMAGE di .env.

Tag yang sedang berjalan dicatat di deploy-history.txt sebelum mengganti IMAGE.

Image versi sebelumnya masih ada di disk, atau pasti ada di registry dan kamu sudah login.

Deploy memakai docker compose up -d --wait dengan --wait-timeout, dan kode keluarnya diperhatikan.

Setelah rollback kamu verifikasi dengan docker compose ps, curl lokal, curl ke domain publik, dan log.

Rilis yang menyentuh database punya backup yang sudah teruji, dan migrasinya bisa berjalan dengan versi lama.

## Belajar lebih dalam

Panduan ini menjawab satu pertanyaan: bagaimana mengembalikan rilis yang rusak. Lesson gratis kami menempatkannya dalam gambaran yang lebih besar, termasuk drill rilis rusak yang bisa kamu jalankan di laptop dan daftar apa saja yang perlu di-backup di satu server.

Buka lesson: Monitoring, Rollback, dan Backup

Latih rollback ini sekali di laptop sebelum kamu membutuhkannya di server yang sedang bermasalah. Rollback yang pernah dicoba jauh lebih tenang daripada yang pertama kali dijalankan saat pengunjung sedang melihat error.

## Sumber

- Dokumentasi Docker: docker compose up (--wait, --wait-timeout)
- Dokumentasi Docker: docker compose down (opsi --volumes)
- Dokumentasi Docker: docker image ls (kolom, --format, --filter)
- Dokumentasi Docker: HEALTHCHECK (interval, retries, start period)
- Dokumentasi GitHub: menjalankan ulang workflow dan job

Hasil yang diharapkan

## Source links

- https://docs.docker.com/reference/cli/docker/compose/up/
- https://docs.docker.com/reference/cli/docker/compose/down/
- https://docs.docker.com/reference/cli/docker/image/ls/
- https://docs.docker.com/reference/dockerfile/#healthcheck
- https://docs.github.com/en/actions/how-tos/manage-workflow-runs/re-run-workflows-and-jobs

## FAQ

### Kenapa rollback Docker saya tidak mengubah apa pun?

Paling sering IMAGE di .env sebenarnya tidak berubah, karena pola sed tidak cocok atau perintah dijalankan di folder yang salah. Jalankan docker compose config dan lihat baris image: sebelum menjalankan up. Kalau IMAGE diarahkan ke latest, itu sudah menunjuk build yang rusak, jadi pakai tag commit SHA.

### Apakah docker compose up --wait me-rollback rilis yang gagal?

Tidak. --wait menunggu service running atau healthy dan keluar dengan kode bukan nol saat gagal, tetapi tidak pernah membatalkan deploy. Rilis yang rusak bisa tetap melayani pengunjung, jadi rollback adalah langkah terpisah yang harus kamu atau sebuah script jalankan.

### Bisakah rollback deploy Docker kalau image saya hanya bertag latest?

Tidak dengan andal, karena latest berpindah di setiap push dan setelah rilis buruk ia menunjuk build yang buruk. Kalau image lama masih ada di server, kamu bisa menemukannya lewat IMAGE ID, tetapi kebiasaan yang aman adalah tag unik seperti commit SHA. Mulai beri tag setiap build sekarang.

### Apakah rollback juga membatalkan migrasi database?

Tidak. Rollback hanya menukar kode yang berjalan di container, dan migrasi yang sudah dijalankan tetap berlaku. Tulis migrasi dalam dua tahap agar versi lama tetap bisa berjalan, dan buat backup yang sudah teruji sebelum rilis yang menyentuh database.

### Apakah aman memakai docker compose down -v untuk rollback?

Tidak. Opsi -v menghapus named volume yang dideklarasikan di file Compose, yang biasanya berisi datamu. Untuk rollback, ganti IMAGE ke tag sebelumnya lalu jalankan docker compose up -d --wait, dan biarkan volume apa adanya.

---

- HTML version: https://www.matthewswong.com/id/blog/cara-rollback-deploy-docker-di-vps/
- English: https://www.matthewswong.com/en/blog/cara-rollback-deploy-docker-di-vps/
- Site index for agents: https://www.matthewswong.com/llms.txt
- Sitemap: https://www.matthewswong.com/sitemap.xml
- API description (OpenAPI): https://www.matthewswong.com/openapi.json
