Cara Deploy Laravel dari GitHub ke VPS (Manual + GitHub Actions)

pindipin
23 September 2026
14 min read
Cara Deploy Laravel dari GitHub ke VPS (Manual + GitHub Actions)

Memindahkan aplikasi Laravel dari lingkungan lokal atau shared hosting ke Virtual Private Server (VPS) memberikan kontrol penuh atas performa, keamanan, dan konfigurasi server. Namun, mengelola server sendiri menuntut pemahaman alur instalasi stack yang tepat serta pengaturan hak akses folder yang aman. Jika alur deployment dilakukan secara manual dengan perintah copy-paste berulang kali, risiko kesalahan manusia (human error) saat merilis fitur baru menjadi sangat tinggi.

Solusi terbaik untuk masalah ini adalah membangun alur deployment otomatis berbasis CI/CD (Continuous Integration / Continuous Deployment) menggunakan GitHub Actions. Setiap kali kode baru di-push ke repository, GitHub Actions akan terhubung ke VPS melalui SSH dan mengeksekusi script deployment secara konsisten. Jika kamu ingin mendalami pengelolaan alur kerja repository Git yang rapi sebelum memasang CI/CD, pelajari juga panduan workflow Git Laravel.

Artikel ini membahas panduan komprehensif mulai dari persiapan awal VPS Ubuntu (22.04 / 24.04 LTS), konfigurasi stack Nginx dan PHP-FPM, deployment manual pertama kali, hingga otomatisasi penuh menggunakan GitHub Actions.


1. Persiapan Environment Server VPS (Ubuntu Stack Setup)

Langkah awal adalah menyiapkan server VPS yang masih bersih (fresh install). OS yang direkomendasikan adalah Ubuntu 22.04 LTS atau 24.04 LTS karena stabilitas dan dukungan paket perangkat lunaknya yang luas.

1.1 Update Perangkat Lunak & Keamanan Dasar SSH

Sebelum menginstal stack web server, perbarui indeks paket sistem terlebih dahulu.

sudo apt update && sudo apt upgrade -y

Sangat tidak disarankan menggunakan user root untuk kebutuhan operasional sehari-hari dan deployment. Buat user baru dengan akses sudo (misalnya user deployer):

sudo adduser deployer
sudo usermod -aG sudo deployer

Pindah ke user deployer dan buat folder .ssh untuk mendaftarkan public key SSH komputer kamu:

su - deployer
mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys

Setelah meletakkan public key di file authorized_keys, uji koneksi SSH dari terminal lokal tanpa kata sandi. Jika berhasil, matikan autentikasi kata sandi dan otorisasi root pada file /etc/ssh/sshd_config:

PasswordAuthentication no
PermitRootLogin no

Restart layanan SSH setelah mengubah konfigurasi:

sudo systemctl restart ssh

1.2 Instalasi Web Server (Nginx) & PHP-FPM

Aplikasi Laravel membutuhkan web server seperti Nginx dan runtime PHP beserta beberapa ekstensi spesifik. Install Nginx dan PHP versi 8.3 (atau 8.2 sesuai kebutuhan proyek) dengan perintah berikut:

sudo apt install -y nginx php8.3-fpm php8.3-cli php8.3-mbstring \
php8.3-xml php8.3-bcmath php8.3-curl php8.3-mysql php8.3-sqlite3 \
php8.3-zip php8.3-gd php8.3-intl unzip git

Pastikan layanan Nginx dan PHP-FPM sudah berjalan aktif di latar belakang:

sudo systemctl status nginx
sudo systemctl status php8.3-fpm

1.3 Instalasi Composer & Node.js

Composer diperlukan untuk mengelola dependensi PHP, sedangkan Node.js dan NPM digunakan untuk mengompilasi asset frontend (Vite / Tailwind CSS).

Instal Composer secara global ke direktori /usr/local/bin:

curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
sudo chmod +x /usr/local/bin/composer

Untuk menginstal Node.js versi LTS terbaru (misal Node.js 20), gunakan script dari NodeSource:

curl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt install -y nodejs

Verifikasi versi yang terinstal:

composer --version
node -v
npm -v

1.4 Instalasi & Konfigurasi Database (MySQL)

Install MySQL Server pada VPS:

sudo apt install -y mysql-server
sudo mysql_secure_installation

Masuk ke CLI MySQL untuk membuat database dan user khusus aplikasi Laravel:

