Helipod dirancang agar zero config — cukup push kode dan langsung live. Tapi untuk kebutuhan yang lebih spesifik, kamu bisa memberi instruksi tambahan ke Helipack lewat satu file: helipack.json.
File ini ditempatkan di root repository kamu, dan Helipack akan membacanya saat build untuk meng-override perilaku default.
Struktur helipack.json
Ini adalah semua opsi yang tersedia:
{
"build": {
"dockerfile": "string",
"sourcefile": "string"
},
"run": {
"before": "string",
"command": "string",
"after": "string",
"port": 8000,
"isTcp": false
},
"health": {
"path": "/health",
"duration": 15
},
"volume": {
"mountPath": "/app/storage",
"size": 5
},
"env": {
"KEY": "value"
},
"spec": {
"cpu": 1,
"memory": 512
},
"packages": {
"apk": [],
"apt": [],
"pecl": [],
"phpext": [],
"pip": []
}
}
Mari kita bahas setiap bagian satu per satu.
build — Konfigurasi Build
build.dockerfile
Gunakan Dockerfile kustom alih-alih Dockerfile yang di-generate Helipack.
{
"build": {
"dockerfile": "docker/Dockerfile.production"
}
}
Path relatif dari root repository. Berguna jika kamu punya Dockerfile sendiri di subfolder, atau memiliki beberapa Dockerfile untuk environment berbeda.
build.sourcefile
Khusus untuk Function Pod (serverless function). Menentukan nama file yang menjadi entry point.
{
"build": {
"sourcefile": "handler.ts"
}
}
run — Konfigurasi Runtime
run.port
Override port default yang diexpose aplikasi. Helipack mendeteksi port dari EXPOSE di Dockerfile, tapi kamu bisa override di sini.
{
"run": {
"port": 8080
}
}
Kapan dipakai: Jika aplikasi kamu jalan di port non-standard, atau jika Helipack mendeteksi port yang salah.
run.command
Override start command default. Helipack punya default command per framework (gunicorn untuk Flask/Django, node dist/main untuk NestJS, dll), tapi kamu bisa override.
{
"run": {
"command": "gunicorn myapp.wsgi:application --bind 0.0.0.0:8000 --workers 4 --timeout 120"
}
}
Contoh lain:
{
"run": {
"command": "uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 2 --loop uvloop"
}
}
{
"run": {
"command": "node --max-old-space-size=2048 dist/main.js"
}
}
run.before
Command yang dijalankan sebelum start command, setiap kali ada deployment baru. Ideal untuk database migration.
{
"run": {
"before": "php artisan migrate --force"
}
}
Contoh untuk berbagai framework:
{ "run": { "before": "php artisan migrate --force && php artisan storage:link" } }
{ "run": { "before": "python manage.py migrate --run-syncdb" } }
{ "run": { "before": "npx prisma migrate deploy" } }
{ "run": { "before": "alembic upgrade head" } }
Penting: Jika
run.beforegagal (exit code non-zero), deployment akan dianggap gagal dan pod tidak akan dijalankan. Gunakan|| truedi akhir jika command boleh gagal:{ "run": { "before": "php artisan view:cache || true" } }
run.after
Command yang dijalankan setelah aplikasi mulai berjalan dan health check pertama berhasil.
{
"run": {
"after": "php artisan queue:restart"
}
}
run.isTcp
Set ke true jika aplikasi kamu adalah TCP server (bukan HTTP/HTTPS). Health check HTTP akan dinonaktifkan.
{
"run": {
"port": 9000,
"isTcp": true
}
}
Kapan dipakai: Aplikasi WebSocket, gRPC server, database, game server, atau service TCP lainnya. Baca Panduan TCP Mode di Helipod untuk detail.
health — Konfigurasi Health Check
Helipod secara berkala melakukan HTTP GET ke endpoint health check untuk memastikan pod masih sehat. Jika health check gagal berkali-kali, pod akan di-restart otomatis.
health.path
Path endpoint health check. Default: /.
{
"health": {
"path": "/api/health"
}
}
Rekomendasi: buat endpoint khusus yang mengecek koneksi database dan dependencies kritis.
Contoh health endpoint untuk Django:
# views.py
from django.http import JsonResponse
from django.db import connection
def health(request):
try:
connection.ensure_connection()
return JsonResponse({"status": "ok", "db": "connected"})
except Exception as e:
return JsonResponse({"status": "error", "detail": str(e)}, status=503)
Contoh untuk NestJS:
@Controller('api/health')
export class HealthController {
@Get()
check() {
return { status: 'ok', timestamp: new Date().toISOString() };
}
}
health.duration
Waktu tunggu (detik) sebelum Helipod mulai melakukan health check setelah pod start. Default: 15 detik.
{
"health": {
"path": "/health",
"duration": 30
}
}
Kapan dinaikkan: Jika aplikasi kamu butuh waktu lama untuk startup (misalnya loading ML model besar, warming up cache). Set ke waktu yang cukup agar pod tidak di-restart prematur.
volume — Persistent Storage
Konfigurasi persistent volume yang di-mount ke container. File dalam volume ini tidak hilang saat redeploy.
volume.mountPath
Path di dalam container tempat volume di-mount.
{
"volume": {
"mountPath": "/app/storage",
"size": 10
}
}
volume.size
Ukuran volume dalam GB. Default: bergantung plan.
Kapan dipakai:
- Laravel: mount
/var/www/html/storageuntuk uploaded files - Aplikasi yang menyimpan file lokal (uploads, generated PDFs, dll)
- Database SQLite
- Aplikasi yang butuh cache persistent antar restart
Baca Panduan Persistent Volume di Helipod untuk detail.
env — Default Environment Variables
Set default environment variables yang akan di-inject ke container. Variable yang di-set di tab Variables dashboard akan override nilai di sini.
{
"env": {
"NODE_ENV": "production",
"TZ": "Asia/Jakarta",
"LOG_LEVEL": "info",
"CACHE_TTL": "3600"
}
}
Kapan dipakai: Untuk nilai default yang tidak sensitif. Jangan simpan secret (API key, password) di sini karena helipack.json ada di repository.
spec — Resource Requirements
Override resource yang dibutuhkan pod. Ini adalah hint untuk Helipod — resource aktual tetap dibatasi oleh plan yang kamu pilih.
{
"spec": {
"cpu": 500,
"memory": 512
}
}
cpu: jumlah vCPU (250, 500, 1000, 2000, dst)memory: RAM dalam MB (256, 512, 1024, 2048, dst)
packages — System Package Tambahan
Tambahkan package sistem yang tidak tersedia secara default di base image.
packages.apk — Alpine Linux Packages
Untuk Node.js dan PHP (Alpine-based):
{
"packages": {
"apk": ["ffmpeg", "imagemagick", "wkhtmltopdf", "ghostscript"]
}
}
Contoh use case:
ffmpeg— video/audio processingimagemagick— image manipulationwkhtmltopdf— HTML ke PDFghostscript— PDF processingchromium— headless browser (Puppeteer)
packages.apt — Debian/Ubuntu Packages
Untuk Python (Debian-based):
{
"packages": {
"apt": ["libpq-dev", "libmagic1", "ffmpeg", "poppler-utils"]
}
}
packages.phpext — PHP Extensions
Tambahkan PHP extensions menggunakan mlocati/php-extension-installer:
{
"packages": {
"phpext": ["redis", "imagick", "gd", "zip", "intl", "opcache"]
}
}
Extensions yang sudah diinstall by default untuk Laravel: pdo_mysql, pdo_pgsql, mbstring, xml, bcmath, pcntl, intl, zip, sodium.
packages.pecl — PHP PECL Extensions
{
"packages": {
"pecl": ["redis", "swoole", "imagick"]
}
}
packages.pip — Extra Python Packages
Packages pip tambahan yang diinstall di atas requirements.txt:
{
"packages": {
"pip": ["torch", "transformers"]
}
}
Kapan dipakai: Untuk packages besar seperti PyTorch yang tidak ingin kamu commit ke requirements.txt karena ukurannya.
Contoh Lengkap per Use Case
Laravel Production dengan Queue
{
"run": {
"port": 8000,
"before": "php artisan migrate --force && php artisan config:cache && php artisan route:cache",
"after": "php artisan queue:restart"
},
"health": {
"path": "/",
"duration": 20
},
"volume": {
"mountPath": "/var/www/html/storage",
"size": 10
},
"packages": {
"phpext": ["redis", "gd"],
"apk": ["imagemagick"]
},
"env": {
"TZ": "Asia/Jakarta"
}
}
Next.js dengan Custom Port
{
"run": {
"port": 3000
},
"health": {
"path": "/api/health",
"duration": 30
},
"env": {
"TZ": "Asia/Jakarta",
"NODE_ENV": "production"
}
}
Django + Celery (tanpa separate worker pod)
{
"run": {
"port": 8000,
"before": "python manage.py migrate --run-syncdb && python manage.py collectstatic --noinput",
"command": "gunicorn myproject.wsgi:application --bind 0.0.0.0:8000 --workers 3 --timeout 120"
},
"health": {
"path": "/health/",
"duration": 25
},
"packages": {
"apt": ["libpq-dev", "ffmpeg"]
}
}
FastAPI ML Model Serving
{
"run": {
"port": 8000,
"command": "uvicorn app.main:app --host 0.0.0.0 --port 8000 --workers 1",
"before": "python scripts/download_model.py"
},
"health": {
"path": "/health",
"duration": 60
},
"volume": {
"mountPath": "/app/models",
"size": 20
},
"spec": {
"cpu": 2,
"memory": 4096
},
"packages": {
"pip": ["torch", "transformers", "accelerate"]
}
}
NestJS + Prisma
{
"run": {
"port": 3000,
"before": "npx prisma migrate deploy",
"command": "node dist/main"
},
"health": {
"path": "/api/health",
"duration": 20
},
"env": {
"NODE_ENV": "production"
}
}
TCP Server (WebSocket / gRPC)
{
"run": {
"port": 9000,
"isTcp": true,
"command": "node dist/server.js"
}
}
Prioritas Konfigurasi
Saat ada konflik antara nilai di helipack.json dan konfigurasi di dashboard Helipod, berikut prioritasnya (dari tertinggi ke terendah):
- Dashboard Variables — environment variables yang di-set di tab Variables
- helipack.json
env— default env vars di file konfigurasi - Helipack defaults — nilai bawaan per framework
Ini berarti kamu bisa set nilai default di helipack.json untuk development, lalu override di dashboard untuk production — tanpa ubah kode.
Validasi helipack.json
Sebelum push ke repository, validasi JSON-mu agar tidak ada syntax error:
# Di terminal local
cat helipack.json | python -m json.tool
# Atau gunakan jq
jq . helipack.json
Syntax error di helipack.json akan menyebabkan Helipack mengabaikan file ini dan menggunakan konfigurasi default — bukan menyebabkan build gagal.
Kesimpulan
helipack.json adalah cara kamu berbicara langsung ke Helipack — memberi instruksi spesifik tentang bagaimana aplikasimu harus di-build dan dijalankan. Dari yang sederhana seperti custom port, sampai yang kompleks seperti ML model serving dengan GPU — semua bisa dikonfigurasi lewat satu file JSON.
Ingin tahu lebih dalam tentang cara Helipack mendeteksi framework dan menghasilkan Dockerfile? Baca Helipack: Dockerfile Otomatis.
Punya pertanyaan? Hubungi kami di support@helipod.id atau bergabung ke komunitas di hangar.helipod.io.