Deploy Laravel ke VPS bukan sekadar memindahkan file dari komputer lokal ke server. Di lingkungan production, aplikasi harus berjalan stabil, aman, cepat, dan mudah dipelihara. Karena itu, proses upload Laravel ke VPS perlu dilakukan dengan urutan yang benar: menyiapkan server, memasang dependency, mengatur Nginx, mengelola file .env, menjalankan Composer, mengatur permission, menghubungkan database, mengaktifkan SSL, lalu memastikan queue dan scheduler berjalan jika aplikasi membutuhkannya.
Kenapa Laravel Harus Mengarah ke Folder Public?
public
Di dalam folder public terdapat file index.php sebagai front controller aplikasi. Semua request harus masuk melalui file ini. Folder lain seperti .env, config, storage, dan source code aplikasi tidak boleh terbuka dari browser.
/var/www/nama-project/public
Bukan ke:
/var/www/nama-projectJika root diarahkan ke folder project utama, ada risiko file sensitif dapat terekspos. Ini kesalahan konfigurasi serius dan harus dihindari.
Persiapan VPS Ubuntu
ssh user@ip-server
Lalu update package server:
sudo apt update
sudo apt upgrade -yInstall komponen utama yang dibutuhkan:
sudo apt install -y nginx mysql-server php-fpm php-cli php-mysql php-mbstring php-xml php-bcmath php-curl php-zip php-gd unzip git curlLaravel membutuhkan beberapa extension PHP agar fitur framework berjalan normal, seperti database driver, XML, cURL, mbstring, zip, dan bcmath. Jika extension kurang, Composer install atau aplikasi bisa gagal berjalan.
php -vPastikan versi PHP sesuai dengan requirement Laravel yang digunakan. Jangan memaksakan project Laravel modern berjalan di PHP lama. Ini akan menimbulkan error dependency dan masalah keamanan.
Menyiapkan Folder Project
cd /var/www
sudo mkdir nama-project
sudo chown -R $USER:$USER nama-projectJika project menggunakan Git, clone repository:
git clone https://github.com/username/nama-repository.git nama-project
cd nama-projectJika tidak menggunakan Git, file bisa diupload melalui SFTP atau rsync. Namun untuk production, Git lebih disarankan karena deployment lebih rapi, mudah dilacak, dan lebih aman dibanding upload manual berulang.
Install Composer Dependency
composer install --no-dev --optimize-autoloaderPerintah ini penting untuk production. Opsi --no-dev mencegah package development ikut terpasang di server, sedangkan --optimize-autoloader membantu performa autoload aplikasi.
Menyiapkan File .env
cp .env.example .envEdit file .env:
nano .envMinimal pastikan konfigurasi berikut benar:
APP_NAME="Nama Aplikasi"
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://domainanda.com
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=nama_database
DB_USERNAME=nama_userUntuk production, APP_DEBUG wajib bernilai:
APP_DEBUG=falseJangan biarkan APP_DEBUG=true di server production. Jika terjadi error, Laravel dapat menampilkan detail stack trace, path server, konfigurasi, bahkan informasi sensitif yang tidak boleh dilihat publik.
php artisan key:generateMenyiapkan Database
sudo mysqlBuat database dan user khusus untuk aplikasi:
CREATE DATABASE nama_database CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'nama_user'@'localhost' IDENTIFIED BY 'password_kuat';
GRANT ALL PRIVILEGES ON nama_database.* TO 'nama_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;Jangan gunakan user root database untuk aplikasi Laravel. Buat user khusus dengan akses hanya ke database aplikasi tersebut. Ini lebih aman dan lebih mudah dikelola.
php artisan migrate --forceOpsi --force diperlukan karena Laravel akan meminta konfirmasi saat migration dijalankan di environment production.
php artisan db:seed --forceJangan menjalankan seeder dummy atau data testing di production.
Mengatur Permission Laravel
sudo chown -R www-data:www-data storage bootstrap/cache
sudo chmod -R 775 storage bootstrap/cacheJangan menggunakan:
chmod -R 777Itu solusi malas dan tidak aman. Permission 777 memberi akses tulis kepada semua user sistem. Di production, ini membuka risiko keamanan yang tidak perlu.
Membuat Storage Link
php artisan storage:linkPerintah ini membuat symbolic link dari:
public/storageke:
storage/app/publicTanpa storage link, gambar atau file yang diupload ke storage publik tidak akan bisa diakses dari browser.
Konfigurasi Nginx untuk Laravel
sudo nano /etc/nginx/sites-available/nama-projectIsi konfigurasi berikut. Sesuaikan domain, path project, dan versi PHP-FPM yang digunakan:
server {
listen 80;
server_name domainanda.com www.domainanda.com;
root /var/www/nama-project/public;
index index.php index.html;
charset utf-8;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
client_max_body_size 20M;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location = /favicon.ico {
access_log off;
log_not_found off;
}
location = /robots.txt {
access_log off;
log_not_found off;
}
error_page 404 /index.php;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_hide_header X-Powered-By;
}
location ~ /\.(?!well-known).* {
deny all;
}
}Bagian paling penting adalah:
root /var/www/nama-project/public;dan:
try_files $uri $uri/ /index.php?$query_string;try_files memastikan routing Laravel berjalan melalui index.php. Tanpa konfigurasi ini, route Laravel bisa menghasilkan error 404 dari Nginx.
Aktifkan konfigurasi:
sudo ln -s /etc/nginx/sites-available/nama-project /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginxJika nginx -t menampilkan error, jangan reload sebelum konfigurasi diperbaiki.
Mengaktifkan SSL HTTPS
sudo apt install -y certbot python3-certbot-nginxJalankan:
sudo certbot --nginx -d domainanda.com -d www.domainanda.com
Ikuti instruksi yang muncul. Setelah selesai, cek auto-renewal:
sudo certbot renew --dry-runDi file .env, pastikan APP_URL menggunakan HTTPS:
APP_URL=https://domainanda.comJika aplikasi menggunakan session, cookie, atau URL generator, konfigurasi APP_URL yang benar sangat penting.
Optimasi Laravel untuk Production
php artisan config:cache
php artisan route:cache
php artisan view:cache
php artisan event:cachePerintah ini membantu Laravel membaca konfigurasi dan route lebih efisien.
php artisan config:clear
php artisan config:cacheBanyak kasus error di Laravel production terjadi karena developer mengubah .env, tetapi lupa membersihkan cache config. Akibatnya aplikasi tetap membaca konfigurasi lama.
Menjalankan Queue Worker
sudo apt install -y supervisorBuat konfigurasi:
sudo nano /etc/supervisor/conf.d/nama-project-worker.conf
Isi:
[program:nama-project-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/nama-project/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=www-data
numprocs=1
redirect_stderr=true
stdout_logfile=/var/www/nama-project/storage/logs/worker.log
stopwaitsecs=3600Aktifkan:
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start nama-project-worker:*Saat deploy update kode baru, restart queue agar worker membaca kode terbaru:
php artisan queue:restartLaravel menyediakan sistem queue untuk menunda proses berat agar request web lebih cepat, dan worker perlu dikelola dengan benar di server production.
Menjalankan Scheduler Laravel
crontab -eIsi:
* * * * * cd /var/www/nama-project && php artisan schedule:run >> /dev/null 2>&1Scheduler berguna untuk menjalankan tugas berkala seperti kirim email terjadwal, membersihkan data sementara, membuat laporan, atau sinkronisasi data. Laravel menyediakan scheduler agar pengelolaan cron lebih rapi dari dalam aplikasi.
Checklist Setelah Deploy
Setelah aplikasi online, jangan langsung dianggap selesai. Lakukan pengecekan berikut:
- Domain sudah mengarah ke IP VPS.
- Nginx root mengarah ke folder public.
- APP_ENV=production.
- APP_DEBUG=false.
- APP_URL sudah HTTPS.
- Database terkoneksi.
- Migration sudah dijalankan.
- Permission storage dan bootstrap/cache sudah benar.
- Storage link sudah dibuat jika aplikasi memakai upload file.
- SSL aktif dan auto-renewal berjalan.
- Queue worker aktif jika aplikasi memakai queue.
- Scheduler aktif jika aplikasi memakai task terjadwal.
- Log Laravel tidak menampilkan error berulang.
- File .env tidak bisa diakses dari browser.
- Halaman utama, login, upload, email, dan fitur utama sudah diuji.
tail -f storage/logs/laravel.logCek log Nginx:
sudo tail -f /var/log/nginx/error.logDua log ini sangat penting untuk debugging. Jika muncul error 500, jangan menebak. Baca log terlebih dahulu.
Penyebab Error 500 Setelah Upload Laravel ke VPS
- APP_KEY belum dibuat.
- File .env salah konfigurasi.
- Permission storage tidak benar.
- PHP extension kurang.
- Composer dependency belum terinstall.
- Database belum dibuat atau credential salah.
- Config cache masih memakai value lama.
- Versi PHP tidak sesuai.
- Nginx root tidak mengarah ke folder public.
- Queue atau storage gagal menulis file.
