SSD Nodes Learn 🎉 VPS mulai $5.50/bln
Panduan Matt ConnorOleh Matt Connor

Menjalankan Ollama dengan Podman Rootless di VPS

Pelajari cara menjalankan Ollama tanpa root di VPS: pengguna khusus, lingering, Quadlet setelah reboot, label SELinux, dan port 11434 tertutup.

Menjalankan Ollama dalam Podman rootless pada VPS

Untuk menjalankan Ollama dalam Podman rootless pada server, lima hal harus terpenuhi. Panduan desktop dapat melewati beberapa hal tersebut. Pengguna nonprivileged khusus memiliki container. Lingering diaktifkan untuk pengguna tersebut agar container tetap berjalan setelah Anda logout. File Quadlet menyerahkan container kepada systemd agar container berjalan kembali setelah reboot. Direktori model memiliki label SELinux pada distribusi yang menerapkan SELinux. API hanya listen pada loopback, dan Anda mengaksesnya melalui tunnel SSH (secure shell).

Ollama adalah server untuk large language models (LLM). Ollama menyimpan bobot model di disk, memuatnya ke memory, dan menjawab request HTTP pada port 11434. Ollama tidak memiliki login, API key, atau akun pengguna, sehingga network adalah satu-satunya kontrol akses yang tersedia. Podman menjalankan container tanpa daemon dan tanpa root. Dengan demikian, apa pun yang keluar dari container pada awalnya berjalan sebagai pengguna nonprivileged biasa. Jika Anda ingin membaca perbandingan runtime terlebih dahulu, baca perbedaan Podman dan Docker pada VPS. Jika Anda ingin sepenuhnya melewati container, menginstal Ollama langsung pada VPS adalah cara yang lebih singkat.

SSD Nodes menyediakan Fedora di antara image-nya, dan Fedora menyertakan Podman serta SELinux (security-enhanced Linux) secara default. Setiap perintah di bawah ini berjalan pada distribusi apa pun yang menggunakan Podman 5 atau yang lebih baru.

Perubahan yang diperlukan pada versi untuk laptop di server

Fedora Magazine menerbitkan panduan yang jelas tentang stack ini pada 5 August 2026: Menjalankan Ollama secara lokal dengan Podman di Fedora Linux, oleh Yazan Monshed. Panduan tersebut cocok untuk satu jam pertama mempelajari tool ini. Namun, panduan itu ditujukan untuk laptop, dan empat pilihannya berperilaku berbeda pada mesin dengan alamat IP publik.

  • Container dijalankan dengan podman run -d biasa. Container yang dijalankan secara manual tidak akan berjalan kembali setelah reboot karena tidak ada konfigurasi yang memintanya untuk dijalankan.
  • Panduan tersebut menggunakan tag yang dapat berubah, ollama/ollama. Pada laptop, Anda akan mengetahui perubahan perilaku pada hari terjadinya perubahan tersebut. Pada server, tanda pertamanya dapat berupa script yang berhenti bekerja saat malam.
  • Port dipublikasikan dengan -p 11434:11434, yang mengikat semua interface. Di balik router rumah, port tersebut tidak dapat dijangkau dari Internet. Pada VPS, konfigurasi ini menjadi API inference publik tanpa password.
  • Container dijalankan sebagai user login Anda sendiri. Pada server, account yang memiliki container seharusnya tidak memiliki file atau resource lain, sehingga jika terjadi container breakout, akses tersebut hanya masuk ke home directory yang kosong.

Tidak satu pun pilihan tersebut keliru untuk mesin yang menjadi sasaran panduan itu. Setiap pilihan hanya perlu ditinjau kembali ketika server dapat dijangkau dari mana saja dan tidak ada orang yang duduk di depannya.

Buat pengguna tanpa hak istimewa dan periksa subuid

Rootless Podman memetakan ID pengguna internal container (UID) ke blok ID yang belum digunakan pada host. Blok tersebut dideklarasikan dalam /etc/subuid dan /etc/subgid. Tanpa blok ini, container rootless sama sekali tidak dapat dijalankan.

sudo dnf install -y podman        # or: sudo apt install -y podman
sudo useradd --create-home --shell /bin/bash --comment "Ollama container owner" ollama
sudo passwd --lock ollama
grep ollama /etc/subuid /etc/subgid

grep harus menampilkan dua baris, masing-masing dari satu file, dan setiap baris mencantumkan rentang yang terdiri dari 65536 ID:

/etc/subuid:ollama:100000:65536
/etc/subgid:ollama:100000:65536

