Mendeploy Laravel 11 Inertia Vue ke Coolify menggunakan Docker Compose (dengan dan tanpa SSR)

September 16, 2024 (2mo ago)

Mendeploy Laravel 11 Inertia Vue ke Coolify menggunakan Docker Compose (dengan dan tanpa SSR)

Dalam panduan komprehensif ini, kita akan membahas proses mendeploy aplikasi Laravel 11 dengan Inertia dan Vue.js ke Coolify menggunakan Docker Compose. Kita akan membahas setup Server-Side Rendering (SSR) dan non-SSR, memungkinkan Anda memilih opsi terbaik untuk proyek Anda.

Prasyarat

Sebelum kita mulai, pastikan Anda memiliki hal-hal berikut:

  1. Aplikasi Laravel 11 dengan Inertia dan Vue.js yang sudah disetup
  2. Akun Coolify dan server yang sudah disetup

Langkah 1: Menyiapkan Konfigurasi Docker

Pertama, kita perlu membuat file Dockerfile dan docker-compose.yaml di root proyek Laravel Anda.

Dockerfile

Buat file Dockerfile dengan konten berikut:

FROM php:8.2-apache
 
# Install dependensi sistem
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip \
    libwebp-dev \
    libjpeg62-turbo-dev \
    libfreetype6-dev
 
# Bersihkan cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
 
# Install ekstensi PHP
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath
RUN docker-php-ext-configure gd --with-webp --with-jpeg --with-freetype
RUN docker-php-ext-install -j$(nproc) gd
 
# Aktifkan Apache mod_rewrite
RUN a2enmod rewrite
 
# Dapatkan Composer terbaru
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
 
# Atur direktori kerja
WORKDIR /var/www
 
# Salin konten direktori aplikasi yang ada
COPY . /var/www
 
# Salin file virtual host Apache
COPY docker/apache/000-default.conf /etc/apache2/sites-available/000-default.conf
 
# Salin konfigurasi PHP kustom
COPY docker/php/custom.ini $PHP_INI_DIR/conf.d/
 
# Tingkatkan batas memori PHP
RUN echo "memory_limit = 512M" >> $PHP_INI_DIR/conf.d/docker-php-memlimit.ini
 
# Install dependensi Composer
RUN composer install --no-interaction --no-dev --prefer-dist
 
