SSD Nodes Learn Hosting plans →
Panduan Matt ConnorOleh Matt Connor · Diperbarui 2026-09-04

Menjalankan Ollama di Podman Rootless pada VPS

Panduan menjalankan Ollama sebagai container Podman rootless di VPS, dengan user khusus, lingering, Quadlet setelah reboot, label SELinux, dan port tertutup.

Menjalankan Ollama dalam Podman rootless pada VPS

Untuk menjalankan Ollama dalam Podman rootless pada server, lima hal harus terpenuhi yang dapat diabaikan dalam panduan desktop. Pengguna tanpa hak istimewa khusus memiliki container tersebut. Lingering diaktifkan untuk pengguna itu 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 mendengarkan 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 HTTP request pada port 11434. Ollama tidak memiliki login, API key, atau akun pengguna, sehingga jaringan menjadi satu-satunya kontrol akses yang tersedia. Podman menjalankan container tanpa daemon dan tanpa root, sehingga apa pun yang keluar dari container pada awalnya berjalan sebagai pengguna biasa tanpa hak istimewa. Jika Anda ingin membaca perbandingan runtime terlebih dahulu, baca perbedaan Podman dan Docker pada VPS. Jika Anda ingin melewati container sepenuhnya, menginstal Ollama langsung pada VPS adalah langkah yang lebih singkat.

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

Mengapa versi laptop memerlukan perubahan di server

Fedora Magazine menerbitkan panduan yang jelas tentang stack ini pada 5 Agustus 2026: Menjalankan Ollama Secara Lokal dengan Podman di Fedora Linux, oleh Yazan Monshed. Panduan itu cocok untuk satu jam pertama mempelajari alat-alat tersebut. 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 start.
  • Panduan tersebut menggunakan tag yang terus berubah, yaitu ollama/ollama. Pada laptop, Anda akan menyadari perubahan perilakunya pada hari perubahan itu terjadi. Di server, tanda pertama biasanya berupa script yang tiba-tiba berhenti bekerja pada malam sebelumnya.
  • Publikasi dilakukan dengan -p 11434:11434, yang mengikat semua interface. Di belakang router rumah, layanan tersebut tidak dapat dijangkau dari Internet. Di VPS, konfigurasi ini menjadi API inference publik tanpa password.
  • Container dijalankan sebagai user login Anda sendiri. Di server, account yang memiliki container seharusnya tidak memiliki resource lain, sehingga jika terjadi container breakout, penyerang masuk ke home directory yang kosong.

Tidak ada yang salah dengan pilihan tersebut untuk mesin yang menjadi sasaran panduan. 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, lalu periksa subuid

Rootless Podman memetakan ID pengguna internal (UID) container 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 dimulai.

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 seharusnya menampilkan dua baris, masing-masing dari satu file, dan setiap baris mencantumkan rentang 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, dan perintah podman pertama sebagai pengguna tersebut akan gagal seperti ini:

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

Tetapkan rentang yang tidak digunakan oleh 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 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. Setiap 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 harus menampilkan Linger=yes. Aktifkan lingering sebelum membuat unit, karena direktori yang diperlukan unit, /run/user/<uid>, hanya tersedia setelah lingering aktif.

Ada satu langkah lain yang sering tidak terduga. sudo -iu ollama memberikan shell, tetapi tidak memberikan 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 perencanaan kapasitas disk

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 memberi nama pada file tersebut. Jika Anda menggunakan named volume, seperti dalam artikel Fedora Magazine, tree yang sama berada di bawah /home/ollama/.local/share/containers/storage/volumes/<volume>/_data. Dalam kedua kasus, ollama pull dan ollama run menulis bobot ke tree yang sama. Perbedaan kedua perintah tersebut hanya terletak pada apakah sesi chat dibuka setelah proses download selesai.

Tentukan kapasitas disk sebelum mengunduh apa pun. Ukuran download 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
  }
]

Seluruh 7 baris adalah angka yang dipublikasikan di ollama.com/library, bukan ukuran yang diukur langsung dari disk. Tag terkecil di sini, gemma3:4b, memerlukan download sebesar 3.3 GB. Tag terbesar, qwen3:30b, memerlukan download sebesar 19 GB. Image container menggunakan ruang tambahan di storage milik Podman, jadi periksa kedua angka tersebut secara bersamaan dengan 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.

Tetapkan 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 yang telah dirilis, yaitu 0.32.9 per Agustus 2026, bukan latest. Tag yang ditetapkan memastikan restart pada pukul 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.

Tuliskan host registry juga. Di Fedora, nama pendek dalam unit systemd tidak memiliki terminal untuk menampilkan prompt. Akibatnya, unit gagal dengan pesan:

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

Menjalankan pull secara manual terlebih dahulu bersifat opsional, tetapi berguna karena proses tersebut memindahkan pengunduhan berukuran beberapa gigabyte ke luar batas waktu start unit.

Unit Quadlet yang tetap berfungsi setelah reboot

Quadlet adalah systemd generator milik Podman. Anda menulis file .container, lalu systemd mengubahnya menjadi service saat boot, sehingga podman generate systemd tidak lagi diperlukan. Simpan file ini sebagai /home/ollama/.config/containers/systemd/ollama.container dan tetapkan kepemilikannya kepada user 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.