Nomor awal Anda akan berbeda, dan itu tidak masalah. Jika grep tidak menampilkan apa pun, useradd belum mengalokasikan rentang, sehingga perintah podman pertama sebagai pengguna tersebut gagal dengan pesan berikut:

Error: cannot find UID/GID for user ollama: no subuid ranges found for user "ollama" in /etc/subuid

Tetapkan rentang yang tidak dimiliki pengguna lain, lalu beri tahu Podman bahwa pemetaan lamanya sudah tidak berlaku:

sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 ollama
sudo -iu ollama podman system migrate

Mengunci kata sandi berarti tidak ada pengguna yang dapat login langsung sebagai ollama. Anda mengakses akun tersebut dari pengguna admin dengan sudo -iu ollama.

Aktifkan lingering agar service tetap berjalan setelah logout

Instance systemd milik pengguna biasanya dimulai saat login dan dihentikan saat logout, dan /run/user/<uid> ikut dihapus. Semua container rootless milik pengguna tersebut berhenti pada saat yang sama. Lingering membuat instance pengguna tetap berjalan tanpa sesi yang terhubung.

sudo loginctl enable-linger ollama
loginctl show-user ollama --property=Linger

Perintah tersebut seharusnya menampilkan Linger=yes. Aktifkan lingering sebelum membuat unit, karena direktori yang diperlukan unit, /run/user/<uid>, hanya ada setelah lingering diaktifkan.

Ada satu langkah tambahan yang sering tidak diperhitungkan. sudo -iu ollama menyediakan shell, tetapi tidak menyediakan session bus, sehingga systemctl --user langsung gagal:

Failed to connect to bus: $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR not defined

systemd mencari user bus di $XDG_RUNTIME_DIR/bus, dan sudo -i tidak menetapkan variabel tersebut. Tetapkan variabel itu secara manual di setiap shell admin yang digunakan untuk mengelola service ini:

sudo -iu ollama
export XDG_RUNTIME_DIR=/run/user/$(id -u)
systemctl --user status

Lokasi blob model dan jumlah ruang disk yang perlu disiapkan

Ollama menulis bobot model ke /root/.ollama/models di dalam container. Kaitkan sebuah direktori dari home pengguna ke path tersebut agar file tersimpan di lokasi yang dapat Anda ukur: /home/ollama/ollama-data/models. Blob disimpan di models/blobs sebagai file berbasis alamat konten, sedangkan models/manifests berisi indeks kecil yang mencantumkan file tersebut. Jika Anda menggunakan volume bernama, seperti dalam tulisan Fedora Magazine, struktur yang sama berada di bawah /home/ollama/.local/share/containers/storage/volumes/<volume>/_data.

Tentukan kapasitas disk sebelum mengunduh apa pun. Ukuran unduhan yang dipublikasikan memberikan batas minimum.

ChartPublished download size per Ollama model tag, ollama.com/library, checked 13 August 2026
The data behind this chart
[
  {
    "label": "gemma3:4b",
    "download_gb": 3.3
  },
  {
    "label": "mistral:7b",
    "download_gb": 4.4
  },
  {
    "label": "qwen3:8b",
    "download_gb": 5.2
  },
  {
    "label": "gemma3:12b",
    "download_gb": 8.1
  },
  {
    "label": "qwen3:14b",
    "download_gb": 9.3
  },
  {
    "label": "gemma3:27b",
    "download_gb": 17
  },
  {
    "label": "qwen3:30b",
    "download_gb": 19
  }
]

Semua 7 baris merupakan angka yang dipublikasikan di ollama.com/library, bukan ukuran yang diukur langsung dari disk. Tag terkecil di sini, gemma3:4b, berukuran unduhan 3.3 GB. Tag terbesar, qwen3:30b, berukuran unduhan 19 GB. Image container itu sendiri menggunakan ruang tambahan dalam storage milik Podman, jadi periksa kedua angka tersebut bersama-sama menggunakan podman system df dan df -h /home. Model juga memerlukan RAM kira-kira sebesar ukuran filenya saat dimuat, ditambah ruang untuk context window. Karena itu, model berukuran 19 GB tidak akan berjalan pada VPS dengan RAM 16 GB.

Sematkan tag image, dan gunakan nama registry lengkap

sudo -iu ollama
export XDG_RUNTIME_DIR=/run/user/$(id -u)
mkdir -p ~/ollama-data ~/.config/containers/systemd
podman pull docker.io/ollama/ollama:0.32.9