# Install Node.js dan npm
ENV NODE_VERSION=20.16.0
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
ENV NVM_DIR=/root/.nvm
RUN . "$NVM_DIR/nvm.sh" && nvm install ${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm use v${NODE_VERSION}
RUN . "$NVM_DIR/nvm.sh" && nvm alias default v${NODE_VERSION}
ENV PATH="/root/.nvm/versions/node/v${NODE_VERSION}/bin/:${PATH}"
 
# Install dependensi npm dan build asset
RUN npm install && npm run build
 
# Ubah kepemilikan storage dan bootstrap/cache
RUN chown -R www-data:www-data /var/www/storage /var/www/bootstrap/cache
 
# Pastikan storage dan bootstrap/cache dapat ditulis
RUN chmod -R 775 /var/www/storage /var/www/bootstrap/cache
 
# Salin direktori storage ke direktori .dist
RUN cp -a /var/www/storage /var/www/storage.dist
 
# Salin direktori bootstrap/cache ke direktori .dist
RUN cp -a /var/www/bootstrap/cache /var/www/bootstrap/cache.dist
 
# Salin script entrypoint
COPY docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
 
# Atur sebagai entrypoint
ENTRYPOINT ["docker-entrypoint.sh"]
 
# Ubah root dokumen ke public
ENV APACHE_DOCUMENT_ROOT /var/www/public
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/sites-available/*.conf
RUN sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf
 
EXPOSE 80 443
CMD ["apache2-foreground"]

docker-compose.yaml

Buat file docker-compose.yaml dengan konten berikut:

services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    image: laravel
    container_name: laravel-app
    restart: unless-stopped
    working_dir: /var/www
    volumes:
      - storage:/var/www/storage
      - cache:/var/www/bootstrap/cache
    networks:
      - laravel
    depends_on:
      - db
    healthcheck:
      test:
        - CMD
        - curl
        - "-f"
        - "http://127.0.0.1"
      interval: 2s
      timeout: 10s
      retries: 10
    labels:
      - "traefik.http.middlewares.upload-limit.buffering.maxRequestBodyBytes=67108864"
      - "traefik.http.routers.myapp.middlewares=upload-limit@docker"
 
  scheduler:
    image: laravel
    container_name: laravel-scheduler
    restart: unless-stopped
    command: ["php", "/var/www/artisan", "schedule:work"]
    volumes:
      - storage:/var/www/storage
      - cache:/var/www/bootstrap/cache
    networks:
      - laravel
    depends_on:
      - app
 
  # Uncomment blok berikut jika Anda menggunakan SSR
  # ssr:
  #   image: laravel
  #   container_name: laravel-ssr
  #   restart: unless-stopped
  #   command: ["php", "/var/www/artisan", "inertia:start-ssr"]
  #   volumes:
  #     - storage:/var/www/storage
  #     - cache:/var/www/bootstrap/cache
  #   networks:
  #     - laravel
  #   depends_on:
  #     - app
 
  db:
    image: mariadb:11.4
    container_name: laravel-db
    restart: unless-stopped
    environment:
      MYSQL_DATABASE: ${DB_DATABASE}
      MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
      MYSQL_PASSWORD: ${DB_PASSWORD}
      MYSQL_USER: ${DB_USERNAME}
    volumes:
      - dbdata:/var/lib/mysql
    networks:
      - laravel
    healthcheck:
      test:
        - CMD
        - mariadb-admin
        - ping
        - "-h127.0.0.1"
        - "-uroot"
        - "-p${DB_PASSWORD}"
      interval: 5s
      timeout: 20s
      retries: 10
 
networks:
  laravel:
    driver: bridge
 
volumes:
  storage:
    driver: local
  cache:
    driver: local
  dbdata:
    driver: local

Jika Anda tidak menggunakan SSR, biarkan service ssr tetap dikomentari. Jika Anda menggunakan SSR, hilangkan komentar pada blok service ssr.

Langkah 2: Membuat File Konfigurasi Tambahan

docker-entrypoint.sh

Buat file docker-entrypoint.sh di root proyek Anda:

#!/bin/bash
set -e
 
# Salin konten direktori storage jika volume storage kosong
if [ ! "$(ls -A /var/www/storage)" ]; then
    cp -a /var/www/storage.dist/. /var/www/storage/
fi
 
# Salin konten direktori bootstrap/cache jika volume cache kosong
if [ ! "$(ls -A /var/www/bootstrap/cache)" ]; then
    cp -a /var/www/bootstrap/cache.dist/. /var/www/bootstrap/cache/
fi
 
# Atur izin yang tepat
chown -R www-data:www-data /var/www/storage /var/www/bootstrap/cache
chmod -R 775 /var/www/storage /var/www/bootstrap/cache
 
# Bersihkan dan cache route dan config
php /var/www/artisan route:clear
php /var/www/artisan route:cache
php /var/www/artisan config:clear
php /var/www/artisan config:cache
 
# Jalankan docker-php-entrypoint asli
exec docker-php-entrypoint "$@"

.dockerignore

Buat file .dockerignore di root proyek Anda:

node_modules
vendor
.git
.idea

Konfigurasi Apache

Buat file di docker/apache/000-default.conf:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/public
    Timeout 300
 
    <Directory /var/www/public>
        Options Indexes FollowSymLinks
        AllowOverride All
        Require all granted
    </Directory>
 
    # Menangani HTTPS saat di belakang proxy
    SetEnvIf X-Forwarded-Proto "https" HTTPS=on
 
    # Logging
    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
 
    # Kompresi
    <IfModule mod_deflate.c>
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE text/plain
        AddOutputFilterByType DEFLATE text/xml
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/xml
        AddOutputFilterByType DEFLATE application/xhtml+xml
        AddOutputFilterByType DEFLATE application/rss+xml
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE application/x-javascript
    </IfModule>
 
    # Caching
    <IfModule mod_expires.c>
        ExpiresActive On
        ExpiresByType image/jpg "access plus 1 year"
        ExpiresByType image/jpeg "access plus 1 year"
        ExpiresByType image/gif "access plus 1 year"
        ExpiresByType image/png "access plus 1 year"
        ExpiresByType image/webp "access plus 1 year"
        ExpiresByType text/css "access plus 1 month"
        ExpiresByType application/pdf "access plus 1 month"
        ExpiresByType text/x-javascript "access plus 1 month"
        ExpiresByType application/javascript "access plus 1 month"
        ExpiresByType application/x-shockwave-flash "access plus 1 month"
        ExpiresByType image/x-icon "access plus 1 year"
        ExpiresDefault "access plus 2 days"
    </IfModule>
 
    # Header Keamanan
    <IfModule mod_headers.c>
        Header set X-Content-Type-Options "nosniff"
        Header set X-Frame-Options "DENY"
        Header set X-XSS-Protection "1; mode=block"
        Header set Referrer-Policy "no-referrer-when-downgrade"
    </IfModule>
 
    # Batasi body request ke 64MB
    LimitRequestBody 67108864
</VirtualHost>

Konfigurasi PHP

Buat file di docker/php/custom.ini:

upload_max_filesize = 64M
post_max_size = 64M
max_execution_time = 300
max_input_time = 300
memory_limit = 512M

Langkah 3: Menyiapkan Aplikasi Laravel Anda

  1. Jika Anda menggunakan SSR, pastikan Anda telah mengatur Inertia SSR dengan benar di aplikasi Laravel Anda.
  2. Modifikasi app/Providers/AppServiceProvider.php Anda untuk memaksa penggunaan HTTPS di produksi:
<?php
 
namespace App\Providers;
 
use Illuminate\Support\Facades\URL;
use Illuminate\Support\ServiceProvider;
 
class AppServiceProvider extends ServiceProvider
{
    public function register(): void
    {
        //
    }
 
    public function boot(): void
    {
        if ($this->app->environment('production')) {
            URL::forceScheme('https');
        }
    }
}

Perubahan ini memastikan bahwa semua URL yang dihasilkan oleh aplikasi Anda di produksi akan menggunakan HTTPS.

Langkah 4: Deploy ke Coolify

  1. Masuk ke dashboard Coolify Anda.
  2. Hubungkan repositori Git Anda ke Coolify.
  3. Buat proyek baru dan pilih "Docker Compose" sebagai metode deployment.
  4. Di pengaturan proyek Coolify, pastikan untuk mengatur variabel lingkungan berikut:
    • DB_HOST: Atur ini ke nama service database Anda di file Docker Compose (mis., db)
    • DB_DATABASE: Nama database Anda
    • DB_USERNAME: Username database Anda
    • DB_PASSWORD: Password database Anda
    • Variabel lingkungan spesifik lainnya yang dibutuhkan aplikasi Anda di .env
  5. Konfigurasi pengaturan deployment:
    • Atur nama container
    • Atur nama domain
    • Atur perintah post-deployment berikut:
      php artisan storage:link
      
      Perintah ini akan membuat symlink dari public/storage ke storage/app/public.
  6. Simpan konfigurasi Anda dan deploy aplikasi Anda.

Langkah 5: Tugas Pasca-Deployment

Setelah berhasil di-deploy, pergi ke tab Command. Jalankan perintah berikut:

php artisan migrate --force

Perintah ini akan menjalankan migrasi database Anda, memastikan skema database Anda up to date.

Kesimpulan

Anda sekarang telah berhasil mendeploy aplikasi Laravel 11 Inertia Vue ke Coolify menggunakan Docker Compose, dengan opsi untuk setup SSR dan non-SSR. Konfigurasi ini menyediakan infrastruktur yang dapat diskalakan dan mudah dikelola untuk aplikasi Anda.

Poin-poin penting yang perlu diingat:

  1. Modifikasi AppServiceProvider memastikan penggunaan HTTPS di lingkungan produksi.
  2. Perintah php artisan storage:link dijalankan sebagai tugas pasca-deployment untuk mengatur linking storage yang tepat.
  3. Migrasi database dijalankan menggunakan tab Command Coolify setelah deployment.

Ingatlah untuk memantau kinerja dan log aplikasi Anda, dan lakukan penyesuaian seperlunya untuk mengoptimalkan operasinya di lingkungan produksi. Jika Anda menggunakan SSR, perhatikan layanan SSR untuk memastikan berjalan dengan lancar dan memberikan manfaat kinerja yang diharapkan.

Selamat mendeploy!