KelasIT.com
DevOps

Deploy Laravel ke Server

Panduan deploy aplikasi Laravel ke server Linux (VPS): menyiapkan Nginx, PHP-FPM, MySQL, konfigurasi produksi, izin berkas, optimasi cache, HTTPS, queue worker, scheduler, backup, dan prosedur update tanpa drama.

Deploy Laravel ke Server

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

  1. Siapkan server dan keamanan dasar.
  2. Pasang Nginx, PHP, Composer, MySQL.
  3. Ambil kode (Git) dan pasang dependency.
  4. Atur .env produksi dan izin berkas.
  5. Konfigurasi Nginx mengarah ke folder public.
  6. Jalankan migration dan optimasi.
  7. Pasang HTTPS, queue worker, dan scheduler.
  8. 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 fail2ban untuk 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-dev melewatkan 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=false wajib. 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:

  • --force diperlukan karena Laravel menolak menjalankan migration di produksi tanpa konfirmasi.
  • config:cache membuat fungsi env() hanya bekerja di dalam file config/. Pastikan kode aplikasi memakai config('...'), bukan env() langsung.
  • route:cache gagal jika ada route berupa closure; ubah menjadi controller.
  • Setiap kali .env atau konfigurasi berubah, jalankan lagi php artisan config:cache (atau optimize:clear lalu 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 (mysqldump atau paket spatie/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.log dan /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:

  1. Unggah proyek di luar public_html (misalnya /home/user/tokoku).
  2. Isi public_html dengan isi folder public, lalu ubah path di index.php agar menunjuk ke ../tokoku/vendor/autoload.php dan ../tokoku/bootstrap/app.php.
  3. Buat database lewat cPanel, atur .env, jalankan migration lewat SSH bila tersedia atau lewat route sementara yang dihapus setelahnya.
  4. Cron job dibuat lewat menu cPanel.

Ini bekerja, tetapi VPS memberi kontrol dan keamanan yang jauh lebih baik.

Masalah umum dan solusinya

GejalaPenyebab / solusi
500 Internal Server Error tanpa pesanCek 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 lamaCache konfigurasi: php artisan config:clear lalu cache ulang
Gambar unggahan 404php artisan storage:link belum dijalankan
CSS/JS tidak termuat atau memakai URL salahAset belum di-build, atau APP_URL salah
"Permission denied" pada log/cacheIzin storage dan bootstrap/cache untuk www-data
Email tidak terkirimKredensial SMTP salah atau queue worker tidak jalan
Perubahan kode tidak terbaca jobWorker belum di-restart (queue:restart)

Daftar periksa sebelum rilis

  • [ ] APP_ENV=production, APP_DEBUG=false, APP_KEY terisi.
  • [ ] Document root = public; .env tidak terakses via web.
  • [ ] HTTPS aktif dengan pembaruan sertifikat otomatis.
  • [ ] Izin storage dan bootstrap/cache benar, 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.

A
Admin KelasIT

Menulis tentang pemrograman, database, AI, dan karier di dunia IT supaya belajar terasa lebih mudah dan menyenangkan.

Komentar (0)

Komentar hanya untuk member. Masuk atau daftar gratis untuk ikut berdiskusi.

Mau belajar lebih dalam?

Course online dengan latihan coding interaktif dan sertifikat.

Lihat Course →

Gabung komunitas

Tanya jawab, info event, dan teman belajar di grup WhatsApp.

Gabung Grup