CREATE DATABASE laravel_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'PasswordSangatRahas1a!';
GRANT ALL PRIVILEGES ON laravel_db.* TO 'laravel_user'@'localhost';
FLUSH PRIVILEGES;
EXIT;

1.5 Instalasi Supervisor & Setup Laravel Scheduler

Laravel menggunakan queue untuk memproses task latar belakang (seperti pengiriman email atau pemrosesan gambar). Supervisor bertugas memastikan queue worker Laravel terus berjalan dan otomatis melakukan restart jika terjadi crash.

Install Supervisor:

sudo apt install -y supervisor

Buat file konfigurasi worker baru di /etc/supervisor/conf.d/laravel-worker.conf:

[program:laravel-worker]
process_name=%(program_name)s_%(process_num)02d
command=php /var/www/my-laravel-app/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=deployer
numprocs=2
redirect_stderr=true
stdout_logfile=/var/www/my-laravel-app/storage/logs/worker.log
stopwaitsecs=3600

Informasikan Supervisor untuk membaca konfigurasi baru dan memulainya:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start laravel-worker:*

Untuk task scheduling (Laravel Scheduler), tambahkan baris cron job menggunakan perintah crontab -e pada user deployer:

* * * * * cd /var/www/my-laravel-app && php artisan schedule:run >> /dev/null 2>&1

2. Deployment Manual Pertama Kali (Initial Setup)

Sebelum mengkonfigurasi otomatisasi CI/CD, lakukan deployment manual terlebih dahulu untuk memastikan struktur direktori, izin akses, file .env, dan server block Nginx berfungsi dengan benar.

2.1 Mendaftarkan SSH Deploy Key di GitHub

Agar server VPS dapat menarik kode (pull) dari repository private GitHub tanpa mengetik kata sandi, buat pasangan SSH Deploy Key khusus pada VPS:

ssh-keygen -t ed25519 -C "vps-deploy-key" -f ~/.ssh/id_ed25519_github -N ""

Tampilkan public key yang dihasilkan:

cat ~/.ssh/id_ed25519_github.pub

Salin teks public key tersebut, lalu buka repository proyek kamu di GitHub:

  1. Masuk ke Settings > Deploy keys.
  2. Klik Add deploy key.
  3. Berikan judul (misal: VPS Production Server).
  4. Tempelkan isi public key dan simpan (centang Allow write access jika dibutuhkan, namun untuk deploy key biasanya akses read-only sudah cukup).

Tambahkan konfigurasi SSH client pada VPS di ~/.ssh/config agar perintah Git otomatis menggunakan private key tersebut:

Host github.com
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_ed25519_github
    IdentitiesOnly yes

Uji koneksi SSH ke GitHub:

ssh -T git@github.com

2.2 Clone Repository & Konfigurasi File Environment

Buat direktori tujuan di /var/www/my-laravel-app dan sesuaikan kepemilikan direktori awal:

sudo mkdir -p /var/www/my-laravel-app
sudo chown -R deployer:www-data /var/www/my-laravel-app

Clone repository GitHub ke direktori tersebut:

git clone git@github.com:username/repository-name.git /var/www/my-laravel-app
cd /var/www/my-laravel-app

Salin file contoh konfigurasi .env.example menjadi .env:

cp .env.example .env
nano .env

Buka file .env dan sesuaikan parameter utama untuk lingkungan produksi:

APP_NAME="Laravel Pro"
APP_ENV=production
APP_KEY=
APP_DEBUG=false
APP_URL=https://example.com

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=laravel_user
DB_PASSWORD=PasswordSangatRahas1a!

2.3 Hak Akses & Kepemilikan Direktori (Folder Permissions)

Salah satu penyebab paling umum terjadinya kesalahan HTTP 500 saat deploy Laravel adalah salah konfigurasi hak akses folder. Web server Nginx berjalan di bawah user/group www-data, sedangkan kita mengelola kode dengan user deployer.

Tambahkan user deployer ke dalam grup www-data:

sudo usermod -aG www-data deployer

Atur kepemilikan folder ke deployer:www-data:

sudo chown -R deployer:www-data /var/www/my-laravel-app

Berikan akses baca dan tulis bagi grup pada folder storage dan bootstrap/cache:

sudo find /var/www/my-laravel-app -type f -exec chmod 644 {} \;
sudo find /var/www/my-laravel-app -type d -exec chmod 755 {} \;

sudo chmod -R 775 /var/www/my-laravel-app/storage
sudo chmod -R 775 /var/www/my-laravel-app/bootstrap/cache

