Cara Menjalankan ERPNext di VPS dengan Docker
Panduan self-host ERPNext di VPS dengan Docker: kebutuhan server, 11 container, TLS, email keluar, pin versi, serta uji pemulihan backup.
Apa yang Anda setujui untuk dijalankan
Menjalankan ERPNext secara self-hosted pada VPS adalah pekerjaan operasional, bukan instalasi dengan satu perintah. Stack Docker Compose resmi terdiri dari sebelas container dan menyimpan buku besar umum serta data pelanggan Anda. Karena itu, standar untuk semua langkah berikut harus lebih tinggi: backup belum dapat disebut backup sampai Anda berhasil memulihkannya, dan tag image yang tidak dipatok versinya dapat menyebabkan migrasi skema yang tidak direncanakan.
Beberapa nama akan muncul di seluruh panduan ini. ERPNext adalah aplikasi bisnisnya. Frappe adalah framework Python yang mendasarinya. Bench adalah alat command line untuk mengelola site, dan sudah terpasang di dalam container. Site adalah satu tenant: satu database MariaDB dan satu direktori file yang diunggah. Hampir semua perintah di sini dijalankan bench di dalam container backend untuk satu site bernama tertentu.
Panduan ini menggunakan repository frappe_docker, yaitu deployment yang dikelola oleh proyek tersebut. Semua perintah di bawah telah diperiksa terhadap repository itu pada Agustus 2026. Jika Docker Compose masih baru bagi Anda, menjalankan Docker Compose pada VPS membahas dasar-dasar yang diasumsikan oleh panduan ini.
Berapa kapasitas VPS yang dibutuhkan ERPNext?
The data behind this chart
[
{
"label": "Evaluation",
"vcpu": 2,
"ram_gb": 4,
"disk_gb": 40
},
{
"label": "Small production",
"vcpu": 4,
"ram_gb": 8,
"disk_gb": 100
},
{
"label": "Room to grow",
"vcpu": 4,
"ram_gb": 16,
"disk_gb": 160
}
]Panduan yang dipublikasikan mulai dari 2 vCPU dan 4 GB RAM sebelum satu pengguna pun login. Itu adalah tingkat evaluasi. Angka-angka ini merupakan titik awal, bukan hasil pengukuran dari panduan ini, dan jumlah dokumen Anda sendiri yang menentukan angka sebenarnya. Baris terakhir sama sekali bukan batas minimum yang dipublikasikan. Angka itu kurang lebih menunjukkan titik ketika memori tidak lagi menjadi hal yang perlu Anda pikirkan.
Bersikaplah realistis terhadap paket kecil. VPS 1 GB atau 2 GB akan menjalankan stack, lalu gagal pada impor pertama atau laporan panjang pertama, karena sembilan container yang berjalan lama, buffer pool MariaDB, dan worker Python yang membuat laporan tidak dapat ditampung dalam memori tersebut. Kegagalannya tidak berlangsung secara terkendali. Kernel out-of-memory killer menghentikan sebuah container, lalu docker inspect di dalamnya menampilkan "OOMKilled": true dengan exit code 137. Worker yang dihentikan di tengah pekerjaan dapat meninggalkan dokumen yang sudah dikirim dengan proses background yang baru selesai sebagian.
Untuk perusahaan yang menggunakan ERPNext setiap hari, 8 GB RAM, 4 vCPU, dan 100 GB SSD adalah batas minimum yang realistis. RAM habis terlebih dahulu. Penggunaan disk bertambah lebih cepat dari perkiraan, karena setiap lampiran dan setiap backup lokal disimpan pada volume yang sama dengan database.
Sebelas container dan fungsi masing-masing
Jalankan docker compose ps setelah stack aktif dan sembilan container berjalan. Dua container lainnya, configurator dan create-site, menjalankan tugasnya satu kali lalu berhenti. Karena itu, jumlah keseluruhannya menjadi sebelas.
backendmenjalankan aplikasi Frappe menggunakan gunicorn.benchberada di sini.frontendadalah nginx. Container ini menyajikan aset statis dan meneruskan permintaan lainnya ke backend.queue-shortdanqueue-longadalah worker RQ (Redis Queue). Keduanya menjalankan job latar belakang, seperti email keluar, impor, dan pembuatan laporan.schedulermenjalankan job berbasis waktu, termasuk laporan terjadwal dan dokumen berulang otomatis.websocketadalah proses socket.io yang menangani pembaruan langsung di browser.dbadalah MariaDB.redis-cachedanredis-queueadalah dua instance Redis terpisah. Salah satunya digunakan untuk cache, sedangkan yang lainnya digunakan untuk antrean job.
Pemisahan ini penting untuk dipahami karena membantu menentukan log yang harus dibaca. Email yang macet merupakan masalah pada queue worker, sehingga docker compose logs -f queue-short adalah perintah yang tepat. Jika halaman berhasil dimuat tetapi lencana notifikasi tidak pernah diperbarui, masalahnya ada pada websocket. Membaca log backend untuk kedua masalah tersebut hanya membuang waktu.
Instal dengan file compose production, bukan demo
Repository menyediakan pwd.yml, dan README menjelaskannya secara tegas: "Penyiapan ini hanya ditujukan untuk evaluasi jangka pendek. Anda tidak akan dapat menginstal aplikasi kustom pada penyiapan ini." Gunakan ini untuk mencoba ERPNext selama satu sore. Jangan gunakan ini untuk menjalankan sistem perusahaan.
sudo apt update && sudo apt install -y git
curl -fsSL https://get.docker.com | bash
git clone https://github.com/frappe/frappe_docker
cd frappe_docker
mkdir -p ~/gitops
cp example.env ~/gitops/erpnext.envBuka ~/gitops/erpnext.env dan ubah empat nilai. ERPNEXT_VERSION menetapkan tag image. DB_PASSWORD disediakan sebagai 123 dalam file contoh. SITES_RULE adalah aturan routing Traefik, sedangkan LETSENCRYPT_EMAIL menerima peringatan sertifikat.
ERPNEXT_VERSION=v16.32.1
DB_PASSWORD=<a long random password>
SITES_RULE=Host(`erp.example.com`)
LETSENCRYPT_EMAIL=ops@example.comSekarang render satu file compose, lalu jalankan file tersebut.
docker compose --project-name erpnext \
--env-file ~/gitops/erpnext.env \
-f compose.yaml \
-f overrides/compose.mariadb.yaml \
-f overrides/compose.redis.yaml \
-f overrides/compose.https.yaml \
config > ~/gitops/erpnext.yaml
docker compose --project-name erpnext -f ~/gitops/erpnext.yaml up -dconfig tidak menjalankan apa pun. Perintah ini menggabungkan file dasar dengan override, lalu mencetak hasilnya dengan semua variabel yang sudah disubstitusikan. Setelah itu, jalankan file hasil render tersebut. Langkah tambahan ini bermanfaat: stack yang berjalan tersimpan dalam satu file yang dapat dibaca dan di-commit, sehingga konfigurasinya tidak berubah tanpa Anda sadari ketika seseorang mengedit file env atau ketika Anda melakukan pull terhadap repository. cara beberapa file Docker Compose digabungkan menjelaskan aturan override secara terperinci.
Tunggu db hingga berjalan dan configurator hingga selesai, yang memerlukan waktu beberapa detik, lalu buat site.
docker compose --project-name erpnext exec backend \
bench new-site --mariadb-user-host-login-scope=% \
--db-root-password '<your DB_PASSWORD>' \
--install-app erpnext \
--admin-password '<a strong admin password>' \
erp.example.comPeriksa hasilnya:
docker compose --project-name erpnext ps
docker compose --project-name erpnext exec backend bench --site erp.example.com list-appslist-apps seharusnya mencetak frappe dan erpnext beserta versinya. ps yang sehat menampilkan sembilan service dalam status running dan tidak ada service dalam status restarting.
Ada dua masalah yang sering terjadi di sini. --mariadb-user-host-login-scope=% tidak opsional pada Docker. Container aplikasi mengakses MariaDB melalui jaringan Docker, sehingga koneksi tersebut datang sebagai host jarak jauh, dan user database yang cakupannya hanya localhost tidak dapat login dari sana. Pembuatan site kemudian gagal dengan error akses MariaDB ditolak yang menyebut user root. Cakupan % memberikan akses kepada user site baru dari host mana pun pada jaringan privat tersebut.
Masalah kedua adalah nama site. Secara default, frontend memilih site yang akan dilayani berdasarkan header HTTP Host, sehingga site yang dibuat sebagai erpnext tidak dapat diakses di erp.example.com meskipun keduanya ada. Beri nama site sesuai domain, seperti di atas, atau tetapkan FRAPPE_SITE_NAME_HEADER dalam file env ke nama site, lalu render kembali file compose.
HTTPS dan prasyarat agar dapat berfungsi
Override compose.https.yaml menjalankan Traefik pada port 443, mengalihkan port 80 ke port tersebut, dan meminta sertifikat dari Let's Encrypt. TLS (keamanan lapisan transport) menjaga invoice dan cookie sesi agar tidak dikirim dalam teks biasa melalui jaringan.
Dua hal harus terpenuhi. Jika tidak, sertifikat tidak akan pernah diterbitkan. A record DNS untuk erp.example.com harus sudah mengarah ke VPS. Port 80 dan 443 harus dapat dijangkau dari Internet karena Let's Encrypt memverifikasi bahwa Anda mengendalikan nama tersebut melalui tantangan HTTP-01 pada port 80. Periksa firewall jaringan provider dan firewall pada server. Keduanya merupakan kontrol yang terpisah, dan firewall pada panel sering terlupakan.
Sertifikat tersimpan di volume cert-data pada /letsencrypt/acme.json. Jika browser menampilkan sertifikat default, bukan sertifikat Anda, cari nama service proxy di docker compose --project-name erpnext ps, lalu baca log-nya untuk menemukan error ACME (automatic certificate management environment). Menjalankan aplikasi web lain pada server yang sama? satu instance Traefik di depan beberapa aplikasi Docker Compose menunjukkan cara berbagi proxy tanpa berebut port 443. Aplikasi kedua pada server seperti ini sering ditujukan untuk pelanggan, dan meja bantuan Chatwoot yang di-host sendiri berada di belakang proxy yang sama. Dengan demikian, orang yang menangani invoice juga dapat menjawab email dan chat pelanggan di satu tempat.
Email keluar, atau faktur tidak pernah meninggalkan server
Ini adalah langkah yang sering dilewati panduan ERPNext, padahal langkah ini menentukan apakah sistem benar-benar dapat digunakan. Tanpa email keluar yang berfungsi, tidak ada faktur yang sampai kepada pelanggan, permintaan pengaturan ulang kata sandi tidak diterima, dan laporan terjadwal tidak terkirim. Stack ini tidak menyertakan server email.
Jangan mencoba mengirim email langsung dari VPS melalui port 25. Sebagian besar provider memblokir port keluar 25 pada akun baru. Email yang berhasil keluar pun dapat ditolak atau masuk ke folder spam karena alamat VPS baru belum memiliki reputasi pengiriman. Gunakan relay terautentikasi pada port 587.
Cara yang didukung adalah menggunakan layar Email Account pada antarmuka ERPNext. Layar ini menyimpan kata sandi dalam bentuk terenkripsi. Anda juga dapat menulis key tersebut ke konfigurasi site:
docker compose --project-name erpnext exec backend \
bench --site erp.example.com set-config mail_server smtp.example.com
docker compose --project-name erpnext exec backend \
bench --site erp.example.com set-config mail_port 587 --parse
docker compose --project-name erpnext exec backend \
bench --site erp.example.com set-config use_tls 1 --parse
docker compose --project-name erpnext exec backend \
bench --site erp.example.com set-config mail_login 'erp@example.com'
docker compose --project-name erpnext exec backend \
bench --site erp.example.com set-config auto_email_id 'erp@example.com'--parse menyimpan 587 sebagai angka, bukan sebagai string "587". Baca kembali file tersebut dan pastikan kedua nilai itu tidak diapit tanda kutip:
docker compose --project-name erpnext exec backend \
cat sites/erp.example.com/site_config.jsonAtur mail_password melalui layar Email Account, bukan melalui command line, agar nilainya disimpan dalam bentuk terenkripsi dan tidak pernah masuk ke shell history.
Selanjutnya, kirim pesan sungguhan. Buat Sales Invoice, kirim melalui email ke alamat yang Anda kendalikan, lalu pantau antreannya:
docker compose --project-name erpnext logs -f queue-shortEmail keluar diproses sebagai background job. Karena itu, pesan yang tidak pernah sampai biasanya muncul sebagai job yang gagal di log tersebut, bukan sebagai error di browser. Publikasikan juga record SPF (sender policy framework) dan DKIM (domainkeys identified mail) untuk domain pengirim, lalu tambahkan kebijakan DMARC. Tanpa record tersebut, faktur yang secara teknis benar tetap dapat masuk ke folder spam pelanggan. Jika Anda ingin mengelola seluruh jalur pengiriman sendiri, server email Mailcow yang di-host sendiri menyediakan relay yang Anda kendalikan, pada server terpisah dari ERP.
Cadangan yang benar-benar dapat dipulihkan
Dump database saja bukan cadangan ERPNext. Lampiran dan file privat berada di direktori sites, bukan di MariaDB. Jika hanya database yang dipulihkan, setiap purchase order yang diunggah akan kembali sebagai tautan rusak.
docker compose --project-name erpnext exec backend \
bench --site erp.example.com backup --with-filesPerintah tersebut menulis empat file ke dalam sites/erp.example.com/private/backups pada volume sites:
- dump
-database.sql.gz - arsip
-files.tarberisi file publik - arsip
-private-files.tarberisi file privat - salinan
-site_config_backup.jsonkonfigurasi site
File keempat sering dibuang, padahal file inilah yang paling bermasalah jika hilang. File tersebut berisi encryption_key, yaitu kunci yang digunakan Frappe untuk mengenkripsi password yang tersimpan: kredensial akun email, kunci payment gateway, dan setiap secret integrasi. Jika database dipulihkan tanpa kunci yang sesuai, site akan dimuat secara normal, tetapi pengiriman email gagal dengan pesan berikut:
frappe.exceptions.ValidationError: Encryption key is invalid! Please check site_config.jsonSimpan keempat file tersebut secara bersamaan setiap saat.
Selanjutnya, keluarkan file-file tersebut dari server. Cadangan di dalam volume tidak akan bertahan jika server rusak, dan bench juga akan menghapusnya: secara default, bench menghapus cadangan yang berusia lebih dari 24 jam dari direktori tersebut.
docker compose --project-name erpnext cp \
backend:/home/frappe/frappe-bench/sites/erp.example.com/private/backups \
~/erpnext-backupsJalankan perintah tersebut dari cron, lalu kirim direktori itu ke lokasi yang tidak Anda administrasikan. cadangan restic terenkripsi ke penyimpanan di luar lokasi adalah alat yang tepat karena restic mengenkripsi data sebelum upload, dan restic check membuktikan bahwa repository masih dapat dibaca. Cadangan ERP adalah salinan seluruh ledger Anda, sehingga harus disimpan dalam keadaan terenkripsi pada perangkat keras yang bukan server ini.
Uji pemulihan sebelum Anda membutuhkannya
Cadangan yang belum diuji hanya merupakan perkiraan. Uji pemulihan pada site kedua di server yang sama, jangan pernah pada site produksi.
docker compose --project-name erpnext exec backend \
bench new-site --mariadb-user-host-login-scope=% \
--db-root-password '<your DB_PASSWORD>' \
--admin-password '<a strong admin password>' \
restore-test.example.com
docker compose --project-name erpnext exec backend \
bench --site restore-test.example.com --force restore \
sites/erp.example.com/private/backups/<stamp>-erp.example.com-database.sql.gz \
--with-public-files sites/erp.example.com/private/backups/<stamp>-erp.example.com-files.tar \
--with-private-files sites/erp.example.com/private/backups/<stamp>-erp.example.com-private-files.tar \
--db-root-password '<your DB_PASSWORD>'Salin kunci enkripsi dari konfigurasi yang dicadangkan ke site hasil pemulihan. Jika tidak, integrasi pada site tersebut akan tetap rusak:
docker compose --project-name erpnext exec backend \
bench --site restore-test.example.com set-config encryption_key '<value from site_config_backup.json>'Sekarang periksa pemulihan seperti seorang akuntan. Buka laporan Accounts Receivable dan bandingkan saldo akhir dengan site produksi. Buka faktur pembelian terbaru dan unduh lampirannya. Site yang hanya dapat menampilkan halaman login tidak membuktikan apa pun.
Hapus site pengujian setelah selesai:
docker compose --project-name erpnext exec backend \
bench drop-site restore-test.example.comMengapa pinning versi lebih penting untuk ERPNext
Pada situs statis, tag image yang tidak dipatok berarti restart tak terduga. Pada ERPNext, artinya migrasi schema. bench migrate menulis ulang tabel database dan dapat menulis ulang data dokumen, tanpa opsi pembatalan. Rollback berarti memulihkan dari backup, bukan docker compose down.
Karena itu, patok tag tersebut. ERPNEXT_VERSION=v16.32.1 adalah release yang dipatok dalam pwd.yml milik repository pada Agustus 2026. Jangan gunakan nomor tersebut terus-menerus tanpa memeriksanya. Release saat ini tercantum pada halaman release frappe/erpnext, sedangkan tag image yang tersedia tercantum di Docker Hub. Baca catatan untuk versi yang akan Anda gunakan sebelum melakukan pemindahan.
Upgrade dimulai dengan backup dan maintenance mode.
docker compose --project-name erpnext exec backend \
bench --site erp.example.com backup --with-files
docker compose --project-name erpnext exec backend \
bench --site erp.example.com set-maintenance-mode onEdit ERPNEXT_VERSION di ~/gitops/erpnext.env, lalu render, pull, dan migrate.
docker compose --project-name erpnext \
--env-file ~/gitops/erpnext.env \
-f compose.yaml \
-f overrides/compose.mariadb.yaml \
-f overrides/compose.redis.yaml \
-f overrides/compose.https.yaml \
config > ~/gitops/erpnext.yaml
docker compose --project-name erpnext -f ~/gitops/erpnext.yaml pull
docker compose --project-name erpnext -f ~/gitops/erpnext.yaml up -d
docker compose --project-name erpnext exec backend \
bench --site erp.example.com migrate
docker compose --project-name erpnext exec backend \
bench --site erp.example.com set-maintenance-mode offMaintenance mode penting karena migrate mengubah schema saat berjalan. Jika pengguna mengirimkan dokumen ke tabel yang baru dimigrasikan sebagian, Anda dapat berakhir dengan pekerjaan memperbaiki record secara manual.
Lakukan upgrade satu major version setiap kali, dengan backup di antara setiap langkah. Kode migrasi dalam suatu release ditulis untuk melakukan upgrade dari release sebelumnya. Jika major version dilewati, migrasi dijalankan dalam kombinasi yang tidak pernah diuji.
Repository tersebut juga menyediakan overrides/compose.migrator.yaml, yang menambahkan container untuk menjalankan bench --site all migrate setiap kali start. Ini praktis. Namun, docker compose up dengan tag yang berubah juga dapat memigrasikan database production Anda tanpa ada yang memantaunya. Pada sistem bisnis, jalankan migrate sebagai keputusan yang Anda ambil pada pagi itu.
Memperkuat keamanan server yang menyimpan data pelanggan
Ubah kata sandi Administrator saat login pertama. File compose evaluasi menetapkan admin sebagai kata sandi tersebut, dan kebiasaan ini dapat terbawa ke lingkungan produksi.
Ubah DB_PASSWORD dari 123 di example.env. Nilai tersebut akan muncul dalam ~/gitops/erpnext.yaml yang dirender dalam teks biasa, jadi chmod 600 file tersebut dan jangan menyimpannya di repositori git mana pun. Untuk opsi yang lebih aman, overrides/compose.mariadb-secrets.yaml membaca kata sandi dari file Docker secret, bukan dari variabel lingkungan. menangani file env dan secret di Docker Compose membahas berbagai pertimbangannya.
Publikasikan hanya yang diperlukan. Dengan override HTTPS, hanya port 80 dan 443 yang diekspos. Jangan menambahkan pemetaan ports ke service db agar client database lebih mudah terhubung karena tindakan tersebut menempatkan MariaDB di Internet publik. Sebagai gantinya, gunakan docker compose --project-name erpnext exec backend bench mariadb. Pada host, izinkan 22, 80, dan 443, tolak port lainnya, lalu periksa juga firewall jaringan terpisah milik provider.
Aktifkan autentikasi dua faktor di System Settings untuk setiap akun yang memiliki peran System Manager. Peran tersebut dapat membaca setiap dokumen dan mengekspor setiap tabel, jadi perlakukan akun tersebut sebagai akun administrator, bukan sekadar kemudahan. Jika Anda menjalankan beberapa aplikasi self-hosted, Authentik sebagai penyedia single sign-on self-hosted lebih baik daripada menambahkan satu kata sandi lagi untuk setiap aplikasi.
Terapkan patch pada host dan lakukan reboot untuk pembaruan kernel. Sebelum mengandalkan stack untuk kembali berjalan, periksa file yang dirender guna memastikan adanya kebijakan restart pada setiap service karena stack tanpa kebijakan tersebut akan tetap berhenti setelah reboot. membuat stack Docker Compose berjalan kembali setelah reboot membahas konfigurasi systemd.
Saat ERPNext tidak lagi nyaman dijalankan pada satu VPS
Satu VPS dapat menjalankan kebutuhan perusahaan kecil dalam waktu lama. Tanda-tanda bahwa kapasitasnya tidak lagi mencukupi antara lain:
- Pekerjaan latar belakang menumpuk, sehingga email dan proses impor terlambat beberapa menit atau beberapa jam.
- Laporan
docker inspectmenunjukkan container dengan"OOMKilled": trueatau exit code 137. - Laporan yang sebelumnya selesai dalam dua detik kini membutuhkan tiga puluh detik, dan MariaDB menjadi proses yang menggunakan CPU.
- Proses backup berlangsung cukup lama hingga satu eksekusi tumpang tindih dengan eksekusi terjadwal berikutnya.
Mulailah dengan menyediakan resource khusus untuk MariaDB. Database dan worker Python bersaing menggunakan memori yang sama, sedangkan buffer pool membutuhkan porsi memori yang lebih besar. Menambah kapasitas application server biasanya tidak memberikan peningkatan sebesar yang diharapkan. menjalankan database dalam Docker atau pada host membahas pilihan tersebut, sedangkan menetapkan batas memori dalam Docker Compose mencegah satu container menghabiskan resource container lain selama Anda melakukan perubahan.
Setelah itu, tambahkan queue worker, bukan kapasitas web. Pekerjaan ERPNext yang lambat berlangsung di latar belakang, seperti pembuatan laporan dan impor massal. Menambah container worker lebih murah daripada menambah kapasitas server, dan langsung mengatasi masalah yang dikeluhkan pengguna.
FAQ
Berapa RAM yang diperlukan ERPNext pada VPS?
Panduan yang dipublikasikan menyarankan mulai dari 4 GB dengan 2 vCPU, tetapi tingkat ini hanya untuk evaluasi. Untuk perusahaan yang menggunakannya setiap hari, siapkan 8 GB dan 4 vCPU dengan SSD berkapasitas 100 GB. Jika kurang dari itu, kernel out-of-memory killer akan menghentikan container saat beban tinggi. docker inspect melaporkan kondisi tersebut sebagai "OOMKilled": true dengan exit code 137. Angka ini adalah titik awal, bukan hasil pengukuran. Pantau penggunaan memori Anda sendiri selama bulan pertama.
Apakah saya dapat menjalankan pwd.yml di lingkungan produksi?
Tidak. README proyek menjelaskan bahwa file tersebut hanya ditujukan untuk evaluasi jangka pendek dan menyebutkan bahwa Anda tidak dapat menginstal aplikasi kustom ke dalamnya. Gunakan compose.yaml dengan override MariaDB, Redis, dan HTTPS. Render semuanya menjadi satu file menggunakan docker compose config, lalu jalankan file tersebut.
Mengapa site ERPNext saya tidak dapat diakses segera setelah dibuat?
Secara default, frontend memilih site yang akan dilayani berdasarkan header HTTP Host. Karena itu, nama site harus sama dengan domain pada browser. Site yang dibuat sebagai erpnext tidak akan dilayani pada erp.example.com. Buat site menggunakan domain sebagai namanya, atau tetapkan FRAPPE_SITE_NAME_HEADER dalam file env ke nama site, render ulang file compose, lalu restart stack.
Apa saja yang harus ada dalam backup ERPNext?
Ada empat file yang harus disimpan bersama: dump -database.sql.gz, arsip -files.tar dan -private-files.tar, serta salinan konfigurasi -site_config_backup.json. Menjalankan bench --site erp.example.com backup --with-files akan menghasilkan keempat file tersebut. Salinan konfigurasi berisi encryption_key. Tanpa file itu, password integrasi yang tersimpan tidak dapat didekripsi saat pemulihan, dan kondisi tersebut muncul sebagai Encryption key is invalid! Please check site_config.json.
Bagaimana cara meng-upgrade ERPNext tanpa merusak data?
Buat backup menggunakan --with-files, aktifkan maintenance mode, ubah ERPNEXT_VERSION dalam file env, render ulang file compose, pull image, jalankan stack, lalu jalankan bench --site erp.example.com migrate dan nonaktifkan maintenance mode. Lakukan upgrade satu major version setiap kali dan baca release notes terlebih dahulu karena migrate menulis ulang schema dan data dokumen tanpa opsi undo. Untuk melakukan rollback, pulihkan backup yang dibuat pada awal proses.