Commit a08f12e2 by Bambang Adrian

tags(v0.1): first commit

parents
🔥 Siap, berikut ini rencana **final changelog untuk `install-osrm-ngpm.sh v4.6`**, biar kamu tahu persis apa yang akan saya implementasikan sebelum saya keluarkan skrip lengkapnya:
---
## 🧩 **install-osrm-ngpm.sh v4.6 — Production Ready Edition**
### ⚙️ Core Enhancements
**Auto Lua Patch**
* Deteksi otomatis `arg[0]` atau variabel bermasalah di file profile `.lua`.
* Patch jadi aman (`local profile_name = "car"`).
* Berlaku untuk semua profile (`car`, `motorcycle`, `bicycle`, `foot`, dll).
**Sequential Routing Preparation**
* Preprocessing tetap jalan satu per satu untuk menghindari OOM/CPU spikes.
* Setelah preprocessing sukses → otomatis buat **`osrm-routed-*` service** di `docker-compose.yml`.
* Jika preprocess gagal → skip pembuatan service & tampilkan log merah `[FAILED]`.
**Docker Compose Update Logic**
* Template `docker-compose.yml` disusun modular.
* Section `services:` akan diupdate otomatis jika profil bertambah.
* Tambah opsi `--rebuild` untuk force-regenerate compose file (jika sudah ada lama).
**Improved Logging**
* Tambah notifikasi jelas:
```
[INFO] ✅ Preprocess success: car
[INFO] 🚀 Spawning routed service: osrm-routed-car (port: 5000)
```
* Tambah warning warna jika ada error Lua atau path permission issue.
---
### 🌐 **Frontend / NGPM Integration**
✅ Tidak auto-modify frontend config (tetap aman untuk multi-proxy)
✅ Menampilkan **Frontend & NGPM hints** di akhir proses:
```
────────────────────────────────────────────
🌐 Frontend Configuration Hints (for NGPM)
────────────────────────────────────────────
- Backend URL: https://route.geotency.com/osrm/v1/
- Profiles available: car, motorcycle
- Example endpoint: /osrm/v1/car/...
────────────────────────────────────────────
```
✅ Mendukung argument:
* `--domain` untuk menentukan domain base URL (misal `https://route.geotency.com`)
* `--backend-path` untuk menentukan path (misal `/osrm/v1`)
---
### 🧠 **Argumen Baru / Diperbaiki**
| Flag | Deskripsi | Default |
| --------------------- | ------------------------------------- | ------------------------------------------------------------ |
| `--profiles` | Daftar profil yang diinstall | `car` |
| `--profile-dir` | Direktori profil Lua | `~/data/docker-data/osrm/profiles` |
| `--map-dir` | Direktori file `.osm.pbf` | `~/data/docker-data/osrm/dataset` |
| `--map-source` | URL sumber peta untuk update otomatis | `http://download.geofabrik.de/asia/indonesia-latest.osm.pbf` |
| `--backend-version` | Versi OSRM backend | `latest` |
| `--frontend-version` | Versi OSRM frontend | `latest` |
| `--backend-registry` | Registry backend | `ghcr.io/project-osrm/osrm-backend` |
| `--frontend-registry` | Registry frontend | `ghcr.io/project-osrm/osrm-frontend` |
| `--backend-port` | Port backend utama | `5000` |
| `--frontend-port` | Port frontend (opsional) | `8080` |
| `--network` | Docker network | `ngpm-network` |
| `--work-dir` | Direktori kerja utama | `~/data/docker-data/osrm` |
| `--with-frontend` | Ikut deploy OSRM frontend | `false` |
| `--domain` | Domain base (untuk hint output) | *kosong* |
| `--backend-path` | Base path API | `/osrm/v1` |
| `--dry-run` | Simulasi tanpa eksekusi | `false` |
| `--update` | Update image, peta, dan profil | `false` |
| `--print-config` | Menampilkan konfigurasi saja | `false` |
---
### 🪄 **Auto-Fix for Common Issues**
* Fix permission issue saat preprocess (pakai tmp writable volume)
* Patch Lua `arg` nil
* Skip rebuild jika hasil `.osrm` sudah valid
* Auto-recreate Docker network jika belum ada
---
### 🧾 **Output Akhir**
```
2025-10-15 10:21:45 [SUCCESS] OSRM backend deployed for: car, motorcycle
2025-10-15 10:21:45 [SUCCESS] Docker Compose file: /home/sysadmin/data/docker-data/osrm/docker-compose.yml
────────────────────────────────────────────
🌐 Frontend Configuration Hints (for NGPM)
────────────────────────────────────────────
Backend: https://route.geotency.com/osrm/v1/
Profiles: car, motorcycle
Network: ngpm-network
────────────────────────────────────────────
💡 Test endpoint:
curl "https://route.geotency.com/osrm/v1/car/106.8,-6.2;106.9,-6.3"
────────────────────────────────────────────
```
# **Dokumentasi Setup Jupyter Lab dengan Conda/Mamba + Python 3.14 dan Bash Script Launcher**
## **1. Tujuan**
Dokumen ini menjelaskan cara:
1. Menyiapkan **Conda/Mamba** di Linux user space.
2. Membuat **environment Python 3.14** terisolasi.
3. Menginstall **Jupyter Lab**.
4. Menjalankan Jupyter Lab dari shell dengan **wrapper script**, mendukung default direktori dan port, serta opsi override.
5. Menghindari error permission yang umum terjadi pada installasi system-wide.
---
## **2. Prasyarat**
* Sistem operasi: Linux (Ubuntu, Rocky Linux, CentOS, Debian, dll.)
* User dengan akses shell (root tidak diperlukan jika menggunakan local cache).
* Miniconda/Anaconda sudah terinstall, misal di `$HOME/miniconda3` atau `/opt/miniconda`.
> Catatan: Jika Miniconda belum terinstall, bisa diunduh dari [Miniconda Downloads](https://docs.conda.io/en/latest/miniconda.html) dan install di user home.
---
## **3. Setup Mamba**
Mamba adalah versi Conda yang lebih cepat untuk installasi paket.
```bash
# Pastikan Conda update
conda update conda -y
# Install Mamba di environment base
conda install mamba -n base -c conda-forge -y
```
> **Tips:** Mamba otomatis akan menggunakan Conda environment base.
---
## **4. Membuat Environment Python 3.14**
Buat environment baru bernama `jupyterlab`:
```bash
# Gunakan folder cache lokal supaya tidak perlu root
export CONDA_PKGS_DIRS=$HOME/.conda/pkgs
# Buat environment Python 3.14
mamba create -n jupyterlab python=3.14 -y
# Aktifkan environment
conda activate jupyterlab
```
---
## **5. Install Jupyter Lab**
Install Jupyter Lab dalam environment `jupyterlab`:
```bash
mamba install -c conda-forge jupyterlab -y
```
Cek versi Python dan Jupyter Lab:
```bash
python --version
jupyter lab --version
```
---
## **6. Bash Script Launcher untuk Jupyter Lab**
### **6.1 Tujuan**
Script ini memudahkan menjalankan Jupyter Lab dari shell:
* Default direktori: direktori saat ini (`$PWD`)
* Default port: `8888`
* Bisa override dengan parameter `-d DIRPATH` dan `-p PORT`
### **6.2 Script: jupyterlab**
Simpan script di `~/bin/jupyterlab`:
```bash
#!/bin/bash
# File: ~/bin/jupyterlab
# Usage: jupyterlab -d /path/to/dir -p 9999
# --- Default values ---
DIR="$PWD"
PORT="8888"
# --- Parse arguments ---
while getopts "d:p:" opt; do
case $opt in
d) DIR="$OPTARG" ;;
p) PORT="$OPTARG" ;;
*) echo "Usage: $0 [-d directory] [-p port]" ; exit 1 ;;
esac
done
# --- Auto-detect conda path ---
CONDA_BIN=$(which conda)
if [ -z "$CONDA_BIN" ]; then
echo "Error: Conda not found in PATH."
exit 1
fi
# Extract Conda base path
CONDA_BASE=$($CONDA_BIN info --base)
CONDA_SH="$CONDA_BASE/etc/profile.d/conda.sh"
if [ ! -f "$CONDA_SH" ]; then
echo "Error: conda.sh not found at $CONDA_SH"
exit 1
fi
# --- Set local Conda cache ---
export CONDA_PKGS_DIRS=$HOME/.conda/pkgs
# --- Source conda.sh and activate environment ---
source "$CONDA_SH"
conda activate jupyterlab
# --- Run Jupyter Lab ---
jupyter lab --notebook-dir="$DIR" --port="$PORT" --no-browser
```
---
### **6.3 Setup script agar bisa dijalankan global**
```bash
# Pastikan direktori ~/bin
mkdir -p ~/bin
# Beri hak eksekusi
chmod +x ~/bin/jupyterlab
# Tambahkan ~/bin ke PATH di ~/.bashrc atau ~/.zshrc
export PATH="$HOME/bin:$PATH"
# Reload shell config
source ~/.bashrc
```
---
### **6.4 Cara Pakai**
* **Default direktori & port:**
```bash
jupyterlab
```
* **Custom direktori dan port:**
```bash
jupyterlab -d /home/user/projects -p 9999
```
> Script ini otomatis mengaktifkan environment `jupyterlab` sehingga user tidak perlu mengetik `conda activate jupyterlab`.
---
## **7. Catatan Penting**
1. **Folder Cache Lokal**
* Tanpa mengatur `CONDA_PKGS_DIRS`, Mamba/Conda bisa gagal menulis ke `/opt/miniconda/pkgs` jika tidak root.
* Disarankan menggunakan folder lokal `$HOME/.conda/pkgs`.
2. **Environment Management**
* Semua paket diinstall di environment `jupyterlab`, terisolasi dari system Python.
* Bisa membuat environment lain untuk proyek berbeda tanpa konflik.
3. **Buka Browser Otomatis**
* Script default menggunakan `--no-browser`.
* Bisa diubah jika ingin membuka browser otomatis dengan menambahkan opsi `--browser`.
4. **Port Konflik**
* Default port Jupyter Lab adalah 8888.
* Jika port sudah dipakai, jalankan dengan opsi `-p` untuk port lain.
---
## **8. Referensi Resmi**
* [Conda Documentation](https://docs.conda.io/projects/conda/en/latest/index.html)
* [Mamba Documentation](https://mamba.readthedocs.io/)
* [Jupyter Lab Documentation](https://jupyterlab.readthedocs.io/en/stable/)
* [Miniconda Installation](https://docs.conda.io/en/latest/miniconda.html)
---
**Dokumentasi ini self-contained**, mencakup semua langkah dari setup Conda/Mamba sampai wrapper script untuk Jupyter Lab.
---
Kalau mau, aku bisa buat **versi PDF siap cetak** atau **Markdown lengkap dengan snippet copy-paste**, supaya bisa langsung dibagikan ke tim.
Kamu mau aku buatkan versi PDF/Markdown itu juga?
#!/usr/bin/env bash
# Script untuk menginstal Docker Compose sebagai plugin untuk setup Docker Rootless.
# Versi 2.1: Memperbaiki bug kritis di mana `set -e` menyebabkan exit senyap saat tidak dalam mode dry-run.
# --- Konfigurasi Awal & Keamanan Skrip ---
set -euo pipefail
# --- Variabel Global & Konstanta ---
readonly SCRIPT_NAME="$(basename "$0")"
readonly GITHUB_REPO="docker/compose"
readonly ROOTLESS_PLUGIN_DIR="${HOME}/.docker/cli-plugins"
# Sesuaikan direktori ini jika Anda menggunakan ~/.local/bin
readonly COMPAT_SYMLINK_DIR="${HOME}/bin"
# --- Variabel Default untuk Argumen ---
VERBOSE=false
INSTALL_COMPAT_SYMLINK=false
DRY_RUN=false
TARGET_VERSION=""
TMP_DOWNLOAD_FILE=""
# --- Fungsi Logging (Modularitas) ---
if [[ -t 1 ]]; then
readonly C_RESET=$(tput sgr0); readonly C_INFO=$(tput setaf 6); readonly C_SUCCESS=$(tput setaf 2)
readonly C_WARN=$(tput setaf 3); readonly C_ERROR=$(tput setaf 1); readonly C_BOLD=$(tput bold)
else
readonly C_RESET="" C_INFO="" C_SUCCESS="" C_WARN="" C_ERROR="" C_BOLD=""
fi
log_info() { $VERBOSE && echo -e "${C_INFO}[INFO]${C_RESET} $1"; }
log_step() { echo -e "\n${C_BOLD}${C_SUCCESS}==>${C_RESET}${C_BOLD} $1${C_RESET}"; }
log_success() { echo -e "${C_SUCCESS}[SUKSES]${C_RESET} $1"; }
log_warn() { echo -e "${C_WARN}[PERINGATAN]${C_RESET} $1"; }
log_error() { echo -e "${C_ERROR}[ERROR]${C_RESET} $1" >&2; }
log_dry_run() { echo -e "${C_WARN}[DRY RUN]${C_RESET} Would execute: $*"; }
# --- Fungsi Eksekusi Terpusat untuk Dry Run ---
execute_cmd() {
if $DRY_RUN; then
log_dry_run "$@"
else
log_info "Executing: $*"
"$@"
fi
}
# --- Fungsi Bantuan & Penanganan Argumen ---
usage() {
cat << EOF
Penggunaan: $SCRIPT_NAME [OPTIONS]
Skrip ini menginstal Docker Compose (sebagai plugin) untuk lingkungan Docker rootless.
Opsi:
-V, --version VERSION Instal versi spesifik (mis. v2.27.0). Jika tidak, instal versi terbaru.
-c, --compat Buat symlink di ${COMPAT_SYMLINK_DIR}/docker-compose.
-v, --verbose Aktifkan mode verbose untuk output yang lebih detail.
-d, --dry-run Simulasikan instalasi tanpa melakukan perubahan pada sistem.
-h, --help Tampilkan pesan bantuan ini.
EOF
exit 0
}
parse_args() {
while [[ $# -gt 0 ]]; do
case $1 in
-V|--version) TARGET_VERSION="$2"; shift 2 ;;
-c|--compat) INSTALL_COMPAT_SYMLINK=true; shift ;;
-v|--verbose) VERBOSE=true; shift ;;
-d|--dry-run) DRY_RUN=true; shift ;;
-h|--help) usage ;;
*) log_error "Opsi tidak valid: $1"; usage ;;
esac
done
# --- PERBAIKAN KRITIS DI SINI ---
# Menggunakan `if` statement yang aman untuk `set -e` daripada `&&`
if [[ "$DRY_RUN" == "true" ]]; then
VERBOSE=true # Dry run secara implisit mengaktifkan verbose
fi
# --- AKHIR PERBAIKAN ---
}
# --- Fungsi Pengecekan & Validasi ---
check_dependencies() {
log_step "Memeriksa dependensi yang dibutuhkan..."
local missing_deps=false
for cmd in curl uname docker id; do
if ! command -v "$cmd" &> /dev/null; then
log_error "Perintah '$cmd' tidak ditemukan. Mohon instal terlebih dahulu."
missing_deps=true
fi
done
if $missing_deps; then exit 1; fi
log_success "Semua dependensi ditemukan."
}
check_rootless_setup() {
log_step "Memvalidasi setup Docker rootless..."
if [[ "$(id -u)" -eq 0 ]]; then
log_error "Skrip ini dirancang untuk pengguna non-root. Mohon jalankan tanpa sudo."
exit 1
fi
if ! docker context show | grep -q 'rootless'; then
log_error "Konteks Docker saat ini bukan 'rootless'. Pastikan Docker rootless sudah dikonfigurasi."
exit 1
fi
if ! docker ps > /dev/null 2>&1; then
log_error "Perintah 'docker ps' gagal. Pastikan DOCKER_HOST env var sudah ter-set dan daemon berjalan."
exit 1
fi
log_success "Setup Docker rootless terverifikasi."
}
# --- Fungsi Inti ---
get_latest_version() {
log_info "Mengambil versi rilis terbaru dari GitHub API..."
local latest_url="https://api.github.com/repos/${GITHUB_REPO}/releases/latest"
if ! LATEST_VERSION=$(curl -sSL "$latest_url" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/'); then
log_error "Gagal mengambil versi terbaru dari GitHub API."
exit 1
fi
if [[ -z "$LATEST_VERSION" ]]; then
log_error "Tidak dapat menentukan versi terbaru. Respons API mungkin berubah."
exit 1
fi
log_info "Versi terbaru yang ditemukan: ${LATEST_VERSION}"
TARGET_VERSION="$LATEST_VERSION"
}
download_compose() {
local arch; arch=$(uname -m)
log_info "Arsitektur terdeteksi: $arch"
local download_url="https://github.com/${GITHUB_REPO}/releases/download/${TARGET_VERSION}/docker-compose-linux-${arch}"
TMP_DOWNLOAD_FILE=$(mktemp)
log_info "File temporary untuk unduhan: ${TMP_DOWNLOAD_FILE}"
log_step "Mengunduh Docker Compose versi ${TARGET_VERSION}..."
echo "URL: $download_url"
if $DRY_RUN; then
execute_cmd touch "$TMP_DOWNLOAD_FILE" # Buat file kosong palsu untuk simulasi
log_success "Pengunduhan berhasil (simulasi)."
return
fi
if ! curl -fSL "$download_url" -o "$TMP_DOWNLOAD_FILE"; then
log_error "Gagal mengunduh Docker Compose. Periksa URL atau koneksi internet."
exit 1
fi
if [[ ! -s "$TMP_DOWNLOAD_FILE" ]]; then
log_error "File yang diunduh kosong. Instalasi dibatalkan."
exit 1
fi
log_success "Pengunduhan berhasil."
}
install_plugin() {
local install_path="${ROOTLESS_PLUGIN_DIR}/docker-compose"
log_step "Menginstal plugin Docker Compose..."
execute_cmd mkdir -p "$ROOTLESS_PLUGIN_DIR"
execute_cmd install -m 755 "$TMP_DOWNLOAD_FILE" "$install_path"
log_success "Plugin Docker Compose berhasil diinstal di ${install_path}"
}
setup_compat_symlink() {
if ! $INSTALL_COMPAT_SYMLINK; then return; fi
local install_path="${ROOTLESS_PLUGIN_DIR}/docker-compose"
local symlink_path="${COMPAT_SYMLINK_DIR}/docker-compose"
log_step "Membuat symlink untuk kompatibilitas mundur..."
execute_cmd mkdir -p "$COMPAT_SYMLINK_DIR"
execute_cmd ln -sf "$install_path" "$symlink_path"
if ! [[ ":$PATH:" == *":${COMPAT_SYMLINK_DIR}:"* ]]; then
log_warn "Direktori '${COMPAT_SYMLINK_DIR}' tidak ditemukan di PATH Anda. Buka terminal baru agar perubahan dikenali."
fi
log_success "Symlink 'docker-compose' berhasil dibuat di ${symlink_path}"
}
verify_installation() {
log_step "Memverifikasi instalasi..."
if $DRY_RUN; then
log_warn "Verifikasi dilewati dalam mode Dry Run."
return
fi
if ! docker compose version &> /dev/null; then
log_error "Verifikasi gagal. Perintah 'docker compose' (dengan spasi) tidak berfungsi."
exit 1
fi
local installed_version; installed_version=$(docker compose version --short)
log_success "Verifikasi berhasil! Versi Docker Compose yang terinstal: ${installed_version}"
}
cleanup() {
if [[ -n "$TMP_DOWNLOAD_FILE" && -f "$TMP_DOWNLOAD_FILE" ]]; then
log_info "Membersihkan file temporary: ${TMP_DOWNLOAD_FILE}"
execute_cmd rm -f "$TMP_DOWNLOAD_FILE"
fi
}
# --- Fungsi Main (Orkestrasi) ---
main() {
trap cleanup EXIT
parse_args "$@"
check_dependencies
check_rootless_setup
if [[ -z "$TARGET_VERSION" ]]; then
get_latest_version
fi
download_compose
install_plugin
setup_compat_symlink
verify_installation
local suffix=""
$DRY_RUN && suffix=" (Simulasi)"
echo -e "\n${C_BOLD}${C_SUCCESS}Instalasi Docker Compose selesai dengan sukses!${suffix}${C_RESET}"
}
# --- Titik Masuk Eksekusi ---
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
main "$@"
fi
\ No newline at end of file
#!/usr/bin/env bash
# ==============================================================================
# Script: install-docker-rootless.sh
# Versi: 2.9
# Deskripsi: Menginstal Docker dalam Rootless Mode di Rocky Linux 10.
# - Memperbaiki nama paket dependensi.
# - Memperbaiki metode eksekusi sub-shell 'su'.
# - Menambahkan pemuatan otomatis modul kernel 'ip_tables'.
# - Mengatur konteks D-Bus untuk interaksi systemctl --user.
# - Menambahkan pembersihan otomatis untuk idempotensi.
# - Menyuntikkan env vars sesi untuk deteksi systemd oleh installer.
# - Memperbaiki path soket pada konteks Docker secara otomatis.
#
# Penggunaan:
# sudo ./install-docker-rootless.sh -u <user> [--dry-run]
# ==============================================================================
# --- Konfigurasi Keamanan dan Error Handling ---
set -euo pipefail
# --- Variabel dan Konstanta ---
readonly SCRIPT_NAME=$(basename "$0")
USERNAME=""
DRY_RUN=false
# --- Fungsi Logging Berwarna (DRY & Robust) ---
readonly COLOR_GREEN='\033[0;32m'
readonly COLOR_YELLOW='\033[0;33m'
readonly COLOR_RED='\033[0;31m'
readonly COLOR_BLUE='\033[0;34m'
readonly COLOR_NC='\033[0m'
log_info() { printf "${COLOR_YELLOW}[INFO]${COLOR_NC} %s\n" "$1"; }
log_success() { printf "${COLOR_GREEN}[SUCCESS]${COLOR_NC} %s\n" "$1"; }
log_error() { printf "${COLOR_RED}[ERROR]${COLOR_NC} %s\n" "$1" >&2; }
log_dry_run() { printf "${COLOR_BLUE}[DRY-RUN]${COLOR_NC} Akan menjalankan: %s\n" "$*"; }
# --- Fungsi Wrapper Eksekusi ---
execute() {
if [ "$DRY_RUN" = true ]; then
log_dry_run "$@"
return 0
else
"$@"
fi
}
# --- Fungsi-fungsi Modular ---
show_help() {
echo "Penggunaan: sudo ./${SCRIPT_NAME} -u <nama_pengguna> [opsi]"
echo " -u, --user <user> Pengguna non-root untuk instalasi Docker Rootless. (Wajib)"
echo " --dry-run Tampilkan perintah yang akan dijalankan tanpa eksekusi."
echo " -h, --help Tampilkan pesan bantuan ini."
}
parse_arguments() {
while [[ $# -gt 0 ]]; do
case $1 in
-u|--user) USERNAME="$2"; shift 2 ;;
--dry-run) DRY_RUN=true; shift 1 ;;
-h|--help) show_help; exit 0 ;;
*) log_error "Argumen tidak valid: $1"; show_help; exit 1 ;;
esac
done
if [[ -z "$USERNAME" ]]; then
log_error "Parameter -u atau --user wajib diisi."; show_help; exit 1
fi
}
check_prerequisites() {
log_info "Memeriksa prasyarat sistem..."
if [[ "$EUID" -ne 0 ]]; then
log_error "Skrip ini harus dijalankan dengan hak akses root atau sudo."; exit 1
fi
if ! id -u "${USERNAME}" >/dev/null 2>&1; then
log_error "Pengguna '${USERNAME}' tidak ditemukan di sistem."; exit 1
fi
log_success "Prasyarat sistem terpenuhi."
}
prepare_system_for_rootless() {
log_info "Menyiapkan sistem untuk Docker Rootless..."
log_info "Menghapus instalasi Docker berbasis sistem (rootful) jika ada..."
if [ "$DRY_RUN" = true ]; then
log_dry_run "dnf remove -y docker-ce ..."
else
dnf remove -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin > /dev/null 2>&1 || true
fi
local required_pkg="shadow-utils-subid"
log_info "Memastikan dependensi sistem terinstal (${required_pkg}, curl)..."
if ! dnf list installed ${required_pkg} &>/dev/null || ! dnf list installed curl &>/dev/null; then
execute dnf install -y ${required_pkg} curl
else
log_info "Dependensi sudah terinstal."
fi
log_info "Memastikan modul kernel 'ip_tables' dimuat..."
execute modprobe ip_tables
local modules_conf="/etc/modules-load.d/docker-rootless.conf"
if [ "$DRY_RUN" = true ]; then
execute sh -c "echo ip_tables > ${modules_conf}"
elif [ ! -f "${modules_conf}" ] || ! grep -q -x "ip_tables" "${modules_conf}"; then
echo "ip_tables" > "${modules_conf}"
fi
log_success "Sistem siap untuk instalasi Rootless."
}
install_and_configure_rootless_as_user() {
log_info "Menjalankan skrip instalasi Rootless sebagai pengguna '${USERNAME}'..."
local user_uid
user_uid=$(id -u "${USERNAME}")
if [ "$DRY_RUN" = true ]; then
log_dry_run "Membersihkan instalasi rootless sebelumnya (jika ada)..."
log_dry_run "su - ${USERNAME} -c \"<blok perintah instalasi rootless dengan env vars>\""
printf " ${COLOR_BLUE}└─ Akan menyuntikkan env vars sesi untuk deteksi systemd.${NC}\n"
printf " ${COLOR_BLUE}└─ Akan mengunduh dan menjalankan skrip instalasi.${NC}\n"
printf " ${COLOR_BLUE}└─ Akan memperbaiki konteks Docker secara otomatis.${NC}\n"
printf " ${COLOR_BLUE}└─ Akan mengkonfigurasi PATH di ~/.bashrc.${NC}\n"
else
local user_cmd="bash -s -- '${user_uid}'"
su - "${USERNAME}" -c "${user_cmd}" <<'EOF'
set -euo pipefail
USER_UID="$1"
export XDG_RUNTIME_DIR="/run/user/${USER_UID}"
export DBUS_SESSION_BUS_ADDRESS="unix:path=${XDG_RUNTIME_DIR}/bus"
mkdir -p "${XDG_RUNTIME_DIR}"
chmod 700 "${XDG_RUNTIME_DIR}"
echo "[INFO] Membersihkan keadaan bersih dengan menghapus sisa-sisa instalasi sebelumnya..."
systemctl --user stop docker >/dev/null 2>&1 || true
rm -f "$HOME/bin/dockerd" "$HOME/bin/docker" "$HOME/bin/docker-compose" "$HOME/bin/docker-proxy" "$HOME/bin/containerd" "$HOME/bin/ctr" "$HOME/bin/runc"
rm -f "$HOME/.config/systemd/user/docker.service"
echo "[SUCCESS] Pembersihan selesai."
echo "[INFO] Memulai instalasi Docker Rootless yang baru..."
if ! curl -fsSL https://get.docker.com/rootless | sh; then
echo "[ERROR] Gagal menjalankan skrip instalasi Docker Rootless." >&2; exit 1
fi
echo "[INFO] Memperbaiki path soket pada konteks Docker agar sesuai dengan systemd..."
"$HOME/bin/docker" context update rootless --docker "host=unix://${XDG_RUNTIME_DIR}/docker.sock"
BASHRC_FILE="$HOME/.bashrc"
if [ -f "$BASHRC_FILE" ] && ! grep -q '$HOME/bin' "$BASHRC_FILE"; then
echo -e "\n# Add Docker Rootless binaries to PATH\nexport PATH=\$HOME/bin:\$PATH" >> "$BASHRC_FILE"
fi
EOF
fi
log_success "Instalasi Rootless untuk pengguna '${USERNAME}' selesai."
}
enable_user_services() {
log_info "Mengaktifkan service Docker level-pengguna dan Linger untuk '${USERNAME}'..."
execute loginctl enable-linger "${USERNAME}"
local user_uid
user_uid=$(id -u "${USERNAME}")
local user_cmd="export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${user_uid}/bus; systemctl --user enable --now docker"
log_info "Menjalankan perintah service sebagai pengguna dengan konteks D-Bus..."
execute su - "${USERNAME}" -c "${user_cmd}"
log_info "Memeriksa status service Docker Rootless..."
local status_cmd="export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/${user_uid}/bus; systemctl --user status docker"
if [ "$DRY_RUN" = true ]; then
log_dry_run su - "${USERNAME}" -c "'${status_cmd}'"
else
su - "${USERNAME}" -c "${status_cmd}" || true
fi
log_success "Service Docker Rootless aktif dan akan berjalan saat boot."
}
final_instructions() {
if [ "$DRY_RUN" = true ]; then
echo
log_info "DRY-RUN SELESAI. Tidak ada perubahan yang dibuat pada sistem."
else
echo
log_success "Instalasi Docker Rootless Selesai!"
printf "${COLOR_YELLOW}================== TINDAKAN PENTING ==================${COLOR_NC}\n"
printf "Pengguna '%s' harus LOG OUT dan LOG IN KEMBALI agar PATH baru\n" "${USERNAME}"
printf "dapat berfungsi dengan benar.\n\n"
printf "Setelah login kembali, lakukan PENYIAPAN SATU KALI dengan menjalankan:\n"
printf " ${COLOR_GREEN}docker context use rootless${COLOR_NC}\n\n"
printf "Setelah itu, verifikasi instalasi dengan:\n"
printf " ${COLOR_GREEN}docker run hello-world${COLOR_NC}\n\n"
printf "Anda sekarang mengelola Docker dengan:\n"
printf " ${COLOR_GREEN}systemctl --user status docker${COLOR_NC}\n"
printf "${COLOR_YELLOW}======================================================${COLOR_NC}\n"
fi
}
main() {
parse_arguments "$@"
if [ "$DRY_RUN" = true ]; then
log_info "Menjalankan dalam mode DRY-RUN. Tidak ada perubahan yang akan dibuat."
echo "------------------------------------------------------------------"
fi
check_prerequisites
prepare_system_for_rootless
install_and_configure_rootless_as_user
enable_user_services
final_instructions
}
main "$@"
\ No newline at end of file
#!/usr/bin/env bash
# ==============================================================================
# Script: install-docker.sh
# Deskripsi: Menginstal dan mengkonfigurasi Docker Engine di Rocky Linux 10
# dengan cara yang aman dan modular.
#
# Penggunaan:
# sudo ./install-docker.sh -u <nama_pengguna_non_root>
#
# Contoh:
# sudo ./install-docker.sh -u andi
# ==============================================================================
# --- Konfigurasi Keamanan dan Error Handling ---
set -euo pipefail
# --- Variabel dan Konstanta ---
readonly SCRIPT_NAME=$(basename "$0")
readonly DOCKER_REPO_URL="https://download.docker.com/linux/centos/docker-ce.repo"
USERNAME=""
# --- Fungsi Logging dan Output Berwarna (DRY & Robust) ---
# ANSI color codes
readonly COLOR_GREEN='\033[0;32m'
readonly COLOR_YELLOW='\033[0;33m'
readonly COLOR_RED='\033[0;31m'
readonly COLOR_NC='\033[0m' # No Color
log_info() {
printf "${COLOR_YELLOW}[INFO]${COLOR_NC} %s\n" "$1"
}
log_success() {
printf "${COLOR_GREEN}[SUCCESS]${COLOR_NC} %s\n" "$1"
}
log_error() {
printf "${COLOR_RED}[ERROR]${COLOR_NC} %s\n" "$1" >&2
}
# --- Fungsi-fungsi Modular ---
show_help() {
echo "Penggunaan: sudo ./${SCRIPT_NAME} -u <nama_pengguna>"
echo " -u, --user Nama pengguna non-root yang akan ditambahkan ke grup 'docker'."
echo " -h, --help Tampilkan pesan bantuan ini."
echo
echo "Contoh: sudo ./${SCRIPT_NAME} --user john"
}
parse_arguments() {
while [[ $# -gt 0 ]]; do
case $1 in
-u|--user)
USERNAME="$2"
shift 2
;;
-h|--help)
show_help
exit 0
;;
*)
log_error "Argumen tidak valid: $1"
show_help
exit 1
;;
esac
done
if [[ -z "$USERNAME" ]]; then
log_error "Nama pengguna wajib diisi menggunakan flag -u atau --user."
show_help
exit 1
fi
}
check_prerequisites() {
log_info "Memeriksa prasyarat sistem..."
if [[ "$EUID" -ne 0 ]]; then
log_error "Skrip ini harus dijalankan dengan hak akses root atau sudo."
exit 1
fi
if ! grep -q 'ID="rocky"' /etc/os-release || ! grep -q 'VERSION_ID="10"' /etc/os-release; then
log_error "Skrip ini dirancang khusus untuk Rocky Linux 10."
exit 1
fi
log_success "Prasyarat sistem terpenuhi."
}
remove_old_docker() {
log_info "Menghapus instalasi Docker versi lama jika ada..."
dnf remove -y docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine > /dev/null 2>&1 || true
log_success "Pembersihan instalasi lama selesai."
}
setup_docker_repo() {
log_info "Menyiapkan repository resmi Docker..."
if ! dnf list installed dnf-utils &>/dev/null; then
dnf install -y dnf-utils
fi
if ! dnf config-manager --add-repo "$DOCKER_REPO_URL"; then
log_error "Gagal menambahkan repository Docker."
exit 1
fi
log_success "Repository Docker berhasil ditambahkan."
}
install_docker_engine() {
log_info "Menginstal Docker Engine dan komponen terkait..."
if ! dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin; then
log_error "Gagal menginstal paket-paket Docker."
exit 1
fi
log_success "Docker Engine berhasil diinstal."
}
start_and_enable_docker() {
log_info "Memulai dan mengaktifkan service Docker..."
systemctl start docker
systemctl enable docker
if ! systemctl is-active --quiet docker; then
log_error "Service Docker gagal dimulai. Menampilkan status untuk diagnosis:"
systemctl status docker
exit 1
fi
log_success "Service Docker sedang berjalan dan aktif saat boot."
}
configure_post_install() {
local user_to_add="$1"
log_info "Melakukan konfigurasi pasca-instalasi untuk pengguna '${user_to_add}'..."
if ! id -u "${user_to_add}" >/dev/null 2>&1; then
log_error "Pengguna '${user_to_add}' tidak ditemukan di sistem."
exit 1
fi
groupadd --force docker
if ! usermod -aG docker "${user_to_add}"; then
log_error "Gagal menambahkan pengguna '${user_to_add}' ke grup 'docker'."
exit 1
fi
log_success "Pengguna '${user_to_add}' berhasil ditambahkan ke grup 'docker'."
}
final_instructions() {
echo
log_success "Instalasi Docker Selesai!"
printf "${COLOR_YELLOW}================== TINDAKAN PENTING ==================${COLOR_NC}\n"
printf "Untuk menerapkan perubahan, pengguna '%s' harus log out dan log in kembali.\n" "${USERNAME}"
printf "\n"
printf "Atau, untuk sesi terminal saat ini saja, jalankan sebagai pengguna '%s':\n" "${USERNAME}"
printf " ${COLOR_GREEN}newgrp docker${COLOR_NC}\n"
printf "\n"
printf "Setelah itu, verifikasi instalasi dengan menjalankan (tanpa sudo):\n"
printf " ${COLOR_GREEN}docker run hello-world${COLOR_NC}\n"
printf "${COLOR_YELLOW}======================================================${COLOR_NC}\n"
}
# --- Fungsi Utama (Orkestrasi) ---
main() {
parse_arguments "$@"
check_prerequisites
remove_old_docker
setup_docker_repo
install_docker_engine
start_and_enable_docker
configure_post_install "$USERNAME"
final_instructions
}
# --- Eksekusi Skrip ---
main "$@"
\ No newline at end of file
#!/bin/bash
# File: ~/bin/jupyterlab
# Usage: jupyterlab -d /path/to/dir -p 9999
# --- Default values ---
DIR="$PWD"
PORT="8888"
# --- Parse arguments ---
while getopts "d:p:" opt; do
case $opt in
d) DIR="$OPTARG" ;;
p) PORT="$OPTARG" ;;
*) echo "Usage: $0 [-d directory] [-p port]" ; exit 1 ;;
esac
done
# --- Auto-detect conda path ---
CONDA_BIN=$(which conda)
if [ -z "$CONDA_BIN" ]; then
echo "Error: Conda not found in PATH."
exit 1
fi
# Extract Conda base path
CONDA_BASE=$($CONDA_BIN info --base)
CONDA_SH="$CONDA_BASE/etc/profile.d/conda.sh"
if [ ! -f "$CONDA_SH" ]; then
echo "Error: conda.sh not found at $CONDA_SH"
exit 1
fi
# --- Set local Conda cache ---
export CONDA_PKGS_DIRS=$HOME/.conda/pkgs
# --- Source conda.sh and activate environment ---
source "$CONDA_SH"
conda activate jupyterlab
# --- Run Jupyter Lab ---
jupyter lab --notebook-dir="$DIR" --port="$PORT" --no-browser
#!/bin/bash
# Script untuk menghapus GNOME Tweaks & reset GNOME ke default
set -e # Stop jika ada error
echo "Menghapus GNOME Tweaks..."
sudo dnf remove -y gnome-tweaks
echo "Menghapus konfigurasi dan cache..."
rm -rf ~/.config/gnome-tweaks \
~/.local/share/gnome-tweaks \
~/.cache/gnome-tweaks \
~/.local/share/gnome-shell \
~/.config/dconf/user
echo "Reset semua setting GNOME ke default..."
dconf reset -f /org/gnome/
echo "Selesai! Silakan logout/login ulang untuk efek penuh."
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment