From 0147dad533064277136e6d0e8989958f5ce150f7 Mon Sep 17 00:00:00 2001 From: oxpoe Date: Sat, 17 Oct 2026 04:32:49 +0700 Subject: [PATCH] feat: provisioner podman + podman-compose + Cockpit untuk Fedora server --- LICENSE | 21 ++++++++ README.md | 85 +++++++++++++++++++++++++++++++ install.sh | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 249 insertions(+) create mode 100644 LICENSE create mode 100644 README.md create mode 100755 install.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6da4880 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 oxpoe + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..5c9bc89 --- /dev/null +++ b/README.md @@ -0,0 +1,85 @@ +# fedora-server + +Provisioner **Fedora** untuk menjadikan VPS langsung siap sebagai **server container**: +[Podman](https://podman.io) + `podman-compose` + **Cockpit** (`cockpit-podman`) + pendukung. + +Satu perintah: + +```bash +curl -fsSL https://gitea.oxpoe.qzz.io/oxpoe/fedora-server/raw/branch/main/install.sh | sudo bash +``` + +## Yang dipasang + +| Kategori | Paket | +|---|---| +| Container engine | `podman`, `podman-compose`, `buildah`, `skopeo` | +| Manajemen web | `cockpit`, `cockpit-podman`, `cockpit-storaged`, `cockpit-networkmanager` | +| Util | `git`, `jq` | +| SELinux tooling | `policycoreutils-python-utils` | + +Service yang diaktifkan: +- `podman.socket` — API socket (untuk Cockpit/klien remote). +- `podman-restart.service` — **container ber-`restart:` policy naik otomatis saat boot**. +- `cockpit.socket` — web UI di `https://:9090`. + +## Opsi + +```bash +install.sh [opsi] + +--update jalankan `dnf upgrade` dulu (default: tidak) +--with-docker-shim pasang podman-docker (perintah `docker` -> podman) +--with-tui pasang podman-tui (TUI di terminal) +--no-cockpit tanpa Cockpit (podman saja) +--admin-user NAME buat user (grup wheel) untuk login Cockpit +--uninstall lepas paket & service yang dipasang skrip ini +``` + +Contoh: + +```bash +# podman saja, tanpa Cockpit +curl -fsSL .../install.sh | sudo bash -s -- --no-cockpit + +# lengkap + shim docker + user admin +curl -fsSL .../install.sh | sudo bash -s -- --with-docker-shim --admin-user admin +``` + +Skrip **idempotent** — aman dijalankan ulang. + +## Setelah selesai + +```bash +podman run --rm docker.io/alpine echo "podman jalan" +podman compose up -d # di folder berisi compose.yaml +``` + +**Cockpit**: buka `https://:9090`, login pakai user Linux + password. +> Cloud image biasanya *key-only* (root tanpa password) → buat user dulu: +> `useradd -m admin && passwd admin`, lalu login `admin`. + +## Catatan penting + +- **Rootful** secara default (paling cocok untuk server & VPN/tun/host-network). Untuk + rootless, buat user non-root (subuid/subgid dibuat otomatis di Fedora) dan pakai + `systemctl --user enable podman-restart.service`. +- **SELinux** (kalau `Enforcing`): bind mount ke path host butuh relabel — tambahkan + `:z` (shared) atau `:Z` (private) di compose/volume, cth `- ./data:/data:Z`. + Tanpa itu bisa muncul "Permission denied" padahal file ada. +- **Autostart container** mengandalkan `podman-restart.service` (sudah di-enable). Urutan + antar-service tidak dijamin; untuk itu pakai **Quadlet**. +- **firewalld**: kalau aktif, service `cockpit` dibuka otomatis. Podman mengatur aturan + port container-nya sendiri via integrasi firewalld. + +## Uninstall + +```bash +curl -fsSL .../install.sh | sudo bash -s -- --uninstall +``` + +`podman` dan data container (`/var/lib/containers`) tidak dihapus otomatis. + +## Lisensi + +MIT — lihat [LICENSE](LICENSE). diff --git a/install.sh b/install.sh new file mode 100755 index 0000000..234ac92 --- /dev/null +++ b/install.sh @@ -0,0 +1,143 @@ +#!/usr/bin/env bash +# +# fedora-server — provisioner Fedora untuk server container: +# podman + podman-compose + Cockpit (cockpit-podman) + pendukung. +# +# Pakai: +# curl -fsSL https://gitea.oxpoe.qzz.io/oxpoe/fedora-server/raw/branch/main/install.sh | sudo bash +# +# Opsi: +# --update jalankan `dnf upgrade` dulu (default: tidak) +# --with-docker-shim pasang podman-docker (perintah `docker` -> podman) +# --with-tui pasang podman-tui (TUI di terminal) +# --no-cockpit tanpa Cockpit (podman saja) +# --admin-user NAME buat user (grup wheel) untuk login ke Cockpit +# --uninstall lepas paket & service yang dipasang skrip ini +# -h, --help bantuan ini +# +# Idempotent: aman dijalankan berulang. + +set -euo pipefail + +BLUE='\033[1;34m'; YEL='\033[1;33m'; RED='\033[1;31m'; GRN='\033[1;32m'; NC='\033[0m' +log() { printf "${BLUE}==>${NC} %s\n" "$*"; } +ok() { printf "${GRN} +${NC} %s\n" "$*"; } +warn() { printf "${YEL} !${NC} %s\n" "$*"; } +die() { printf "${RED} x${NC} %s\n" "$*" >&2; exit 1; } + +UPDATE=0 WITH_DOCKER=0 WITH_TUI=0 WITH_COCKPIT=1 ADMIN_USER="" UNINSTALL=0 +while [ $# -gt 0 ]; do + case "$1" in + --update) UPDATE=1 ;; + --with-docker-shim) WITH_DOCKER=1 ;; + --with-tui) WITH_TUI=1 ;; + --no-cockpit) WITH_COCKPIT=0 ;; + --admin-user) shift; ADMIN_USER="${1:?--admin-user butuh nama}";; + --uninstall) UNINSTALL=1 ;; + -h|--help) sed -n '2,18p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;; + *) die "opsi tak dikenal: $1" ;; + esac + shift +done + +[ "${EUID:-$(id -u)}" -eq 0 ] || die "Jalankan sebagai root: ... | sudo bash" +command -v dnf >/dev/null 2>&1 || die "Ini bukan sistem berbasis dnf (Fedora/RHEL)." + +CORE=(podman podman-compose buildah skopeo git jq) +COCKPIT=(cockpit cockpit-podman cockpit-storaged cockpit-networkmanager) +SELTOOLS=(policycoreutils-python-utils) + +# ---------------------------------------------------------------- uninstall +if [ "$UNINSTALL" = 1 ]; then + log "Melepas service" + systemctl disable --now cockpit.socket 2>/dev/null || true + systemctl disable --now podman.socket 2>/dev/null || true + systemctl disable podman-restart.service 2>/dev/null || true + + log "Menghapus paket yang dipasang skrip ini" + dnf remove -y "${COCKPIT[@]}" podman-tui podman-docker buildah skopeo "${SELTOOLS[@]}" 2>/dev/null || true + + warn "podman & data container TIDAK dihapus otomatis." + warn "Kalau mau benar-benar bersih: dnf remove -y podman && rm -rf /var/lib/containers" + ok "Selesai." + exit 0 +fi + +# ---------------------------------------------------------------- update +if [ "$UPDATE" = 1 ]; then + log "Update paket (dnf upgrade)" + dnf upgrade -y --refresh +fi + +# ---------------------------------------------------------------- install +log "Memasang inti: podman + podman-compose + buildah/skopeo" +dnf install -y "${CORE[@]}" + +log "Memasang alat SELinux (troubleshooting :z/:Z)" +dnf install -y "${SELTOOLS[@]}" || warn "policycoreutils-python-utils gagal (lanjut)" + +if [ "$WITH_COCKPIT" = 1 ]; then + log "Memasang Cockpit (podman, storage, network)" + dnf install -y "${COCKPIT[@]}" || { warn "modul Cockpit sebagian gagal, coba versi minimal"; dnf install -y cockpit cockpit-podman; } +fi + +if [ "$WITH_DOCKER" = 1 ]; then + log "Memasang shim podman-docker (perintah 'docker' -> podman)" + dnf install -y podman-docker +fi + +if [ "$WITH_TUI" = 1 ]; then + log "Memasang podman-tui" + dnf install -y podman-tui +fi + +# ---------------------------------------------------------------- services +log "Mengaktifkan service" +systemctl enable --now podman.socket +systemctl enable podman-restart.service # container ber-restart policy naik saat boot +if [ "$WITH_COCKPIT" = 1 ]; then + systemctl enable --now cockpit.socket +fi + +if systemctl is-active --quiet firewalld; then + log "Firewall: buka Cockpit" + firewall-cmd --permanent --add-service=cockpit >/dev/null + firewall-cmd --reload >/dev/null + ok "firewalld: service 'cockpit' dibuka" +else + warn "firewalld tidak aktif — dilewati (perlu dibuka manual bila nanti diaktifkan)" +fi + +# ---------------------------------------------------------------- admin user +if [ -n "$ADMIN_USER" ]; then + log "Menyiapkan user admin untuk Cockpit: $ADMIN_USER" + id "$ADMIN_USER" >/dev/null 2>&1 || useradd -m "$ADMIN_USER" + usermod -aG wheel "$ADMIN_USER" + warn "Set password untuk $ADMIN_USER (dipakai login Cockpit):" + passwd "$ADMIN_USER" || warn "gagal set password — jalankan manual: passwd $ADMIN_USER" +fi + +# ---------------------------------------------------------------- ringkasan +IP="$(hostname -I 2>/dev/null | awk '{print $1}')" +VER_PODMAN="$(rpm -q --qf '%{VERSION}' podman 2>/dev/null || echo '-')" +VER_PCOMPOSE="$(rpm -q --qf '%{VERSION}' podman-compose 2>/dev/null || echo '-')" + +printf '\n%s\n' "$(printf "${GRN}==>${NC} Selesai. Fedora siap jadi server container.")" +printf ' %-18s %s\n' "podman" "$VER_PODMAN" +printf ' %-18s %s\n' "podman-compose" "$VER_PCOMPOSE" +printf ' %-18s %s\n' "podman.socket" "$(systemctl is-enabled podman.socket 2>/dev/null || echo off)" +printf ' %-18s %s\n' "podman-restart" "$(systemctl is-enabled podman-restart.service 2>/dev/null || echo off)" + +if [ "$WITH_COCKPIT" = 1 ]; then + printf ' %-18s %s\n' "Cockpit" "https://${IP:-}:9090" + warn "Cockpit butuh login user + PASSWORD. Cloud image sering key-only (belum ada)." + warn "Kalau belum ada user berpassword: useradd -m admin && passwd admin (login pakai 'admin')" +fi + +cat <<'EOF' + + Coba cepat: + podman run --rm docker.io/alpine echo "podman jalan" + Jalankan stack compose: + cd /path/berisi/compose.yaml && podman compose up -d +EOF