Ringkasan infrastruktur DevOps server bitbox.id (podman, zitadel, forgejo, mail server)
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-11 13:58:11 +07:00
infra feat: diagram topologi volume Podman + install.sh (deploy otomatis + suntik secret dari .env) 2026-10-11 13:55:12 +07:00
.env.example feat(infra): tambah config asli server (systemd quadlet, Caddyfile, Stalwart config) dengan rahasia disensor + .env.example lengkap 2026-10-11 13:50:57 +07:00
.gitignore docs: tambah .env.example (placeholder non-produksi), diagram sekuens SSO, backup/restore, .gitignore 2026-10-11 13:45:38 +07:00
install.sh feat: diagram topologi volume Podman + install.sh (deploy otomatis + suntik secret dari .env) 2026-10-11 13:55:12 +07:00
README.md docs: TODO.md gap-analysis vs DevOps profesional (23 issue + label) 2026-10-11 13:58:11 +07:00
TODO.md docs: TODO.md gap-analysis vs DevOps profesional (23 issue + label) 2026-10-11 13:58:11 +07:00

Infrastruktur DevOps — bitbox.id

Ringkasan (rangkuman) infrastruktur DevOps yang menjalankan layanan Bitbox: reverse proxy, identitas (IAM), Git hosting, dan mail server. Semua layanan berjalan sebagai container Podman di dalam satu VM Proxmox.

⚠️ Catatan: seluruh kredensial (password, master key, secret, token, OAuth client secret) disunting/redacted dalam dokumen ini. Dokumen ini untuk dokumentasi arsitektur, bukan untuk menyimpan rahasia.


1. Ringkasan

