$ aoox

DocsAplikasi

Cara build

Tiga cara mengubah repo menjadi image: Dockerfile milikmu sendiri, deteksi otomatis oleh Nixpacks, atau situs statis dengan nginx.

Pilihan
Dockerfile · Nixpacks · Railpack · Situs statis, per aplikasi
Berjalan di
Daemon Docker (builder klasik); Railpack lewat BuildKit sendiri
Hasil
Image <registry>/<project>/<app>:<id>
Halaman ini tentang aplikasi yang dibangun dari repo Git. Aplikasi yang sumbernya image siap pakai tidak melewati tahap build sama sekali — lihat Dua sumber aplikasi.

Mana yang dipilih?

Hasilnya hanya file HTML/CSS/JS (Vite, CRA, Astro, Hugo, dokumentasi)?ya → Situs statistidak → lanjut
Repo sudah punya Dockerfile?ya → Dockerfiletidak → lanjut
Butuh build ulang cepat / cache layer?ya → Dockerfile atau Railpacktidak → lanjut
Ingin nol konfigurasi dan cache antar deploy (di host, bukan server remote)?ya → Railpacktidak → lanjut
Ingin nol konfigurasi, terima build lambat tiap kali?ya → Nixpackstidak → Dockerfile
DockerfileNixpacksRailpackSitus statis
SetupTulis Dockerfile sendiriNol konfigurasiNol konfigurasiPerintah build + folder output
Build ulangCache layer DockerSelalu dari awal (--no-cache)Cache BuildKit antar deploySelalu dari awal
Build pertamaTergantung base imageLambat: base ± 350 MB + nix-env284 detik (helper + BuildKit sekali)Cepat: node alpine + nginx alpine
Build berikutnyaCepat bila layer tak berubahTetap lambat, unduh ulang dependensi±8 detik — dependensi dari cacheSelalu dari awal
Kontrol imagePenuhTerbatas ke opsi nixpacksTerbatas ke opsi railpackTidak ada — nginx :80
Server remoteYaYaTidak — host sajaYa
Cocok untukProduksi, image rampingPrototipe, repo tanpa DockerfileDeploy berulang tanpa DockerfileSPA, landing page, dokumentasi

Dockerfile

Pilih Cara build → Dockerfile dan isi Dockerfile di repo (default Dockerfile di root). Build dijalankan daemon Docker langsung dari URL Git (POST /build?remote=…) — daemon yang meng-clone, API tidak butuh git.

Contoh minimal (Node.js)
FROM node:22-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "server.js"]
  • Builder klasik, bukan BuildKit: sintaks RUN --mount, COPY --link, dan heredoc tidak didukung.
  • Layer cache berlaku antar build selama base image dan langkah awal tidak berubah — letakkan COPY package*.json + npm ci sebelum COPY . ..
  • Sertakan wget atau curl di image bila memakai health check (alpine punya wget bawaan busybox).

Nixpacks

Pilih Cara build → Nixpacks untuk repo tanpa Dockerfile. Tidak ada binary nixpacks di host maupun di image API — semuanya berjalan di container:

  1. 01helperimage aoox-nixpacks dibangun sekali (debian + git + nixpacks CLI)
  2. 02clonecontainer sekali-jalan git clone --depth 1 (kredensial tidak keluar dari helper)
  3. 03plannixpacks build → menulis .nixpacks/Dockerfile
  4. 04buildsource di-tar → POST /build dengan Dockerfile hasil generate
Konsekuensi yang perlu diketahui
  • Build pertama lambat: base image nixpacks (± 350 MB) di-pull dan helper image dibangun sekali; versi nixpacks dipin oleh aoox.
  • Tidak ada cache dependensi antar build — --no-cache wajib karena cache mount nixpacks butuh BuildKit. Setiap deploy mengunduh ulang dependensi.
  • Source tree ditahan di memori API selama build (tanpa .git) — repo yang sangat besar sebaiknya memakai Dockerfile.

Mengarahkan Nixpacks

Nixpacks membaca variabel NIXPACKS_*. Isi lewat Build args:

Build args
NIXPACKS_NODE_VERSION=22
NIXPACKS_BUILD_CMD=npm run build
NIXPACKS_START_CMD=node server.js

Alternatif: taruh nixpacks.toml di repo — dibaca otomatis saat plan.

Railpack

Pilih Cara build → Railpack untuk repo tanpa Dockerfile yang di-deploy berulang kali dan ingin cache dependensi tetap ada. Berbeda dari Nixpacks, Railpack mengeksekusi build plan-nya lewat container moby/buildkit yang hidup terus dengan volume sendiri — layer dependensi bertahan antar deploy.

  1. 01helperimage aoox-railpack dibangun sekali (docker CLI + git + binary railpack)
  2. 02buildkitcontainer aoox-buildkit (moby/buildkit) dinyalakan sekali, volume cache sendiri
  3. 03clonehelper git clone --depth 1, lalu railpack build --cache-key <project>/<app>
  4. 04cachelayer dependensi tersimpan di volume BuildKit — deploy berikutnya memakainya lagi
