Add standalone artifact deploy workflow
This commit is contained in:
2
.gitignore
vendored
2
.gitignore
vendored
@ -8,3 +8,5 @@ dist
|
||||
.env.production
|
||||
.env.local
|
||||
tsconfig.tsbuildinfo
|
||||
.deploy-release
|
||||
*.tar.gz
|
||||
|
||||
30
deploy/scripts/build-linux-release.sh
Executable file
30
deploy/scripts/build-linux-release.sh
Executable file
@ -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"
|
||||
19
deploy/scripts/upload-linux-release.sh
Executable file
19
deploy/scripts/upload-linux-release.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echo "Usage: $0 <user@host> [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"
|
||||
@ -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/<timestamp>`
|
||||
- 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
|
||||
|
||||
@ -8,6 +8,7 @@ const securityHeaders = [
|
||||
];
|
||||
|
||||
const nextConfig: NextConfig = {
|
||||
output: "standalone",
|
||||
reactStrictMode: true,
|
||||
poweredByHeader: false,
|
||||
async headers() {
|
||||
|
||||
Reference in New Issue
Block a user