2.4 Instalasi Dependensi, Migrasi, & Optimasi Cache

Jalankan instalasi dependensi Composer tanpa paket development:

composer install --no-dev --optimize-autoloader

Generate kunci aplikasi (application key):

php artisan key:generate

Jalankan migrasi database dengan flag --force (flag ini wajib digunakan di lingkungan produksi agar artisan tidak meminta konfirmasi interaktif):

php artisan migrate --force

Buat symbolic link untuk direktori penyimpanan media publik:

php artisan storage:link

Install dependensi Node.js dan build asset frontend:

npm ci
npm run build

Lakukan optimasi performa Laravel dengan memuat konfigurasi, route, dan view ke dalam memori cache:

php artisan config:cache
php artisan route:cache
php artisan view:cache

2.5 Konfigurasi Server Block Nginx

Buat file konfigurasi Nginx baru di /etc/nginx/sites-available/my-laravel-app:

sudo nano /etc/nginx/sites-available/my-laravel-app

Masukkan konfigurasi baku Nginx untuk Laravel berikut:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    root /var/www/my-laravel-app/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

    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:/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;
    }
}

Aktifkan konfigurasi situs dengan membuat symlink ke folder sites-enabled:

sudo ln -s /etc/nginx/sites-available/my-laravel-app /etc/nginx/sites-enabled/

Uji sintaks Nginx dan lakukan reload:

sudo nginx -t
sudo systemctl reload nginx

2.6 Aktivasi SSL HTTPS dengan Certbot (Let's Encrypt)

Gunakan Certbot untuk memasang sertifikat SSL gratis secara otomatis:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

Certbot akan otomatis memperbarui file konfigurasi Nginx kamu untuk mengalihkan seluruh lalu lintas HTTP ke HTTPS secara aman.


3. Membuat Script Deployment Otomatis (deploy.sh)

Melakukan rilis kode baru secara manual memerlukan banyak langkah berurutan. Jika ada satu langkah yang terlewat (misalnya lupa menjalankan php artisan queue:restart), aplikasi bisa mengalami perilaku yang membingungkan.

Buat sebuah script bash pembantu bernama deploy.sh di dalam folder proyek /var/www/my-laravel-app/deploy.sh:

nano /var/www/my-laravel-app/deploy.sh

Isi file deploy.sh dengan baris perintah berikut:

#!/bin/bash
set -e

echo "=== Memulai Proses Deployment ==="

# 1. Pastikan berada di direktori proyek
cd /var/www/my-laravel-app

# 2. Ambil perubahan kode terbaru dari branch main
echo "Mengunduh kode terbaru dari Git..."
git pull origin main

# 3. Install/Update dependensi PHP
echo "Menginstal dependensi Composer..."
composer install --no-dev --optimize-autoloader

# 4. Jalankan migrasi database
echo "Menjalankan migrasi database..."
php artisan migrate --force

# 5. Build asset frontend (Opsional jika dilakukan di server)
echo "Mengompilasi asset frontend..."
npm ci
npm run build

# 6. Rebuild cache aplikasi
echo "Memperbarui cache konfigurasi, route, dan view..."
php artisan config:cache
php artisan route:cache
php artisan view:cache

# 7. Restart queue worker agar membaca kode baru
echo "Merestart Laravel Queue Worker..."
php artisan queue:restart

echo "=== Deployment Berhasil Selesai! ==="

Berikan hak akses eksekusi pada script tersebut:

chmod +x /var/www/my-laravel-app/deploy.sh

Uji eksekusi script secara langsung dari terminal VPS untuk memastikan tidak ada perintah yang error:

/var/www/my-laravel-app/deploy.sh

4. Otomatisasi CI/CD dengan GitHub Actions

Dengan script deploy.sh yang sudah siap di VPS, kini kamu bisa mengkonfigurasi GitHub Actions agar mengeksekusi script tersebut secara otomatis setiap kali ada penambahan kode (push) ke branch main. Penataan pipeline ini melengkapi panduan workflow Git Laravel dalam siklus pengolahan kode yang modern.

4.1 Menyiapkan SSH Key Khusus GitHub Actions

GitHub Actions membutuhkan private key SSH untuk masuk ke VPS sebagai user deployer.

Buat pasangan kunci SSH baru di komputer lokal atau VPS khusus untuk GitHub Actions:

ssh-keygen -t ed25519 -C "github-actions-deploy" -f ~/.ssh/github_actions_vps -N ""

Tambahkan isi dari github_actions_vps.pub ke file ~/.ssh/authorized_keys milik user deployer di VPS:

cat ~/.ssh/github_actions_vps.pub >> ~/.ssh/authorized_keys

4.2 Menambahkan GitHub Encrypted Secrets

Buka repository proyek kamu di GitHub:

  1. Navigasi ke Settings > Secrets and variables > Actions.
  2. Klik tombol New repository secret.
  3. Daftarkan 4 variabel rahasia berikut:
Nama SecretNilai / Isi
VPS_HOSTIP Public server VPS kamu (contoh: 103.170.xx.xx atau example.com)
VPS_USERNAMEUsername SSH di VPS (deployer)
VPS_SSH_KEYIsi lengkap dari private key github_actions_vps (termasuk baris -----BEGIN OPENSSH PRIVATE KEY-----)
VPS_PORTPort SSH server kamu (default: 22)

4.3 Membuat File Workflow GitHub Actions (.github/workflows/deploy.yml)

Di dalam proyek Laravel lokal kamu, buat direktori .github/workflows dan buat file deploy.yml:

name: Deploy Laravel to VPS

on:
  push:
    branches:
      - main

jobs:
  deploy:
    name: Execute Remote Deployment Script
    runs-on: ubuntu-latest

    steps:
      - name: Trigger Remote Deploy Script via SSH
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USERNAME }}
          key: ${{ secrets.VPS_SSH_KEY }}
          port: ${{ secrets.VPS_PORT }}
          script: |
            cd /var/www/my-laravel-app
            ./deploy.sh