Gunakan tag versi rilis, 0.32.9 per Agustus 2026, bukan latest. Tag yang disematkan memastikan restart pada 04:00 menggunakan binary yang sama dengan yang Anda uji. Dengan demikian, setiap perubahan perilaku berasal dari perubahan yang Anda buat. Docker Hub juga menerbitkan tag -rc dan -rocm untuk versi yang sama. Pilih tag biasa, kecuali Anda memiliki GPU AMD.

Tulis juga host registry. Di Fedora, short name dalam unit systemd tidak memiliki terminal untuk menampilkan prompt. Akibatnya, unit gagal dengan pesan berikut:

Error: short-name "ollama/ollama" did not resolve to an alias and no unqualified-search registries are defined

Menarik image secara manual terlebih dahulu bersifat opsional, tetapi berguna karena proses tersebut memindahkan unduhan berukuran beberapa gigabita ke luar batas waktu start unit.

Unit Quadlet yang tetap berjalan setelah reboot

Quadlet adalah generator systemd milik Podman. Anda menulis file .container, systemd mengubahnya menjadi service saat boot, dan podman generate systemd tidak lagi diperlukan. Simpan file ini sebagai /home/ollama/.config/containers/systemd/ollama.container, dengan pemilik pengguna ollama.

[Unit]
Description=Ollama API (rootless)
After=network-online.target
Wants=network-online.target

[Container]
Image=docker.io/ollama/ollama:0.32.9
ContainerName=ollama
PublishPort=127.0.0.1:11434:11434
Volume=/home/ollama/ollama-data:/root/.ollama:Z
Environment=OLLAMA_KEEP_ALIVE=30m
Environment=OLLAMA_MAX_LOADED_MODELS=1

[Service]
Restart=always
TimeoutStartSec=900

[Install]
WantedBy=default.target

Nama file menentukan nama service, sehingga ollama.container menjadi ollama.service.

systemctl --user daemon-reload
systemctl --user start ollama.service
systemctl --user status ollama.service

status seharusnya menampilkan active (running). Jangan jalankan systemctl --user enable ollama.service. Unit tersebut tidak ada sebagai file di disk, sehingga systemd menolaknya:

Failed to enable unit: Unit file /run/user/1001/systemd/generator/ollama.service is transient or generated.

Section [Install] sudah menangani tugas tersebut. Quadlet membuat link untuk menjalankan service saat boot selama daemon-reload. Karena itu, perintah tersebut wajib dijalankan. TimeoutStartSec=900 mencakup start pertama yang masih harus mengunduh image, karena durasi default 90 detik tidak cukup untuk unduhan berukuran dua gigabyte dan systemd akan menghentikan proses start dengan status gagal. OLLAMA_KEEP_ALIVE=30m menyimpan model di memori di antara permintaan, bukan membongkarnya setelah lima menit. Trade-off-nya dijelaskan dalam menjaga model Ollama tetap dimuat di memori. Jika ada istilah systemd di sini yang masih baru, cara kerja service dan timer systemd pada VPS menjelaskan unit tersebut.

Mengapa direktori model menghasilkan kesalahan izin ditolak dengan SELinux

Di Fedora, RHEL, Rocky, dan AlmaLinux, SELinux secara default berada dalam mode enforcing. Proses container berjalan dalam domain container_t, sedangkan direktori di home pengguna diberi label user_home_t. Kebijakan SELinux tidak mengizinkan keduanya berinteraksi, sehingga Ollama tidak dapat membuat struktur direktori model dan container berhenti. getenforce menampilkan Enforcing pada sistem ini, dan penolakan tersebut dicatat:

sudo ausearch -m avc -ts recent

Anda akan melihat baris yang mencantumkan domain dan label target:

avc:  denied  { write } for  pid=1842 comm="ollama" name="models" dev="vda1" ino=131077 scontext=system_u:system_r:container_t:s0:c214,c827 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=dir permlisted=0

:Z di akhir baris Volume= adalah perbaikannya. Perintah tersebut memberi label ulang pada direktori host menjadi container_file_t dan memberinya kategori MCS (multi-category security) privat yang hanya digunakan oleh container ini. Huruf kecil :z menggunakan label bersama, yang diperlukan jika dua container membaca direktori yang sama.

Perhatikan :Z karena perintah ini bersifat destruktif dan tidak menampilkan pesan. Pelabelan ulang dilakukan secara rekursif. Jika Anda mengarahkannya ke /home/ollama, setiap file di dalam direktori home tersebut akan diberi label ulang, sehingga akses ke kunci SSH pengguna itu rusak. Selalu berikan :Z subdirektori khusus yang tidak berisi file lain. Named volume tidak memerlukannya karena Podman memberi label yang benar saat membuatnya. Untuk penjelasan lebih luas, dasar-dasar SELinux untuk server menjelaskan context dan boolean. Ubuntu dan Debian menggunakan AppArmor, sehingga :Z tidak melakukan apa-apa di sana dan aman jika tetap dicantumkan dalam unit.

