Otomatisasi Webserver Ubuntu 24 (LEMP): Nginx, PHP-FPM, Mari...
Otomatisasi Webserver Ubuntu 24 (LEMP): Nginx, PHP-FPM, MariaDB, Certbot — Domain Siap HTTPS
Panduan lengkap dan siap salin-tempel untuk membangun stack LEMP (Linux, Nginx, MariaDB, PHP-FPM) di Ubuntu 24. Termasuk skrip otomatis instalasi, pembuatan virtual host/domain, direktori web, <code>index.php</code>, serta penerbitan SSL Let’s Encrypt dengan Certbot. Dilengkapi petunjuk DNS agar domain mengarah ke IP publik server Anda.
Tujuan panduan ini adalah membawa sebuah server Ubuntu 24 dari kondisi awal menjadi siap melayani website dengan HTTPS secara otomatis. Anda akan: (1) menginstal paket dasar, (2) membuat server block Nginx untuk domain, (3) menerbitkan sertifikat Let’s Encrypt, dan (4) melakukan verifikasi. Seluruh perintah disiapkan agar copy-paste friendly.
Pendapat singkat: Otomasi yang baik menghemat waktu dan mencegah salah ketik—musuh alami sesi lembur.Daftar Isi- Prasyarat & Catatan Keamanan
- Arsitektur Singkat (LEMP)
- Penting: Arahkan DNS ke Server Ini
- Skrip Utama:
bootstrap-lemp-ubuntu24.sh - Cara Menjalankan Skrip Utama
- Menambah Domain Baru:
add-site.sh - Verifikasi & Uji Cepat
- Troubleshooting Ringkas
- Matriks Perbandingan: Nginx vs Apache
- Kesimpulan
- Sumber/Referensi
Prasyarat & Catatan Keamanan
- Server Ubuntu 24.04 LTS dengan IP publik dan akses root (
sudo -i). - Domain yang Anda miliki (misal
example.com). - Firewall membuka port 80/tcp dan 443/tcp.
- Gunakan SSH key untuk produksi; hindari kata sandi lemah.
Arsitektur Singkat (LEMP)
- Linux (Ubuntu 24) sebagai OS.
- Nginx melayani HTTP/HTTPS dan meneruskan request ke PHP-FPM.
- MariaDB sebagai RDBMS.
- PHP-FPM memproses skrip PHP.
- Certbot mengotomasi sertifikat Let’s Encrypt + pembaruan otomatis.
Penting: Arahkan DNS ke Server Ini
Wajib sebelum minta sertifikat: Buat record DNS berikut di Cloudflare/penyedia DNS Anda:Auntukexample.com→IP_PUBLIK_SERVERAuntukwww.example.com→IP_PUBLIK_SERVER- (Opsional IPv6)
AAAAuntuk keduanya →IPv6_SERVER
Setelah itu, cek:
Copydig +short A example.com
dig +short A www.example.comSkrip Utama: bootstrap-lemp-ubuntu24.sh
Skrip ini: menyiapkan UFW, memasang Nginx + PHP-FPM + MariaDB + Certbot, membuat vhost & direktori web, menambahkan index.php, memeriksa DNS → IP server, dan menerbitkan SSL.
/root/bootstrap-lemp-ubuntu24.shCopy
#!/usr/bin/env bash
# File: /root/bootstrap-lemp-ubuntu24.sh
# OS : Ubuntu 24.04 LTS
# Goal : Automate LEMP + domain + HTTPS (Let's Encrypt) end-to-end
set -euo pipefail
# ---------------- Helpers ----------------
log() { echo -e "[e[32mINFOe[0m] $*"; }
warn(){ echo -e "[e[33mWARNe[0m] $*"; }
err() { echo -e "[e[31mERRORe[0m] $*" 1>&2; }
require_root() {
if [[ $EUID -ne 0 ]]; then
err "Jalankan sebagai root. Gunakan: sudo -i"
exit 1
fi
}
get_server_ip() {
local ip4
ip4="$(curl -4s https://api.ipify.org || true)"
echo "$ip4"
}
resolve_domain_ip() {
local d="$1"
local ip
ip="$(getent ahostsv4 "$d" | awk '/STREAM/ {print $1; exit}' || true)"
if [[ -z "$ip" ]]; then
ip="$(dig +short A "$d" 2>/dev/null | head -n1 || true)"
fi
echo "$ip"
}
random_password() {
tr -dc 'A-Za-z0-9_@#%+=' < /dev/urandom | head -c 24 } # ---------------- Inputs ------------------ DOMAIN="${DOMAIN:-}" ADMIN_EMAIL="${ADMIN_EMAIL:-}" DB_NAME="${DB_NAME:-}" DB_USER="${DB_USER:-}" DB_PASS="${DB_PASS:-}" STAGING="${STAGING:-false}" # true|false # -------------- Pre-flight ---------------- require_root command -v curl >/dev/null 2>&1 || apt-get update -y && apt-get install -y curl
log "Memulai bootstrap LEMP Ubuntu 24..."
if [[ -z "$DOMAIN" ]]; then
read -rp "Masukkan DOMAIN (contoh: example.com): " DOMAIN
fi
if [[ -z "$ADMIN_EMAIL" ]]; then
read -rp "Masukkan EMAIL admin untuk Let's Encrypt: " ADMIN_EMAIL
fi
if [[ -n "$DB_NAME" || -n "$DB_USER" || -n "$DB_PASS" ]]; then
log "Mode DB: pembuatan kredensial untuk ${DB_NAME:-}"
if [[ -z "${DB_NAME}" ]]; then read -rp "Masukkan DB_NAME: " DB_NAME; fi
if [[ -z "${DB_USER}" ]]; then read -rp "Masukkan DB_USER: " DB_USER; fi
if [[ -z "${DB_PASS}" ]]; then
read -rp "Masukkan DB_PASS (kosongkan untuk acak): " DB_PASS || true
if [[ -z "${DB_PASS}" ]]; then DB_PASS="$(random_password)"; fi
fi
fi
SERVER_IP="$(get_server_ip || true)"
if [[ -z "$SERVER_IP" ]]; then
warn "Gagal mendeteksi IP publik via api.ipify.org. Pastikan koneksi internet tersedia."
else
log "IP publik server terdeteksi: $SERVER_IP"
fi
DNS_IP_ROOT="$(resolve_domain_ip "$DOMAIN" || true)"
DNS_IP_WWW="$(resolve_domain_ip "www.${DOMAIN}" || true)"
if [[ -z "$DNS_IP_ROOT" || "$DNS_IP_ROOT" != "$SERVER_IP" ]]; then
warn "A record untuk ${DOMAIN} belum mengarah ke IP server ($SERVER_IP). Deteksi: ${DNS_IP_ROOT:-}"
fi
if [[ -z "$DNS_IP_WWW" || "$DNS_IP_WWW" != "$SERVER_IP" ]]; then
warn "A record untuk www.${DOMAIN} belum mengarah ke IP server ($SERVER_IP). Deteksi: ${DNS_IP_WWW:-}"
fi
# -------------- System Prep ----------------
log "Update & upgrade paket..."
export DEBIAN_FRONTEND=noninteractive
apt-get update -y
apt-get upgrade -y
log "Instal paket umum..."
apt-get install -y software-properties-common unzip ca-certificates gnupg ufw
log "Set firewall (UFW)..."
ufw allow OpenSSH >/dev/null 2>&1 || true
ufw allow 80/tcp >/dev/null 2>&1 || true
ufw allow 443/tcp >/dev/null 2>&1 || true
echo "y" | ufw enable >/dev/null 2>&1 || true
# -------------- Install LEMP ---------------
log "Instal Nginx, PHP-FPM, ekstensi, MariaDB, Certbot..."
apt-get install -y nginx
php-fpm php-cli php-mysql php-curl php-xml php-mbstring php-zip php-gd php-intl
mariadb-server
certbot python3-certbot-nginx
systemctl enable --now nginx
systemctl enable --now mariadb
# PHP-FPM service name and socket autodetect
if systemctl list-units | grep -q 'php8.3-fpm'; then
systemctl enable --now php8.3-fpm
else
systemctl enable --now php-fpm || true
fi
PHP_SOCK="$(find /run/php -maxdepth 1 -type s -name 'php*-fpm.sock' | head -n1)"
if [[ -z "$PHP_SOCK" ]]; then
PHP_SOCK="/run/php/php8.3-fpm.sock"
fi
log "Menggunakan PHP-FPM socket: ${PHP_SOCK}"
# --------- (Optional) Create DB ------------
create_db_user() {
local dbn="$1" dbu="$2" dbp="$3"
log "Membuat database & user MariaDB untuk ${DOMAIN}..."
mysql < "/root/${DOMAIN}-db.txt" < "${WEBROOT}/index.php" <<'PHP'
Copy
#!/usr/bin/env bash
# File: /root/add-site.sh
# Add a new domain vhost + webroot + Let's Encrypt (Nginx)
set -euo pipefail
DOMAIN="${DOMAIN:-}"
ADMIN_EMAIL="${ADMIN_EMAIL:-}"
STAGING="${STAGING:-false}"
if [[ -z "$DOMAIN" || -z "$ADMIN_EMAIL" ]]; then
echo "Usage: DOMAIN=example.com ADMIN_EMAIL=admin@example.com [STAGING=true] /root/add-site.sh"
exit 1
fi
WEBROOT="/var/www/${DOMAIN}/public"
mkdir -p "$WEBROOT"
cat > "${WEBROOT}/index.php" <<'PHP'
PHP
chown -R www-data:www-data "/var/www/${DOMAIN}"
find "/var/www/${DOMAIN}" -type f -exec chmod 0644 {} ;
find "/var/www/${DOMAIN}" -type d -exec chmod 0755 {} ;
# Autodetect PHP-FPM socket
PHP_SOCK="$(find /run/php -maxdepth 1 -type s -name 'php*-fpm.sock' | head -n1)"
if [[ -z "$PHP_SOCK" ]]; then PHP_SOCK="/run/php/php8.3-fpm.sock"; fi
VHOST="/etc/nginx/sites-available/${DOMAIN}.conf"
cat > "$VHOST" <Copychmod +x /root/add-site.sh
DOMAIN=sub.example.com ADMIN_EMAIL=admin@example.com /root/add-site.shVerifikasi & Uji Cepat
Copysystemctl status nginx php8.3-fpm mariadbCopycurl -I https://example.com
curl -s https://example.com | headCopysudo certbot renew --dry-runCopytail -n 50 /var/log/nginx/example.com.access.log
tail -n 50 /var/log/nginx/example.com.error.logTroubleshooting Ringkas
- Sertifikat gagal diterbitkan → Pastikan DNS
A/AAAAuntukexample.comdanwww.example.commengarah ke IP server; tunggu propagasi. Jalankan ulang Certbot:
Copycertbot --nginx -d example.com -d www.example.com -m admin@example.com --agree-tos --redirect --non-interactive - Konfigurasi Nginx error → Uji sintaks, lalu reload.
Copynginx -t && systemctl reload nginx - PHP tidak dieksekusi → Pastikan blok
location ~ .php$ada danfastcgi_passmenunjuk ke soket FPM yang benar. - 403/404 → Pastikan
rootmengarah ke/var/www/<domain>/public, fileindex.phpada, dan izin/owner sesuai (www-data). - Kredensial DB → Tersimpan di
/root/<domain>-db.txtbila pembuatan DB diaktifkan.
Matriks Perbandingan: Nginx vs Apache
| Aspek | Nginx | Apache |
|---|---|---|
| Kinerja Static | Event-driven, sangat efisien | Baik, modul luas |
| Reverse Proxy | Native kuat (HTTP/2/3) | Bisa via mod_proxy |
| Konfigurasi PHP | via PHP-FPM | mod_php/PHP-FPM |
| Konsumsi Memori | Umumnya lebih hemat | Cenderung lebih tinggi |
| Ekosistem Modul | Ringkas | Sangat banyak |
Kesimpulan
Dengan skrip bootstrap-lemp-ubuntu24.sh, proses dari server kosong hingga situs aktif dengan HTTPS menjadi ringkas, konsisten, dan mudah diaudit. Pastikan DNS sudah mengarah ke IP publik sebelum meminta sertifikat. Untuk domain tambahan, gunakan add-site.sh agar administrasi tetap rapi dan berulang dengan cepat.
Sumber/Referensi
- https://nginx.org/en/linux_packages.html
- https://www.php.net/manual/en/install.fpm.php
- https://mariadb.com/kb/en/documentation/
- https://certbot.eff.org/
- https://ubuntu.com/server/docs
- https://letsencrypt.org/docs/
.table-wrap{overflow:auto;border:1px solid #e2e8f0;border-radius:12px;margin:8px 0}
table{border-collapse:collapse;width:100%}
th,td{padding:10px;border-bottom:1px solid #e2e8f0;text-align:left}
.refs li{margin-left:18px}
/* Code blocks */
.codebox{margin:10px 0}
.codehead{display:flex;justify-content:space-between;align-items:center;background:var(--soft);border:1px solid #e2e8f0;border-bottom:none;border-radius:10px 10px 0 0;padding:8px 10px;font-size:14px;color:var(--ink-2)}
pre{background:var(--bg);color:var(--fg);border:1px solid var(--line);border-radius:10px;padding:12px;overflow:auto;margin:0}
code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:14px;white-space:pre}
.copy{float:right;margin-left:auto;margin-bottom:6px;padding:6px 10px;border-radius:8px;border:1px solid var(--muted);background:#f8fafc;cursor:pointer}
.copy:disabled{opacity:.6;cursor:not-allowed}
Post Terkait
Membangun Frontend Vendor-Agnostic yang Tahan Perubahan
Artikel ini membahas pendekatan arsitektur frontend yang berfokus pada kontrak internal agar aplikasi web tetap stabil,...
Cara Membuat Localhost Jadi Online dengan Cloudflare Tunnel (Pakai Domain Sendiri)
Panduan praktis untuk mempublikasikan aplikasi yang berjalan di localhost (misalnya web app di port 3000/5173/8080) agar...
Perbedaan Cloud File Storage dan Cloud Object Storage: Memahami Dua Paradigma Penyimpanan Data
Artikel ini membahas perbedaan fundamental antara Cloud File Storage dan Cloud Object Storage dengan fokus pada arsitekt...