Commit file deploy.yml dan lakukan push ke GitHub:

git add .github/workflows/deploy.yml
git commit -m "ci: add github actions vps deployment workflow"
git push origin main

Buka tab Actions di repository GitHub kamu. Kamu akan melihat workflow baru berjalan secara otomatis, terhubung ke VPS melalui SSH, dan mengeksekusi script deploy.sh.


5. Optimasi Spesifikasi Rendah (Vite Build di GitHub Actions Runner)

Jika VPS kamu memiliki spesifikasi RAM terbatas (misalnya 1GB tanpa SWAP), menjalankan perintah npm run build di dalam server VPS sering kali menyebabkan kegagalan akibat masalah Out of Memory (OOM).

Solusi terbaiknya adalah mengompilasi asset frontend langsung di dalam runner gratis milik GitHub Actions, kemudian mengunggah folder hasil kompilasi (public/build) ke VPS menggunakan rsync atau scp.

Berikut adalah alternatif konfigurasi .github/workflows/deploy.yml untuk skenario build asset di runner:

name: Deploy Laravel to VPS (Build Asset on Runner)

on:
  push:
    branches:
      - main

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout Code
        uses: actions/checkout@v4

      - name: Setup Node.js Environment
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: 'npm'

      - name: Install Frontend Dependencies & Build Assets
        run: |
          npm ci
          npm run build

      - name: Copy Built Assets to VPS via Rsync
        uses: Burnett01/rsync-deployments@v7.0.1
        with:
          switches: -avzr --delete
          path: public/build/
          remote_path: /var/www/my-laravel-app/public/build/
          remote_host: ${{ secrets.VPS_HOST }}
          remote_port: ${{ secrets.VPS_PORT }}
          remote_user: ${{ secrets.VPS_USERNAME }}
          remote_key: ${{ secrets.VPS_SSH_KEY }}

      - name: Execute Server Deployment Commands
        uses: appleboy/ssh-action@v1.0.3
        with:
          host: ${{ secrets.VPS_HOST }}
          username: ${{ secrets.VPS_USERNAME }}
          key: ${{ secrets.VPS_SSH_KEY }}
          port: ${{ secrets.VPS_PORT }}
          script: |
            cd /var/www/my-laravel-app
            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

Dengan metode ini, beban kompilasi CSS dan JS dipindahkan penuh ke infrastruktur GitHub Actions, sehingga server VPS tetap dingin dan hemat memori.


6. Practical Pitfalls & Cara Mengatasinya

Dalam rilis aplikasi Laravel di lingkungan nyata, ada beberapa kendala teknis yang sering ditemui. Berikut adalah perincian masalah dan langkah pemecahannya:

6.1 Permisi File & Kesalahan HTTP 500 (Permission Denied)

