feat: provisioner podman + podman-compose + Cockpit untuk Fedora server
This commit is contained in:
commit
0147dad533
3 files changed
+249
No files matched your search
@@ -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.
|
||||||
@@ -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://<ip>: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://<ip-vps>: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).
|
||||||
Executable
+143
@@ -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:-<ip-vps>}: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
|
||||||
Reference in new issue
Block a user