Aspek Nilai
Host fisik Proxmox VE (cluster Prox-P1337-A/B/D)
Node Prox-P1337-B
VM 1030 — nama dev.bitbox.id
OS VM Debian GNU/Linux 13 (trixie), kernel 6.12
Spesifikasi VM 4 vCPU · 8 GB RAM · 60 GB disk
IP publik 103.176.77.13/29 (gw 103.176.77.9)
Container runtime Podman 5.4.2 (rootful)
Orkestrasi systemd Quadlet (/etc/containers/systemd/*.container)
Jaringan container Podman network bitbox — 10.89.0.0/24
Reverse proxy / TLS Caddy 2.11.7 + auto-HTTPS Let's Encrypt
IAM / SSO Zitadel v4.19.4
Git hosting Forgejo 16.0.5
Mail server Stalwart v0.16.25 + Bulwark Webmail 1.13.0
Database PostgreSQL 17.11 (khusus Zitadel)

2. Arsitektur Keseluruhan

graph TB
    Internet([Internet])

    subgraph PVE["Proxmox VE — node Prox-P1337-B"]
        subgraph VM["VM 1030 · dev.bitbox.id · Debian 13"]
            subgraph Net["podman network: bitbox (10.89.0.0/24)"]
                Caddy["caddy<br/>:80 :443"]
                Forgejo["forgejo<br/>:2222 :3000"]
                ZitadelAPI["zitadel-api<br/>:8080"]
                ZitadelLogin["zitadel-login<br/>:3000"]
                Stalwart["stalwart<br/>:25 :465 :587 :993 :995 :4190 :8080"]
                Bulwark["bulwark<br/>:3000"]
                Postgres[("postgres<br/>:5432")]
            end
        end
    end

    Internet -->|80/443| Caddy
    Internet -->|25/465/587/993/995/4190| Stalwart
    Internet -->|2222| Forgejo

    Caddy --> Forgejo
    Caddy --> ZitadelLogin
    Caddy --> ZitadelAPI
    Caddy --> Stalwart
    Caddy --> Bulwark

    ZitadelAPI --> Postgres
    ZitadelLogin --> ZitadelAPI
    Bulwark -->|OIDC| ZitadelAPI
    Forgejo -->|OIDC SSO| ZitadelAPI

Poin penting:

  • Hanya Caddy (80/443), Stalwart (port mail), dan Forgejo (SSH 2222) yang mengekspos port ke host/publik.
  • Container lain (zitadel-api, zitadel-login, bulwark, postgres) hanya bisa diakses internal lewat network bitbox.
  • Semua service dijalankan otomatis oleh systemd melalui Quadlet (.container → unit systemd saat boot).

3. Alur Request (Routing Caddy)

flowchart LR
    U([Pengguna / Browser]) -->|HTTPS :443| C{{Caddy}}
    U -->|SMTP/IMAP :25/465/587/993| S[stalwart]

    C -->|auth.bitbox.id<br/>/ & /ui/v2/login| ZL[zitadel-login :3000]
    C -->|auth.bitbox.id<br/>/api, /oidc, /oauth| ZA[zitadel-api :8080]
    C -->|dev.bitbox.id| F[forgejo :3000]
    C -->|mail/imap/smtp/autodiscover<br/>/jmap, /.well-known/jmap| S[stalwart :8080]
    C -->|mail.bitbox.id webmail| B[bulwark :3000]
    C -->|mailops.bitbox.id admin| S

    ZA <-->|SQL| PG[(postgres :5432)]
    B -->|Login SSO OIDC| ZA
    F -->|Login SSO OIDC| ZA

Domain & virtual host

Domain Diarahkan ke Fungsi
auth.bitbox.id zitadel-login + zitadel-api Login SSO / IAM (UI v2)
dev.bitbox.id forgejo Git hosting (web + API)
mail.bitbox.id, imap.bitbox.id, smtp.bitbox.id, autodiscover.bitbox.id bulwark (webmail) & stalwart (JMAP/autoconfig) Webmail + protokol mail
mailops.bitbox.id stalwart Panel admin Stalwart

3.1 Alur Login SSO (OIDC)

Forgejo dan Bulwark tidak punya login lokal — keduanya memakai Zitadel sebagai Identity Provider (Authorization Code Flow).

sequenceDiagram
    autonumber
    actor U as Pengguna
    participant B as Browser
    participant A as App (Forgejo / Bulwark)
    participant ZL as Zitadel Login (UI v2)
    participant ZA as Zitadel API

    U->>B: Buka https://dev.bitbox.id
    B->>A: GET /
    A-->>B: 302 redirect ke auth.bitbox.id (OIDC authorize)
    B->>ZA: GET /oauth/v2/authorize
    ZA-->>B: redirect ke /ui/v2/login
    B->>ZL: Halaman login Zitadel
    U->>ZL: Kredensial (+ MFA bila aktif)
    ZL->>ZA: Verifikasi & buat authRequest
    ZA-->>B: redirect balik ke App dengan ?code=...
    B->>A: GET /user/oauth2/zitadel/callback?code=...
    A->>ZA: POST /oauth/v2/token (tukar code)
    ZA-->>A: access_token + userinfo
    A-->>B: Buat sesi login, tampilkan dashboard

4. Podman & Quadlet

Runtime memakai Podman dengan pendekatan Quadlet: file unit di /etc/containers/systemd/ dikonversi menjadi service systemd secara otomatis.

/etc/containers/systemd/
├── bitbox.network              # network bridge "bitbox" (10.89.0.0/24)
├── bitbox-caddy.container
├── bitbox-forgejo.container
├── bitbox-postgres.container
├── bitbox-zitadel-api.container
├── bitbox-zitadel-login.container
├── bitbox-stalwart.container
└── bitbox-bulwark.container

Systemd unit yang aktif:

bitbox-network.service        (exited)  network dibuat
bitbox-postgres.service       running   PostgreSQL (DB Zitadel)
bitbox-caddy.service          running   Reverse proxy + TLS
bitbox-zitadel-api.service    running   Zitadel API
bitbox-zitadel-login.service  running   Zitadel Login UI v2
bitbox-forgejo.service        running   Forgejo
bitbox-stalwart.service       running   Mail server
bitbox-bulwark.service        running   Webmail

Mengelola service: systemctl status|restart bitbox-<nama> (bukan podman run manual).

📁 Salinan file konfigurasi asli (unit systemd/Quadlet, Caddyfile, config Stalwart) tersedia di folder infra/ — rahasia sudah disensor menjadi placeholder. Deploy otomatis dengan install.sh.


5. Daftar Container

Container Image Port host Volume Peran
caddy docker.io/library/caddy:2 80, 443/tcp, 443/udp bitbox_caddy-data, bitbox_caddy-config (+ /srv/bitbox/Caddyfile) Reverse proxy & TLS otomatis
postgres docker.io/library/postgres:17-alpine internal 5432 bitbox_pgdata Database Zitadel
zitadel-api ghcr.io/zitadel/zitadel:v4.19.4 internal 8080 bitbox_zitadel-bootstrap IAM / OIDC / OAuth2 API
zitadel-login ghcr.io/zitadel/zitadel-login:v4.19.4 internal 3000 bitbox_zitadel-bootstrap (ro) UI login Zitadel v2
forgejo code.forgejo.org/forgejo/forgejo:16 2222 (SSH), internal 3000 bitbox_forgejo-data Git hosting (web/API/SSH)
stalwart docker.io/stalwartlabs/stalwart:v0.16.25 25, 465, 587, 993, 995, 4190, internal 8080 bitbox_stalwart-data (+ /srv/bitbox/stalwart/etc) Mail server (SMTP/IMAP/POP3/JMAP/managesieve)
bulwark ghcr.io/bulwarkmail/webmail:1.13.0 internal 3000 bitbox_bulwark-{settings,config,state,telemetry} Webmail (login via Zitadel OIDC)

Volume Podman (data persisten):

bitbox_caddy-data          bitbox_zitadel-bootstrap
bitbox_caddy-config        bitbox_stalwart-data
bitbox_forgejo-data        bitbox_bulwark-settings
bitbox_pgdata              bitbox_bulwark-config
                           bitbox_bulwark-state
                           bitbox_bulwark-telemetry

6. Detail Layanan

6.1 Caddy — Reverse Proxy & TLS

  • Image caddy:2 (v2.11.7), config: /srv/bitbox/Caddyfile (mount read-only).
  • Sertifikat Let's Encrypt di-issue & diperbarui otomatis untuk semua vhost.
  • Menangani encode zstd gzip, HSTS/redirect HTTPS, dan routing per-domain (lihat §3).
  • Zitadel API diproksikan via h2c (HTTP/2 cleartext) ke zitadel-api:8080.

6.2 Zitadel — IAM / SSO

  • Dua container: zitadel-api (backend) dan zitadel-login (UI v2). Database: PostgreSQL.
  • Mode start-from-init (first-instance di-bootstrap otomatis: org, admin, service account, login client).
  • Login UI v2 aktif (ZITADEL_DEFAULTINSTANCE_FEATURES_LOGINV2_REQUIRED=true, base URI https://auth.bitbox.id/ui/v2/login/).
  • OIDC discovery: https://auth.bitbox.id/.well-known/openid-configuration.
  • Dipakai sebagai Identity Provider untuk Forgejo dan Bulwark (auto-registrasi user).

6.3 Forgejo — Git Hosting

  • Image forgejo:16 (v16.0.5+gitea-1.22.0), URL https://dev.bitbox.id/.
  • Git SSH di port 2222, dengan SSH server bawaan (START_SSH_SERVER=true).
  • Database internal SQLite (/data/gitea/gitea.db) — terpisah dari PostgreSQL Zitadel.
  • INSTALL_LOCK=true, registrasi mandiri dimatikan (DISABLE_REGISTRATION=true); user dibuat via SSO OAuth2 Zitadel.
  • Mendukung LFS (LFS_START_SERVER=true).

6.4 Mail Server — Stalwart + Bulwark

graph LR
    subgraph Mail["Layanan Mail bitbox.id"]
        MX["MX 10 mail.bitbox.id"] --> S["stalwart"]
        S -->|SMTP 25/587/465| Ext[(Internet)]
        S -->|IMAP 993 / POP3 995| Clients([Mail client])
        S -->|JMAP + Webmail| B["bulwark :3000"]
        Admin([Admin]) -->|mailops.bitbox.id| S
    end
    B -->|SSO OIDC| Z["zitadel (auth.bitbox.id)"]
  • Stalwart v0.16.25: server mail all-in-one (SMTP 25/465/587, IMAPS 993, POP3S 995, ManageSieve 4190, JMAP/admin 8080). Config & sertifikat di /srv/bitbox/stalwart/{etc,cert}.
  • Bulwark Webmail 1.13.0: webmail modern, login hanya via OIDC (OAUTH_ONLY=true ke https://auth.bitbox.id), berbicara ke Stalwart lewat JMAP.
  • DNS mail: MX 10 mail.bitbox.id; DMARC p=quarantine (adkim=s; aspf=s), laporan ke dmarc@bitbox.id.

6.5 PostgreSQL

  • postgres:17-alpine (PostgreSQL 17.11), database zitadel, healthcheck pg_isready.
  • Hanya melayani Zitadel; Forgejo memakai SQLite.

7. Port & Jaringan

Port terbuka di host (VM):

Port Protokol Dibelakang layar
22 TCP sshd (admin, key-only)
80, 443 TCP/UDP Caddy
25, 465, 587 TCP Stalwart (SMTP submission/relay)
993 TCP Stalwart (IMAPS)
995 TCP Stalwart (POP3S)
4190 TCP Stalwart (ManageSieve)
2222 TCP Forgejo (Git over SSH)

Port internal saja (tidak dipublikasikan): 5432 (postgres), 8080 (zitadel-api & stalwart admin), 3000 (forgejo, zitadel-login, bulwark).

Zona jaringan: VM di vmbr1700 Proxmox dengan IP publik 103.176.77.13/29; container saling terhubung di bridge Podman bitbox (10.89.0.0/24).


8. DNS & TLS

Nama Tipe Target
dev.bitbox.id A 103.176.77.13
auth.bitbox.id A 103.176.77.13
mail.bitbox.id A / MX 103.176.77.13 / prio 10
smtp.bitbox.id, imap.bitbox.id A 103.176.77.13
bitbox.id A 103.55.39.179
  • TLS: Let's Encrypt (Caddy), berlaku ±3 bulan, auto-renew.
  • DMARC: v=DMARC1; p=quarantine; adkim=s; aspf=s; rua=mailto:dmarc@bitbox.id; ruf=mailto:dmarc-fail@bitbox.id.

9. Data Persisten & Backup

  • Seluruh state disimpan di Podman volume (bitbox_*) dan dua bind-mount:
    • /srv/bitbox/Caddyfile (konfigurasi Caddy)
    • /srv/bitbox/stalwart/{etc,cert} (konfigurasi & sertifikat mail)
  • Backup penting: bitbox_pgdata (Zitadel), bitbox_forgejo-data (repo Git), bitbox_stalwart-data + stalwart/etc (mail), bitbox_caddy-data (sertifikat).

9.0 Topologi Volume

graph LR
    subgraph VOL["Podman Volume — data persisten"]
        V1[("bitbox_pgdata<br/>DB Zitadel")]
        V2[("bitbox_zitadel-bootstrap<br/>PAT & admin seed")]
        V3[("bitbox_forgejo-data<br/>repo Git + SQLite")]
        V4[("bitbox_stalwart-data<br/>mail + kredensial")]
        V5[("bitbox_caddy-data<br/>sertifikat TLS")]
        V6[("bitbox_caddy-config<br/>config runtime")]
        V7[("bitbox_bulwark-settings")]
        V8[("bitbox_bulwark-config")]
        V9[("bitbox_bulwark-state")]
        V10[("bitbox_bulwark-telemetry")]
    end

    subgraph BIND["Bind mount — file di host"]
        B1["/srv/bitbox/Caddyfile"]
        B2["/srv/bitbox/stalwart/etc"]
        B3["/srv/bitbox/stalwart/cert"]
    end

    PG["postgres"] --> V1
    ZA["zitadel-api"] --> V2
    ZL["zitadel-login"] -.ro.-> V2
    FJ["forgejo"] --> V3
    ST["stalwart"] --> V4
    ST --> B2
    ST -.ro.-> B3
    CA["caddy"] --> V5
    CA --> V6
    CA -.ro.-> B1
    BU["bulwark"] --> V7
    BU --> V8
    BU --> V9
    BU --> V10
Volume Dipakai oleh Isi Prioritas backup
bitbox_pgdata postgres Database Zitadel 🔴 Tinggi
bitbox_forgejo-data forgejo Repo Git, gitea.db, LFS 🔴 Tinggi
bitbox_stalwart-data stalwart Mail, akun, DKIM 🔴 Tinggi
bitbox_caddy-data caddy Sertifikat & akun ACME 🟡 Sedang
bitbox_caddy-config caddy Config runtime Caddy 🟡 Sedang
bitbox_zitadel-bootstrap zitadel-api/-login PAT & seed admin 🟡 Sedang
bitbox_bulwark-* (4) bulwark Settings, config, state, telemetry 🟢 Rendah

9.1 Backup

# 1) Dump database Zitadel (konsisten, tanpa mematikan service)
podman exec postgres pg_dump -U postgres zitadel | gzip > zitadel-$(date +%F).sql.gz

# 2) Backup Forgejo (database + repo + konfigurasi)
podman exec -u git forgejo forgejo dump -c /data/gitea/conf/app.ini -f /data/dump.zip

# 3) Arsipkan volume Podman (tar) + bind-mount
podman volume export bitbox_forgejo-data > forgejo-data.tar
podman volume export bitbox_stalwart-data > stalwart-data.tar
tar czf bitbox-config.tar.gz -C /srv bitbox/Caddyfile bitbox/stalwart/etc bitbox/.env

9.2 Restore

# 1) Pulihkan volume dari tar
podman volume create bitbox_forgejo-data
podman volume import bitbox_forgejo-data forgejo-data.tar

# 2) Pulihkan database
gunzip -c zitadel-2026-01-01.sql.gz | podman exec -i postgres psql -U postgres -d zitadel

# 3) Pulihkan konfigurasi & secret
tar xzf bitbox-config.tar.gz -C /srv

# 4) Mulai ulang seluruh stack
systemctl restart bitbox-postgres bitbox-zitadel-api bitbox-zitadel-login \
  bitbox-forgejo bitbox-stalwart bitbox-bulwark bitbox-caddy

Untuk lingkungan baru, salin .env.example → /srv/bitbox/.env lalu isi nilai asli sebelum menjalankan stack (lihat §10).


10. Catatan Keamanan

  • Registrasi publik dimatikan di Forgejo dan Zitadel; akun via SSO/invite.
  • SSH host: PasswordAuthentication no (hanya public key).
  • Secret disimpan di:
    • /srv/bitbox/.env (master key Zitadel, password Postgres, ACME email, admin Zitadel) — template tersedia di .env.example,
    • environment Quadlet tiap container,
    • dan di-redact pada dokumen ini.
  • Jangan commit .env asli. .env.example hanya berisi placeholder non-produksi.
  • Rekomendasi: rotasi kredensial yang pernah terekspos, dan simpan secret di manajer rahasia (mis. Podman secrets / SOPS / Vault), bukan langsung di file .container.

11. Roadmap & TODO

Analisis celah terhadap praktik DevOps profesional (HA, backup teruji, secret manager, observability, IaC/CI-CD, hardening) ada di:

  • 📋 TODO.md — daftar per prioritas (P0/P1/P2)
  • 🐞 Issues Forgejo — tiap item dengan label area/* & priority/*

Ringkasan gap utama:

Aspek Kondisi sekarang Target profesional
Availability 1 VM, semua layanan (SPOF) HA / pemisahan peran + failover
Backup belum otomatis/teruji 3-2-1 + uji restore + PITR
Secret inline & plaintext secret manager + rotasi
Observability tidak ada metrik + log + alert
Keamanan firewall/fail2ban belum default-deny + fail2ban/WAF
Rilis manual IaC + CI/CD + staging
Docs/Proses README saja runbook + RPO/RTO + review

Dokumen ini dihasilkan dari inspeksi langsung VM dev.bitbox.id (Proxmox VM 1030) melalui QEMU guest agent. Jangan mempublikasikan berkas ini bersama kredensial asli.