Deploy Multiple SvelteKit Projects with Caddy + Rootless Podman

Setup VPS modern tanpa Nginx dan PM2 menggunakan Caddy dan container rootless.

Deploy Multiple SvelteKit Projects with Caddy + Rootless Podman on Debian

Saya ingin setup VPS modern tanpa:

  • Nginx native
  • PM2
  • service rootful
  • /var/www
  • config tersebar di system

Akhirnya saya memilih:

  • Debian Minimal
  • Rootless Podman
  • Caddy Server
  • Multi-project deployment

Struktur Folder

Semua aplikasi saya simpan di:

/home/kravenian/apps

Struktur akhirnya seperti ini:

/home/kravenian/apps
├── caddy
│   ├── compose.yml
│   ├── conf
│   │   └── Caddyfile
│   ├── config
│   └── data
│
├── r3p.dev
│   ├── compose.yml
│   ├── Containerfile
│   └── source-code
│
└── skripsi.r3p.dev
    ├── compose.yml
    ├── Containerfile
    └── source-code

Kenapa Menggunakan Rootless Podman?

Karena:

  • container berjalan sebagai user biasa
  • tidak perlu daemon Docker
  • lebih aman
  • file tetap berada di home user
  • cocok untuk deployment pribadi

Semua container dijalankan oleh user:

kravenian

Bukan root.


Memahami Volume Mapping

Banyak yang bingung bagian ini:

volumes:
  - ./conf:/etc/caddy

Formatnya adalah:

HOST:CONTAINER

Artinya:

/home/kravenian/apps/caddy/conf
↓
/etc/caddy

Penting:

  • /etc/caddy di sini adalah filesystem DI DALAM container
  • bukan /etc/caddy milik VPS host

Jadi setup ini tetap rootless.


Setup Folder Caddy

Masuk ke folder:

cd ~/apps/caddy

Buat struktur:

mkdir -p conf
mkdir -p data
mkdir -p config

compose.yml untuk Caddy

File:

/home/kravenian/apps/caddy/compose.yml

Isi:

services:
  caddy:
    image: docker.io/library/caddy:latest
    container_name: caddy

    restart: unless-stopped

    ports:
      - '80:80'
      - '443:443'
      - '443:443/udp'

    volumes:
      - /home/kravenian/apps/caddy/conf:/etc/caddy
      - /home/kravenian/apps/caddy/data:/data
      - /home/kravenian/apps/caddy/config:/config

Kenapa 443 UDP?

Karena:

- '443:443/udp'

digunakan untuk:

  • HTTP/3
  • QUIC

HTTPS tetap bisa berjalan tanpa ini, tetapi HTTP/3 membutuhkan UDP.


Fungsi Folder data dan config

/data

Digunakan Caddy untuk:

  • SSL Let’s Encrypt
  • certificate
  • private key
  • ACME data

Harus persistent agar SSL tidak regenerate terus.

/config

Digunakan untuk:

  • cache internal
  • autosave config
  • state internal Caddy

Kenapa Tidak Menggunakan /srv?

Dokumentasi resmi Caddy biasanya punya:

- ./site:/srv

Ini digunakan untuk:

  • static HTML
  • file server biasa

Karena saya menggunakan:

  • SvelteKit
  • reverse proxy
  • Node server

maka /srv tidak diperlukan.


Isi Caddyfile

File:

/home/kravenian/apps/caddy/conf/Caddyfile

Isi:

r3p.dev {
    reverse_proxy r3p:3000
}

skripsi.r3p.dev {
    reverse_proxy skripsi:3000
}

Artinya:

  • domain r3p.dev diarahkan ke container r3p
  • domain skripsi.r3p.dev diarahkan ke container skripsi

Konsep Arsitektur

Internet
   │
   ▼
[Caddy]
   ├──► [r3p container]
   └──► [skripsi container]

Caddy menjadi gateway utama:

  • SSL
  • reverse proxy
  • HTTP/2
  • HTTP/3
  • automatic HTTPS

Apakah Setiap Project Memiliki Service Caddy?

Tidak.

Hanya ada SATU service Caddy.

Strukturnya:

~/apps/caddy

Project lain hanya memiliki service aplikasinya masing-masing.

Contoh:

r3p.dev

services:
  r3p:
    build: .

skripsi.r3p.dev

services:
  skripsi:
    build: .

Keuntungan Setup Ini

  • Rootless
  • Lebih aman
  • Tidak mengotori system path
  • Tidak perlu Nginx native
  • Tidak perlu PM2
  • SSL otomatis
  • Mudah CI/CD
  • Mudah backup
  • Multi-project friendly
  • Cocok untuk VPS pribadi

Menjalankan Caddy

cd ~/apps/caddy
podman compose up -d

Penutup

Awalnya saya bingung karena:

  • /etc/caddy
  • rootless
  • volume mapping
  • Podman networking

ternyata konsep pentingnya adalah:

KIRI  = path di HOST VPS
KANAN = path di DALAM CONTAINER

Setelah memahami itu, seluruh arsitektur container jadi jauh lebih mudah dipahami.

© 2026 r3p.dev. All rights reserved.