Tutup port 11434 dan akses API melalui SSH

PublishPort=127.0.0.1:11434:11434 mengikat sisi host ke loopback. Konfirmasikan:

ss -ltnp | grep 11434
curl http://127.0.0.1:11434

Output ss harus menampilkan 127.0.0.1:11434. 0.0.0.0:11434 atau *:11434 berarti port terbuka ke Internet, dan curl harus merespons Ollama is running.

Pastikan sisi yang Anda ikat sudah benar. Alamat dalam PublishPort adalah alamat host. Di dalam container, Ollama harus tetap mendengarkan pada semua interface, sesuai default image. Menetapkan Environment=OLLAMA_HOST=127.0.0.1 akan mengikat Ollama ke loopback milik container sendiri. Podman kemudian meneruskan trafik yang dipublikasikan ke alamat jaringan container, sehingga setiap permintaan ditolak, bahkan dari host.

Port 11434 yang terbuka menimbulkan dua risiko. Ollama tidak memiliki autentikasi. Siapa pun yang dapat menjangkau port tersebut dapat mencantumkan model Anda melalui /api/tags, menjalankan inference pada CPU dan kuota bandwidth Anda melalui /api/generate, mengunduh model baru ke disk, serta menghapus model yang ada. Kedua, HTTP biasa ke port jarak jauh mengirim prompt dan hasil inference dalam teks biasa. Setiap mesin di sepanjang jalur dapat membacanya. Kedua masalah ini hilang jika port tidak pernah keluar dari host.

Dari workstation, teruskan port melalui SSH:

ssh -N -L 11434:127.0.0.1:11434 you@vps.example.com

Sekarang http://127.0.0.1:11434 pada laptop Anda adalah Ollama milik server, di dalam enkripsi sesi SSH. Jika laptop Anda sudah menjalankan Ollama, binding lokal gagal dengan bind [127.0.0.1]:11434: Address already in use. Gunakan -L 11435:127.0.0.1:11434 dan arahkan client ke 11435.

Jika client browser memerlukannya, gunakan reverse proxy dengan kata sandi di depannya. Blok site Caddy terdiri dari empat baris, dan caddy hash-password mencetak hash bcrypt yang diperlukan:

ollama.example.com {
  basic_auth {
    you $2a$14$replace_with_the_generated_hash
  }
  reverse_proxy 127.0.0.1:11434
}

Caddy memperoleh sertifikat melalui TLS (transport layer security) secara mandiri, sehingga trafik terenkripsi. Uji client Anda terlebih dahulu. Banyak tool yang berkomunikasi dengan Ollama tidak memiliki kolom untuk header Authorization, dan akan gagal menggunakan basic auth dengan 401 Unauthorized kosong. SSH tunnel tidak memiliki masalah tersebut. Karena itu, SSH tunnel menjadi rekomendasi default di sini.

Tarik model dan periksa seluruh jalur

podman exec -it ollama ollama pull gemma3:4b
curl -s http://127.0.0.1:11434/api/tags
curl -s http://127.0.0.1:11434/api/generate -d '{"model":"gemma3:4b","prompt":"Reply with the single word: ready","stream":false}'
du -sh ~/ollama-data/models

/api/tags menghasilkan JSON yang mencantumkan gemma3:4b. /api/generate menghasilkan objek JSON dengan bidang response setelah jeda selama bobot model dimuat dari disk. du seharusnya melaporkan angka yang mendekati ukuran unduhan yang dipublikasikan. Selanjutnya, buktikan bagian yang menjadi fokus seluruh panduan ini:

sudo reboot
# reconnect, then:
sudo -iu ollama
export XDG_RUNTIME_DIR=/run/user/$(id -u)
systemctl --user is-active ollama.service

active berarti proses tetap berjalan; bagian [Install] dan daemon-reload semuanya telah berfungsi. inactive berarti salah satu dari ketiganya tidak tersedia.

Mode kegagalan dan string yang akan Anda lihat

Container hilang setelah reboot. Periksa loginctl show-user ollama --property=Linger terlebih dahulu, karena tanpa Linger=yes instance systemd milik pengguna tidak pernah dimulai saat boot. Jika lingering aktif, bagian [Install] tidak ada dalam file .container, atau Anda mengedit file tersebut tetapi tidak menjalankan systemctl --user daemon-reload.

