diff --git a/.gitignore b/.gitignore index aba1a5b..59ea119 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,5 @@ dist .env.production .env.local tsconfig.tsbuildinfo +.deploy-release +*.tar.gz diff --git a/deploy/scripts/build-linux-release.sh b/deploy/scripts/build-linux-release.sh new file mode 100755 index 0000000..30b42d6 --- /dev/null +++ b/deploy/scripts/build-linux-release.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -euo pipefail + +ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +IMAGE="${DOCKER_IMAGE:-node:20}" +ARTIFACT_NAME="${ARTIFACT_NAME:-abelbirdnest-release.tar.gz}" + +cd "$ROOT_DIR" + +docker run --rm \ + -v "$ROOT_DIR":/app \ + -w /app \ + "$IMAGE" \ + bash -lc ' + set -euo pipefail + npm ci + npx prisma generate + npm run build + rm -rf .deploy-release + mkdir -p .deploy-release + cp -R .next/standalone/. .deploy-release/ + mkdir -p .deploy-release/.next + cp -R .next/static .deploy-release/.next/static + cp -R public .deploy-release/public + cp -R prisma .deploy-release/prisma + [ -f .env.production ] && cp .env.production .deploy-release/.env.production || true + tar -czf '"$ARTIFACT_NAME"' -C .deploy-release . + ' + +echo "Artifact created at $ROOT_DIR/$ARTIFACT_NAME" diff --git a/deploy/scripts/upload-linux-release.sh b/deploy/scripts/upload-linux-release.sh new file mode 100755 index 0000000..31e48f0 --- /dev/null +++ b/deploy/scripts/upload-linux-release.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash +set -euo pipefail + +if [ "$#" -lt 1 ]; then + echo "Usage: $0 [remote_base_dir]" + exit 1 +fi + +TARGET="$1" +REMOTE_BASE_DIR="${2:-/var/www/abelbirdnest-web}" +ARTIFACT_NAME="${ARTIFACT_NAME:-abelbirdnest-release.tar.gz}" +RELEASE_NAME="${RELEASE_NAME:-$(date +%Y%m%d-%H%M%S)}" +REMOTE_RELEASE_DIR="$REMOTE_BASE_DIR/releases/$RELEASE_NAME" + +scp "$ARTIFACT_NAME" "$TARGET:$REMOTE_BASE_DIR/" + +ssh "$TARGET" "mkdir -p '$REMOTE_RELEASE_DIR' && tar -xzf '$REMOTE_BASE_DIR/$ARTIFACT_NAME' -C '$REMOTE_RELEASE_DIR' && ln -sfn '$REMOTE_RELEASE_DIR' '$REMOTE_BASE_DIR/current'" + +echo "Uploaded to $TARGET:$REMOTE_RELEASE_DIR" diff --git a/docs/deploy-production.md b/docs/deploy-production.md index 74f188b..a7acac4 100644 --- a/docs/deploy-production.md +++ b/docs/deploy-production.md @@ -352,6 +352,103 @@ npm run build sudo systemctl restart abelbirdnest-web ``` +## 13. Alternatif Deploy: Build di Lokal, Jalankan di Server + +Repo ini sekarang mendukung output Next.js `standalone`, sehingga build bisa dilakukan di lingkungan Linux lokal/container lalu artifact di-upload ke server. + +### Kapan jalur ini dipakai + +Pakai cara ini jika: + +- server production terlalu kecil untuk `next build` +- build sering mati karena RAM habis +- Anda ingin memisahkan proses build dan runtime + +### Prasyarat + +- build harus dilakukan di Linux, atau container Linux +- versi Node saat build harus sama dengan server +- database migration tetap dijalankan di server + +### Script yang disediakan + +Build artifact Linux: + +```bash +deploy/scripts/build-linux-release.sh +``` + +Upload artifact ke server: + +```bash +deploy/scripts/upload-linux-release.sh +``` + +### Contoh build artifact di lokal + +Pastikan `.env.production` sudah ada di root repo jika ingin ikut dibawa ke artifact. + +```bash +./deploy/scripts/build-linux-release.sh +``` + +Artifact default yang dihasilkan: + +```bash +abelbirdnest-release.tar.gz +``` + +Isi artifact: + +- server Next.js standalone +- static assets `.next/static` +- folder `public` +- folder `prisma` +- `.env.production` jika tersedia + +### Contoh upload ke server + +```bash +./deploy/scripts/upload-linux-release.sh abelbirdnest@server /var/www/abelbirdnest-web +``` + +Setelah upload, script akan: + +- copy artifact ke server +- extract ke `/var/www/abelbirdnest-web/releases/` +- update symlink `/var/www/abelbirdnest-web/current` + +### Langkah setelah upload di server + +Masuk ke server: + +```bash +ssh abelbirdnest@server +cd /var/www/abelbirdnest-web/current +set -a +source .env.production +set +a +npx prisma migrate deploy +``` + +Untuk menjalankan standalone app secara manual: + +```bash +PORT=3007 node server.js +``` + +Jika memakai `systemd`, `WorkingDirectory` service harus diarahkan ke: + +```bash +/var/www/abelbirdnest-web/current +``` + +dan `ExecStart` menjadi: + +```bash +/usr/bin/node server.js +``` + Jika branch utama nanti bukan `main`, sesuaikan perintah `git pull`. ## 12. Checklist Go-Live diff --git a/next.config.ts b/next.config.ts index 5bd0cc0..8092ec7 100644 --- a/next.config.ts +++ b/next.config.ts @@ -8,6 +8,7 @@ const securityHeaders = [ ]; const nextConfig: NextConfig = { + output: "standalone", reactStrictMode: true, poweredByHeader: false, async headers() {