Hanya di host
Railpack menjalankan BuildKit di sebelah registry di host aoox sendiri — belum ada BuildKit per server remote. Aplikasi dengan server remote harus memakai Dockerfile atau Nixpacks.
  • Image hasil Railpack mendengarkan di $PORT (konvensi Railway). aoox otomatis mengisi PORT dengan container port yang dikonfigurasi, kecuali aplikasi sudah men-set PORT sendiri di env.
  • Build args diteruskan sebagai --env ke railpack — sama seperti Nixpacks, ikut memengaruhi hasil deteksi provider-nya.
  • Cache di-scope per project/aplikasi, jadi aplikasi lain tidak berbagi layer secara tidak sengaja. Volume BuildKit dipangkas otomatis oleh maintenance malam — prune bawaan Docker tidak menjangkaunya.

Situs statis (nginx)

Pilih Cara build → Situs statis (nginx) untuk repo yang hasil akhirnya hanya file statis. aoox membuat Dockerfile dua tahap: (opsional) tahap build di node:22-alpine, lalu nginx:1.27-alpine yang melayani folder output di port 80.

FieldKeterangan
Perintah buildMis. npm ci && npm run build. Kosongkan bila file sudah ada di repo (tanpa tahap Node).
Folder outputRelatif dari root repo: dist (default), build, out, atau . untuk seluruh repo.
Mode SPAAktif (default): path tak dikenal dilayani index.html (client-side routing). Nonaktif: 404 biasa untuk situs multi-halaman.
Dockerfile yang dihasilkan (ilustrasi)
FROM node:22-alpine AS build
WORKDIR /src
COPY . .
RUN npm ci && npm run build

FROM nginx:1.27-alpine
COPY --from=build /src/dist/ /usr/share/nginx/html/
COPY .aoox/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
  • Port container harus 80. Health check path / cukup (nginx alpine punya wget).
  • Build berjalan lewat helper yang sama dengan Nixpacks (clone di container, konteks tar) — repo privat aman, tapi tanpa cache antar build.
  • Env runtime tidak berguna untuk file statis, dan Build args belum diteruskan ke tahap build statis. Nilai saat build (mis. VITE_API_URL) untuk sementara ditaruh di repo (.env.production) atau di perintah build: VITE_API_URL=https://api.example.com npm run build.
  • Versi Node dipin ke 22 oleh aoox; belum bisa diubah dari UI.

Build args

Field Build args (tab Pengaturan) berformat KEY=VALUE per baris dan diteruskan sebagai --build-arg. Untuk Nixpacks dan Railpack nilainya juga menjadi env saat plan/build. Belum berlaku untuk situs statis.

Dockerfile yang memakainya
ARG NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
RUN npm run build
Build args tidak mendukung referensi ${{…}} dan ikut tersimpan di image yang di-push. Jangan taruh rahasia di sini — pakai environment variables yang diterapkan saat runtime.

Image yang dihasilkan

<registry.url>/<project-slug>/<app-slug>:<12 karakter id deployment>
# contoh: localhost:5000/toko/shop:a1b2c3d4e5f6
  • Tag lama tetap ada di registry sampai dihapus di halaman Registry — itulah yang memungkinkan rollback. Hapus + garbage collect untuk mengembalikan disk.
  • Di server remote image tidak di-push; tersimpan di daemon server itu dengan ref aoox/<project>/<app>:<tag>.

Jebakan umum

GejalaPenyebab & solusi
Build gagal: unknown flag / --mountSintaks BuildKit di Dockerfile. Ganti dengan langkah biasa.
Nixpacks: build menggantungTidak seharusnya terjadi — aoox memaksa --no-cache. Cek log helper di tab Deploy.
Nixpacks memilih versi Node/Python yang salahSet NIXPACKS_NODE_VERSION / NIXPACKS_PYTHON_VERSION di Build args, atau engines di package.json.
Env kosong saat buildEnv memang tidak tersedia di tahap build. Pakai Build args (non-rahasia) atau baca env saat runtime.
Railpack: "run on the aoox host only"Aplikasi ini punya server remote. Pindahkan ke Dockerfile/Nixpacks, atau hapus penempatan server-nya.
Railpack: aplikasi tidak menerima koneksiCek aplikasi membaca process.env.PORT, bukan port tertulis. aoox mengisinya otomatis dari container port.

Langkah berikutnya

Ada yang keliru? Edit halaman ini di GitLab ↗