Error: statfs /home/ollama/ollama-data: no such file or directory. Sumber bind mount harus sudah ada sebelum container dimulai. Podman tidak membuat direktori host untuk Anda. Jalankan mkdir -p ~/ollama-data sebagai pengguna ollama.

Start gagal setelah 90 seconds. journalctl --user -u ollama.service menampilkan Start operation timed out. Terminating. karena image masih dalam proses pull. Lakukan pull secara manual, atau pertahankan TimeoutStartSec=900.

Container dimulai lalu berhenti. podman logs ollama dan sudo ausearch -m avc -ts recent secara bersamaan menunjukkan apakah masalahnya adalah label SELinux. AVC yang menyebut container_t dan user_home_t berarti :Z tidak ada.

Request ditolak dari host. curl: (7) Failed to connect to 127.0.0.1 port 11434: Connection refused dengan service active biasanya berarti OLLAMA_HOST disetel ke alamat loopback di dalam container. Hapus baris tersebut.

Generation sangat lambat, atau container dihentikan. Tanpa GPU, inference berjalan pada CPU dan model berukuran besar memang lambat. Container yang berhenti di tengah request dengan signal: killed dalam log menunjukkan kernel out-of-memory killer, jadi pilih tag yang lebih kecil dari tabel di atas.

Memperbarui image yang dipatok

Pinning berarti pembaruan dilakukan secara sengaja, bukan terjadi tanpa kendali. Edit Image= di ollama.container, lalu muat ulang dan mulai ulang:

systemctl --user daemon-reload
systemctl --user restart ollama.service
podman exec ollama ollama --version

Model disimpan di bind mount, sehingga tetap utuh setelah image diganti. AutoUpdate=registry di bagian [Container] ditujukan bagi pengguna yang menjalankan tag yang dapat berubah. Perintah tersebut tidak berguna jika digunakan bersama tag versi tetap karena isi tag itu tidak pernah berubah. Cadangkan /home/ollama/ollama-data/models/manifests dan file .container, lalu abaikan blob: ukurannya besar, dan ollama pull akan mengambilnya lagi di mesin baru.

FAQ

Mengapa container Podman rootless saya berhenti saat saya logout?

Instance systemd pengguna dan direktori /run/user/<uid> miliknya dibongkar saat sesi terakhir pengguna tersebut berakhir, sehingga semua container rootless ikut berhenti. Jalankan sudo loginctl enable-linger ollama dan pastikan loginctl show-user ollama --property=Linger menampilkan Linger=yes. Aktifkan lingering sebelum membuat unit Quadlet, karena direktori runtime yang diperlukan unit hanya ada setelah lingering diaktifkan.

Apakah saya memerlukan label SELinux pada direktori model Ollama?

Di Fedora, RHEL, Rocky, dan AlmaLinux, ya, jika Anda melakukan bind mount pada direktori host. Container berjalan dalam domain container_t, sedangkan direktori di folder home berlabel user_home_t. Akibatnya, operasi tulis ditolak dan Ollama berhenti. Tambahkan :Z ke baris Volume= dan berikan subdirektori khusus, karena pelabelan ulang dilakukan secara rekursif dan mengarahkan :Z ke seluruh direktori home akan mengganggu akses kunci SSH pengguna tersebut. Named volume diberi label yang benar oleh Podman dan tidak memerlukan pengaturan tambahan.

Berapa banyak ruang disk yang diperlukan model Ollama?

Mulailah dari ukuran unduhan yang dipublikasikan di ollama.com/library. Ukurannya berkisar dari 3.3 GB untuk gemma3:4b hingga 19 GB untuk qwen3:30b. Tambahkan ukuran image Podman, lalu sisakan ruang cadangan, karena model kedua tidak menggantikan model pertama di disk. Periksa df -h /home sebelum melakukan pull dan du -sh ~/ollama-data/models sesudahnya. Rencanakan RAM dengan cara yang sama: model memerlukan memori kira-kira sebesar ukuran filenya saat dimuat, ditambah ukuran context window.

Apakah aman membuka port 11434 pada VPS?

Tidak. Ollama dirilis tanpa autentikasi apa pun, sehingga siapa pun yang dapat menjangkau port tersebut dapat mencantumkan model Anda, menghapusnya, mengunduh model baru ke disk, serta menjalankan inferensi menggunakan CPU dan kuota bandwidth Anda. HTTP biasa melalui Internet juga mengirim setiap prompt dan hasil completion dalam teks biasa. Bind sisi host ke 127.0.0.1 dengan PublishPort=127.0.0.1:11434:11434, konfirmasikan menggunakan ss -ltnp | grep 11434, lalu akses melalui SSH tunnel atau reverse proxy yang mewajibkan kata sandi.