Aplikasi Laravel yang berjalan sempurna di laptop belum tentu langsung hidup di server. Deployment melibatkan konfigurasi web server, izin berkas, variabel lingkungan, dan keamanan. Artikel ini memandu deploy ke VPS Ubuntu dengan Nginx + PHP-FPM + MySQL, yaitu setup yang paling umum di produksi.
Jika memakai shared hosting, prinsipnya sama tetapi kamu tidak punya akses root; lihat bagian khusus di akhir.
Gambaran alur
- Siapkan server dan keamanan dasar.
- Pasang Nginx, PHP, Composer, MySQL.
- Ambil kode (Git) dan pasang dependency.
- Atur
.envproduksi dan izin berkas. - Konfigurasi Nginx mengarah ke folder
public. - Jalankan migration dan optimasi.
- Pasang HTTPS, queue worker, dan scheduler.
- Atur backup dan pemantauan.
1. Menyiapkan server
Setelah membuat VPS (Ubuntu 22.04/24.04 LTS) dan masuk lewat SSH:
sudo apt update && sudo apt upgrade -y
adduser deploy && usermod -aG sudo deploy # jangan bekerja sebagai root
Keamanan dasar:
- Login memakai SSH key, nonaktifkan login root dan password di
/etc/ssh/sshd_config. - Aktifkan firewall:
sudo ufw allow OpenSSH && sudo ufw allow 'Nginx Full' && sudo ufw enable. - Pasang
fail2banuntuk menahan percobaan login berulang. - Aktifkan pembaruan keamanan otomatis (
unattended-upgrades).
2. Memasang komponen
sudo apt install nginx mysql-server git unzip -y
sudo apt install php8.2-fpm php8.2-cli php8.2-mysql php8.2-mbstring php8.2-xml \
php8.2-curl php8.2-zip php8.2-bcmath php8.2-intl -y
curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
Sesuaikan versi PHP dengan kebutuhan aplikasi (Laravel 10 butuh PHP 8.1+). Amankan MySQL dengan sudo mysql_secure_installation, lalu buat database dan user khusus aplikasi dengan hak terbatas:
CREATE DATABASE tokoku CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'tokoku'@'localhost' IDENTIFIED BY 'SandiKuatUnik!';
GRANT ALL PRIVILEGES ON tokoku.* TO 'tokoku'@'localhost';
3. Mengambil kode dan dependency
cd /var/www
sudo git clone https://github.com/username/tokoku.git
sudo chown -R deploy:www-data tokoku
cd tokoku
composer install --no-dev --optimize-autoloader
--no-devmelewatkan paket pengembangan (lebih kecil dan aman).- Jika aplikasi memakai Vite/Mix, build aset di CI atau lokal (
npm ci && npm run build) lalu sertakan hasilnya, atau jalankan build di server.
4. Konfigurasi .env produksi
cp .env.example .env
php artisan key:generate
Nilai penting:
APP_ENV=production
APP_DEBUG=false
APP_URL=https://tokoku.com
DB_DATABASE=tokoku
DB_USERNAME=tokoku
DB_PASSWORD=SandiKuatUnik!
LOG_LEVEL=warning
SESSION_SECURE_COOKIE=true
APP_DEBUG=falsewajib. Dengan debug menyala, halaman error menampilkan isi.env, kredensial database, dan jalur berkas ke pengunjung. Jangan pernah meng-commit.env, dan batasi izinnya:chmod 640 .env.
APP_URL dipakai untuk membuat tautan di email dan notifikasi, jadi harus benar.
5. Izin berkas
Web server (user www-data) harus bisa menulis ke dua folder saja:
sudo chgrp -R www-data storage bootstrap/cache
sudo chmod -R ug+rwx storage bootstrap/cache
Jangan memakai chmod 777. Kode aplikasi sebaiknya tidak bisa ditulis oleh proses web.
Untuk berkas unggahan publik: php artisan storage:link.
6. Konfigurasi Nginx
Kunci utama: document root menunjuk ke folder public, bukan ke akar proyek, agar .env dan kode tidak terakses lewat web.
server {
listen 80;
server_name tokoku.com www.tokoku.com;
root /var/www/tokoku/public;
index index.php;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
location ~ /\.(?!well-known).* {
deny all; # blokir .env, .git, dll.
}
}
Aktifkan dan muat ulang:
sudo ln -s /etc/nginx/sites-available/tokoku /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
try_files ... /index.php?$query_string adalah baris yang membuat route Laravel (/produk/5) berfungsi; kalau hilang, semua URL selain / menghasilkan 404.
7. Migration dan optimasi
php artisan migrate --force
php artisan storage:link
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cache
Catatan:
--forcediperlukan karena Laravel menolak menjalankan migration di produksi tanpa konfirmasi.config:cachemembuat fungsienv()hanya bekerja di dalam fileconfig/. Pastikan kode aplikasi memakaiconfig('...'), bukanenv()langsung.route:cachegagal jika ada route berupa closure; ubah menjadi controller.- Setiap kali
.envatau konfigurasi berubah, jalankan lagiphp artisan config:cache(atauoptimize:clearlalu cache ulang).
Aktifkan juga OPcache di php.ini untuk peningkatan kecepatan PHP yang besar.
8. HTTPS dengan Let's Encrypt
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d tokoku.com -d www.tokoku.com
Certbot memasang sertifikat gratis, mengatur pengalihan HTTP → HTTPS, dan memperbarui otomatis (periksa sudo certbot renew --dry-run). Pastikan DNS domain (A record) sudah mengarah ke IP server sebelum menjalankannya.
9. Queue worker dan scheduler
Queue worker harus berjalan terus. Gunakan Supervisor agar otomatis hidup kembali:
; /etc/supervisor/conf.d/tokoku-worker.conf
[program:tokoku-worker]
command=php /var/www/tokoku/artisan queue:work --sleep=3 --tries=3 --max-time=3600
user=www-data
autostart=true
autorestart=true
numprocs=2
redirect_stderr=true
stdout_logfile=/var/log/tokoku-worker.log
sudo supervisorctl reread && sudo supervisorctl update && sudo supervisorctl start tokoku-worker:*
Ingat: worker menyimpan kode di memori, jadi restart setelah setiap deploy: php artisan queue:restart.
Scheduler cukup satu entri cron:
* * * * * cd /var/www/tokoku && php artisan schedule:run >> /dev/null 2>&1
Semua tugas terjadwal didefinisikan di kode (app/Console/Kernel.php).
10. Prosedur update (deploy berikutnya)
Skrip sederhana deploy.sh:
#!/bin/bash
set -e
cd /var/www/tokoku
php artisan down --retry=60 # mode maintenance
git pull origin main
composer install --no-dev --optimize-autoloader
php artisan migrate --force
php artisan config:cache && php artisan route:cache && php artisan view:cache
php artisan queue:restart
php artisan up
Untuk zero-downtime, gunakan alat seperti Laravel Forge/Envoyer, Deployer, atau GitHub Actions dengan struktur releases/ + symlink current. Otomatiskan lewat CI/CD agar deploy konsisten, dengan test yang lulus sebelum rilis.
11. Backup dan pemantauan
- Backup database terjadwal (
mysqldumpatau paketspatie/laravel-backup) dan simpan di lokasi lain (S3, server berbeda). Uji pemulihannya. - Backup folder
storage/app(unggahan pengguna) dan.env(di tempat aman, terenkripsi). - Log: pantau
storage/logs/laravel.logdan/var/log/nginx/error.log; atur rotasi log agar disk tidak penuh. - Pemantauan uptime (UptimeRobot, Better Stack) dan pelacak error (Sentry, Flare).
- Pantau disk, RAM, dan CPU.
Shared hosting / cPanel
Jika tidak ada akses root:
- Unggah proyek di luar
public_html(misalnya/home/user/tokoku). - Isi
public_htmldengan isi folderpublic, lalu ubah path diindex.phpagar menunjuk ke../tokoku/vendor/autoload.phpdan../tokoku/bootstrap/app.php. - Buat database lewat cPanel, atur
.env, jalankan migration lewat SSH bila tersedia atau lewat route sementara yang dihapus setelahnya. - Cron job dibuat lewat menu cPanel.
Ini bekerja, tetapi VPS memberi kontrol dan keamanan yang jauh lebih baik.
Masalah umum dan solusinya
| Gejala | Penyebab / solusi |
|---|---|
| 500 Internal Server Error tanpa pesan | Cek storage/logs/laravel.log dan log Nginx; biasanya izin storage atau APP_KEY kosong |
404 pada semua URL kecuali / | try_files Nginx belum benar |
| "No application encryption key" | Jalankan php artisan key:generate lalu config:cache |
| Halaman menampilkan konfigurasi lama | Cache konfigurasi: php artisan config:clear lalu cache ulang |
| Gambar unggahan 404 | php artisan storage:link belum dijalankan |
| CSS/JS tidak termuat atau memakai URL salah | Aset belum di-build, atau APP_URL salah |
| "Permission denied" pada log/cache | Izin storage dan bootstrap/cache untuk www-data |
| Email tidak terkirim | Kredensial SMTP salah atau queue worker tidak jalan |
| Perubahan kode tidak terbaca job | Worker belum di-restart (queue:restart) |
Daftar periksa sebelum rilis
- [ ]
APP_ENV=production,APP_DEBUG=false,APP_KEYterisi. - [ ] Document root =
public;.envtidak terakses via web. - [ ] HTTPS aktif dengan pembaruan sertifikat otomatis.
- [ ] Izin
storagedanbootstrap/cachebenar, bukan 777. - [ ] Cache config/route/view dibuat; OPcache aktif.
- [ ] Queue worker (Supervisor) dan cron scheduler berjalan.
- [ ] Backup otomatis dan pernah diuji pulihkan.
- [ ] Firewall aktif, login SSH hanya dengan key.
- [ ] Pemantauan error dan uptime terpasang.
Kesimpulan
Deployment yang rapi bertumpu pada: document root ke public, .env produksi dengan debug mati, izin berkas yang tepat, cache terpadu, HTTPS, worker + scheduler yang terawasi, serta backup yang teruji. Otomatiskan langkahnya dengan skrip atau CI/CD, sehingga setiap rilis mengikuti prosedur yang sama dan bisa diulang tanpa panik.
Komentar (0)
Masuk / Daftar