Bagian [Install] sudah menjalankan tugas tersebut. Quadlet membuat link untuk menjalankan service saat boot selama daemon-reload. Karena itu, perintah tersebut wajib dijalankan. TimeoutStartSec=900 memberikan waktu yang cukup untuk proses start pertama yang masih harus mengunduh image. Nilai default 90 detik tidak cukup untuk mengunduh file berukuran dua gigabyte, sehingga systemd akan menghentikan proses start dan menandainya sebagai gagal. OLLAMA_KEEP_ALIVE=30m mempertahankan model di memory di antara request, bukan membongkarnya setelah lima menit. Trade-off-nya dijelaskan dalam mempertahankan model Ollama di memory. Jika ada istilah systemd di sini yang belum Anda kenal, cara kerja service dan timer systemd pada VPS menjelaskan unit tersebut.

Mengapa direktori model menghasilkan penolakan izin di 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 memiliki label user_home_t. Kebijakan SELinux tidak mengizinkan keduanya saling mengakses. Akibatnya, Ollama tidak dapat membuat struktur direktori model dan container berhenti. Pada sistem ini, getenforce menampilkan Enforcing, 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 menetapkan kategori MCS (multi-category security) privat yang hanya digunakan oleh container ini. Huruf kecil :z menggunakan label bersama. Gunakan opsi tersebut jika dua container perlu membaca direktori yang sama.

Perhatikan :Z karena perintah ini bersifat destruktif dan tidak menampilkan banyak informasi. Pelabelan ulang dilakukan secara rekursif. Jika diarahkan ke /home/ollama, setiap file di dalam direktori home tersebut akan diberi label ulang. Hal ini dapat menyebabkan akses ke kunci SSH pengguna tersebut gagal. Selalu berikan :Z subdirektori khusus yang tidak berisi file lain. Named volume tidak memerlukannya karena Podman memberi label yang benar saat membuat volume tersebut. Untuk penjelasan yang lebih luas, dasar-dasar SELinux untuk server menjelaskan context dan boolean. Ubuntu dan Debian menggunakan AppArmor. Di sana, :Z tidak melakukan apa pun, dan membiarkannya di dalam unit tidak menimbulkan masalah.

Tutup port 11434 dan akses API melalui SSH

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

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 Anda memahami sisi yang diikat. 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, termasuk permintaan 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 inferensi menggunakan CPU dan kuota bandwidth Anda melalui /api/generate, mengunduh model baru ke disk, serta menghapus model yang tersedia. Kedua, HTTP biasa ke port remote mengirimkan prompt dan hasil inferensi dalam teks biasa. Setiap mesin di sepanjang jalur dapat membacanya. Kedua masalah ini hilang jika port tidak pernah meninggalkan server.

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, pengikatan lokal gagal dengan bind [127.0.0.1]:11434: Address already in use. Gunakan -L 11435:127.0.0.1:11434 dan arahkan client Anda ke 11435.

Jika client browser memerlukannya, gunakan reverse proxy dengan kata sandi di depannya. Site block 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, sehingga akan gagal terhadap basic auth dengan 401 Unauthorized kosong. Tunnel SSH tidak memiliki masalah tersebut, sehingga menjadi rekomendasi default di sini.

Unduh 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 mengembalikan JSON yang mencantumkan gemma3:4b. /api/generate mengembalikan objek JSON dengan kolom response setelah jeda saat bobot 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 telah menjalankan fungsinya. inactive berarti salah satu dari ketiganya tidak ada.

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 ada sebelum container dimulai. Podman tidak membuat direktori host untuk Anda. Jalankan mkdir -p ~/ollama-data sebagai pengguna ollama.

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

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

Permintaan dari host ditolak. curl: (7) Failed to connect to 127.0.0.1 port 11434: Connection refused dengan service active biasanya berarti OLLAMA_HOST ditetapkan 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 permintaan dengan signal: killed dalam log menunjukkan kernel out-of-memory killer, jadi pilih tag yang lebih kecil dari chart 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 berada di bind mount, sehingga tetap utuh saat image diganti. AutoUpdate=registry di bagian [Container] ditujukan bagi pengguna yang menjalankan tag yang berubah, dan tidak berguna jika digunakan bersama tag versi tetap karena isi tag tersebut tidak pernah berubah. Cadangkan /home/ollama/ollama-data/models/manifests dan file .container, lalu lewati blob: ukurannya besar, dan ollama pull akan mengambilnya lagi di mesin baru.

FAQ

Mengapa container Podman rootless berhenti saat saya logout?

Instance systemd milik 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 tersedia setelah lingering aktif.

Apakah saya memerlukan label SELinux pada direktori model Ollama?

Di Fedora, RHEL, Rocky, dan AlmaLinux, ya, jika Anda melakukan bind mount direktori host. Container berjalan dalam domain container_t, sedangkan direktori di folder home memiliki label user_home_t, sehingga operasi tulis ditolak dan Ollama berhenti. Tambahkan :Z ke baris Volume= dan gunakan 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 download yang dipublikasikan di ollama.com/library, yang 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 mengekspos port 11434 pada VPS?

Tidak. Ollama tidak menyediakan autentikasi apa pun secara bawaan, sehingga siapa pun yang dapat mengakses port tersebut dapat mencantumkan model Anda, menghapusnya, melakukan pull model baru ke disk, serta menjalankan inference menggunakan CPU dan kuota bandwidth Anda. HTTP biasa melalui internet juga mengirim setiap prompt dan completion dalam teks biasa. Bind sisi host ke 127.0.0.1 menggunakan PublishPort=127.0.0.1:11434:11434, konfirmasikan dengan ss -ltnp | grep 11434, lalu akses melalui SSH tunnel atau reverse proxy yang mewajibkan password.