Jika aplikasi menampilkan halaman kosong atau error 500 setelah deploy, penyebab utamanya hampir selalu berkaitan dengan izin akses folder storage dan bootstrap/cache.

Ketika proses git pull dilakukan oleh user deployer, file baru yang ditarik mungkin tidak bisa ditulis oleh Nginx (www-data).

Solusi:
Pastikan umask user deployer dikonfigurasi agar membuat file dengan izin grup yang dapat ditulis. Atau pastikan script deploy.sh menyertakan penyesuaian izin akses jika diperlukan:

sudo chown -R deployer:www-data /var/www/my-laravel-app/storage /var/www/my-laravel-app/bootstrap/cache
sudo chmod -R 775 /var/www/my-laravel-app/storage /var/www/my-laravel-app/bootstrap/cache

6.2 Prompt Konfirmasi Migrasi Database di Produksi

Secara bawaan, perintah php artisan migrate di lingkungan APP_ENV=production akan menghentikan eksekusi dan meminta konfirmasi interaktif: Application In Production! Do you really wish to run command?.

Dalam alur CI/CD otomatis tanpa terminal interaktif, hal ini membuat proses deploy menggantung (hang) hingga waktu eksekusi runner habis (timeout).

Solusi:
Wajib menggunakan flag --force pada perintah migrasi di script deployment:

php artisan migrate --force

6.3 Queue Worker Masih Menggunakan Kode Lama

Laravel memuat seluruh kode aplikasi ke dalam memori (RAM) saat proses queue:work dinyalakan. Jika kamu memperbarui kode logika di Controller atau Job lalu melakukan git pull, worker Supervisor tidak akan otomatis menyadari perubahan tersebut dan tetap mengeksekusi logika lama.

Solusi:
Selalu sertakan perintah php artisan queue:restart di akhir alur deployment. Perintah ini memberi instruksi halus (graceful signal) kepada worker untuk berhenti setelah menyelesaikan tugas berjalan, dan Supervisor akan otomatis menyalakan instance worker baru dengan kode aplikasi paling mutakhir.

6.4 Error Host Key Verification Failed pada SSH Action

Jika job GitHub Actions gagal pada tahap SSH dengan pesan kesalahan Host key verification failed, artinya runner tidak mengenali fingerprint server VPS kamu.

Solusi:
Action appleboy/ssh-action sebenarnya menangani hal ini secara otomatis. Namun jika kamu menggunakan perintah SSH native dalam runner, pastikan kamu menambahkan fingerprint VPS menggunakan ssh-keyscan:

- name: Scan SSH Host Keys
  run: |
    mkdir -p ~/.ssh
    ssh-keyscan -H ${{ secrets.VPS_HOST }} >> ~/.ssh/known_hosts

7. Penutup

Mengonfigurasi server VPS Ubuntu dari awal dan mengintegrasikannya dengan GitHub Actions memberikan alur deployment yang stabil, cepat, dan terhindar dari human error. Langkah utama yang telah diselesaikan meliputi:

  1. Menyiapkan stack web server (Nginx, PHP 8.3-FPM, MySQL, Composer, Supervisor).
  2. Mengatur skema perizinan direktori yang aman antara user deployer dan grup www-data.
  3. Menyusun script deployment (deploy.sh) yang menangani migrasi, pembersihan cache, dan restart worker.
  4. Mengotomatiskan eksekusi rilis menggunakan GitHub Actions via SSH Secrets.

Rekomendasi Langkah Selanjutnya

Untuk skala proyek yang lebih besar atau sistem dengan transaksi tinggi, kamu dapat mempertimbangkan beberapa peningkatan infrastruktur berikut:

  • Zero-Downtime Deployment: Implementasikan alat rilis berbasis release directory symlinks seperti Deployer.php atau Laravel Envoyer. Metode ini menyiapkan rilis baru di folder terpisah sebelum memindahkan symlink web server, sehingga aplikasi tidak mengalami downtime sama sekali saat proses rilis berlangsung.
  • Error & Log Monitoring: Pasang alat pemantau error otomatis seperti Sentry, Bugsnag, atau Laravel Pulse/Telescope di produksi agar setiap kesalahan runtime setelah deployment dapat terdeteksi secara real-time.

Referensi Terkait

Bagikan Artikel:
Diskusi & Komentar

Fitur komentar belum diaktifkan oleh administrator.

Artikel Terkait

Selesai membaca? Kembali ke beranda untuk melihat artikel menarik lainnya.

Kembali ke Beranda