Skip to content

Instantly share code, notes, and snippets.

@sawirricardo
Last active April 16, 2025 05:04
Show Gist options
  • Save sawirricardo/08e6bd526d73b1124a52a6b14189d1dd to your computer and use it in GitHub Desktop.
Save sawirricardo/08e6bd526d73b1124a52a6b14189d1dd to your computer and use it in GitHub Desktop.
Deploy Laravel app to Coolify or any docker-compose deployment
services:
dragonfly:
image: "docker.dragonflydb.io/dragonflydb/dragonfly"
command: ["--requirepass", "${REDIS_PASSWORD}"]
ulimits:
memlock: -1
volumes:
- dragonflydata:/data
postgres:
image: "postgres:17-alpine"
environment:
- POSTGRES_DB=postgres
- POSTGRES_PASSWORD=${DB_PASSWORD}
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d postgres"]
interval: 5s
retries: 10
timeout: 2s
volumes:
- postgresdata:/var/lib/postgresql/data
app:
image: ${REGISTRY_URL:-ghcr.io}/sawirstudio/pingmyweb.com
environment:
- AUTORUN_ENABLED=true
- APP_NAME=${APP_NAME:-PingMyWeb}
- APP_KEY=${APP_KEY}
- APP_DEBUG=${APP_DEBUG:-false}
- APP_ENV=${APP_ENV:-production}
- APP_URL=${APP_URL:-https://pingmyweb.com}
- DB_CONNECTION=pgsql
- DB_DATABASE=postgres
- DB_HOST=postgres
- DB_PORT=5432
- DB_USERNAME=${DB_USERNAME}
- DB_PASSWORD=${DB_PASSWORD}
- QUEUE_CONNECTION=redis
- CACHE_STORE=redis
- REDIS_HOST=dragonfly
- REDIS_PASSWORD=${REDIS_PASSWORD}
healthcheck:
test: curl --fail http://127.0.0.1:8080/up || exit 1
interval: 5s
retries: 10
timeout: 2s
depends_on:
postgres:
condition: service_healthy
dragonfly:
condition: service_healthy
horizon:
image: ${REGISTRY_URL:-ghcr.io}/sawirstudio/pingmyweb.com
command: ["php", "/var/www/html/artisan", "horizon"]
stop_signal: SIGTERM # Set this for graceful shutdown if you're using fpm-apache or fpm-nginx
healthcheck:
# This is our native healthcheck script for Horizon
test: ["CMD", "healthcheck-horizon"]
start_period: 10s
environment:
- APP_KEY=${APP_KEY}
- APP_DEBUG=${APP_DEBUG:-false}
- APP_ENV=${APP_ENV:-production}
- DB_CONNECTION=pgsql
- DB_DATABASE=postgres
- DB_HOST=postgres
- DB_PORT=5432
- DB_USERNAME=${DB_USERNAME}
- DB_PASSWORD=${DB_PASSWORD}
- QUEUE_CONNECTION=redis
- CACHE_STORE=redis
- REDIS_HOST=dragonfly
- REDIS_PASSWORD=${REDIS_PASSWORD}
depends_on:
postgres:
condition: service_healthy
dragonfly:
condition: service_healthy
volumes:
postgresdata:
dragonflydata:
# Versions
# https://hub.docker.com/r/serversideup/php/tags?name=8.4-fpm-nginx-alpine
ARG SERVERSIDEUP_PHP_VERSION=8.4-fpm-nginx-alpine
# https://github.com/minio/mc/releases
ARG MINIO_VERSION=RELEASE.2025-03-12T17-29-24Z
# https://github.com/cloudflare/cloudflared/releases
ARG CLOUDFLARED_VERSION=2025.2.0
# https://www.postgresql.org/support/versioning/
ARG POSTGRES_VERSION=17
# Add user/group
ARG USER_ID=9999
ARG GROUP_ID=9999
# =================================================================
# Stage 1: Composer dependencies
# =================================================================
FROM serversideup/php:${SERVERSIDEUP_PHP_VERSION} AS base
USER root
RUN install-php-extensions bcmath gd intl
ARG USER_ID
ARG GROUP_ID
RUN docker-php-serversideup-set-id www-data $USER_ID:$GROUP_ID && \
docker-php-serversideup-set-file-permissions --owner $USER_ID:$GROUP_ID --service nginx
WORKDIR /var/www/html
COPY --chown=www-data:www-data composer.json composer.lock ./
RUN composer install --no-dev --no-interaction --no-plugins --no-scripts --prefer-dist
USER www-data
# =================================================================
# Stage 2: Frontend assets compilation
# =================================================================
FROM oven/bun:1 AS static-assets
WORKDIR /usr/src/app
# COPY package*.json vite.config.js tailwind.config.js postcss.config.cjs ./
COPY package*.json vite.config.js bun.lockb ./
COPY . .
RUN bun install
RUN bun run build
# # =================================================================
# # Stage 3: Get MinIO client
# # =================================================================
# FROM minio/mc:${MINIO_VERSION} AS minio-client
# =================================================================
# Final Stage: Production image
# =================================================================
FROM serversideup/php:${SERVERSIDEUP_PHP_VERSION}
ARG USER_ID
ARG GROUP_ID
ARG TARGETPLATFORM
ARG POSTGRES_VERSION
ARG CLOUDFLARED_VERSION
ARG CI=true
WORKDIR /var/www/html
USER root
RUN install-php-extensions bcmath gd intl
RUN docker-php-serversideup-set-id www-data $USER_ID:$GROUP_ID && \
docker-php-serversideup-set-file-permissions --owner $USER_ID:$GROUP_ID --service nginx
# Install PostgreSQL repository and keys
RUN apk add --no-cache gnupg && \
mkdir -p /usr/share/keyrings && \
curl -fSsL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor > /usr/share/keyrings/postgresql.gpg
# Install system dependencies
RUN apk add --no-cache \
postgresql${POSTGRES_VERSION}-client \
openssh-client \
git \
git-lfs \
jq \
lsof \
vim
# Configure shell aliases
RUN echo "alias ll='ls -al'" >> /etc/profile && \
echo "alias a='php artisan'" >> /etc/profile && \
echo "alias logs='tail -f storage/logs/laravel.log'" >> /etc/profile
# # Install Cloudflared based on architecture
# RUN mkdir -p /usr/local/bin && \
# if [ "${TARGETPLATFORM}" = "linux/amd64" ]; then \
# curl -sSL "https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-amd64" -o /usr/local/bin/cloudflared; \
# elif [ "${TARGETPLATFORM}" = "linux/arm64" ]; then \
# curl -sSL "https://github.com/cloudflare/cloudflared/releases/download/${CLOUDFLARED_VERSION}/cloudflared-linux-arm64" -o /usr/local/bin/cloudflared; \
# fi && \
# chmod +x /usr/local/bin/cloudflared
# # Configure PHP
# COPY docker/production/etc/php/conf.d/zzz-custom-php.ini /usr/local/etc/php/conf.d/zzz-custom-php.ini
ENV PHP_OPCACHE_ENABLE=1
ENV AUTORUN_LARAVEL_MIGRATION_ISOLATION=true
# # Configure entrypoint
# COPY --chmod=755 docker/production/entrypoint.d/ /etc/entrypoint.d
# Copy application files from previous stages
COPY --from=base --chown=www-data:www-data /var/www/html/vendor ./vendor
COPY --from=static-assets --chown=www-data:www-data /usr/src/app/public/build ./public/build
# Copy application source code
COPY --chown=www-data:www-data composer.json composer.lock ./
COPY --chown=www-data:www-data app ./app
COPY --chown=www-data:www-data bootstrap ./bootstrap
COPY --chown=www-data:www-data config ./config
COPY --chown=www-data:www-data database ./database
# COPY --chown=www-data:www-data lang ./lang
COPY --chown=www-data:www-data public ./public
COPY --chown=www-data:www-data routes ./routes
COPY --chown=www-data:www-data storage ./storage
# COPY --chown=www-data:www-data templates ./templates
COPY --chown=www-data:www-data resources/views ./resources/views
COPY --chown=www-data:www-data artisan artisan
# COPY --chown=www-data:www-data openapi.yaml ./openapi.yaml
RUN composer dump-autoload
# # Configure Nginx and S6 overlay
# COPY docker/production/etc/nginx/conf.d/custom.conf /etc/nginx/conf.d/custom.conf
# COPY docker/production/etc/nginx/site-opts.d/http.conf /etc/nginx/site-opts.d/http.conf
# COPY --chmod=755 docker/production/etc/s6-overlay/ /etc/s6-overlay/
# RUN mkdir -p /etc/nginx/conf.d && \
# chown -R www-data:www-data /etc/nginx && \
# chmod -R 755 /etc/nginx
# # Install MinIO client
# COPY --from=minio-client /usr/bin/mc /usr/bin/mc
# RUN chmod +x /usr/bin/mc
# Switch to non-root user
USER www-data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment