Add Docker and Nginx configuration for Cloud Run deployment
This commit is contained in:
18
.dockerignore
Normal file
18
.dockerignore
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
.git
|
||||||
|
.gitignore
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
.editorconfig
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.md
|
||||||
|
docker-compose.yml
|
||||||
|
Dockerfile
|
||||||
|
vendor/
|
||||||
|
node_modules/
|
||||||
|
storage/framework/cache/**
|
||||||
|
storage/framework/sessions/**
|
||||||
|
storage/framework/views/**
|
||||||
|
storage/logs/**
|
||||||
|
tests/
|
||||||
|
phpunit.xml
|
||||||
101
Dockerfile
101
Dockerfile
@@ -1,46 +1,81 @@
|
|||||||
# Use the official PHP image based on Alpine Linux
|
# Build stage
|
||||||
FROM php:5.6-fpm-alpine
|
FROM php:5.6-fpm-alpine as composer
|
||||||
|
|
||||||
# Install system dependencies and PHP extensions
|
# Install system dependencies and PHP extensions required for Composer
|
||||||
RUN apk --update --no-cache add \
|
RUN apk add --no-cache \
|
||||||
nginx \
|
git \
|
||||||
libpng-dev \
|
curl \
|
||||||
libjpeg-turbo-dev \
|
|
||||||
freetype-dev \
|
|
||||||
libzip-dev \
|
|
||||||
zip \
|
zip \
|
||||||
unzip \
|
unzip \
|
||||||
|
libmcrypt \
|
||||||
libmcrypt-dev \
|
libmcrypt-dev \
|
||||||
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
|
zlib-dev \
|
||||||
&& docker-php-ext-install gd pdo pdo_mysql zip mcrypt
|
libzip-dev \
|
||||||
|
autoconf \
|
||||||
|
make \
|
||||||
|
gcc \
|
||||||
|
g++ \
|
||||||
|
&& docker-php-ext-install mcrypt mbstring zip \
|
||||||
|
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
|
||||||
|
&& composer self-update --1
|
||||||
|
|
||||||
|
ENV COMPOSER_ALLOW_SUPERUSER=1
|
||||||
|
WORKDIR /app
|
||||||
|
COPY composer.* ./
|
||||||
|
|
||||||
|
# Install dependencies with Composer (optimize later after full copy)
|
||||||
|
RUN composer config platform.php 5.6.40 \
|
||||||
|
&& composer install --prefer-dist --no-dev --no-scripts --no-autoloader
|
||||||
|
|
||||||
|
# Copy the rest of the application and optimize autoload
|
||||||
|
COPY . .
|
||||||
|
RUN composer dump-autoload --optimize --no-dev --classmap-authoritative
|
||||||
|
|
||||||
|
# Production stage
|
||||||
|
FROM php:5.6-fpm-alpine
|
||||||
|
|
||||||
|
# Install runtime dependencies & build PHP extensions
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
nginx \
|
||||||
|
curl \
|
||||||
|
libpng \
|
||||||
|
libjpeg-turbo \
|
||||||
|
freetype \
|
||||||
|
libzip \
|
||||||
|
libmcrypt \
|
||||||
|
zlib \
|
||||||
|
&& apk add --no-cache --virtual .build-deps \
|
||||||
|
autoconf make gcc g++ \
|
||||||
|
libpng-dev libjpeg-turbo-dev freetype-dev libzip-dev libmcrypt-dev zlib-dev \
|
||||||
|
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
|
||||||
|
&& docker-php-ext-install -j"$(nproc)" gd pdo pdo_mysql zip mcrypt mbstring opcache \
|
||||||
|
&& docker-php-ext-enable mcrypt \
|
||||||
|
&& apk del .build-deps \
|
||||||
|
&& php -m | grep -i mcrypt
|
||||||
|
|
||||||
|
# Configure PHP for production
|
||||||
|
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \
|
||||||
|
&& echo "opcache.enable=1" >> /usr/local/etc/php/conf.d/opcache.ini \
|
||||||
|
&& echo "opcache.memory_consumption=128" >> /usr/local/etc/php/conf.d/opcache.ini \
|
||||||
|
&& echo "opcache.interned_strings_buffer=8" >> /usr/local/etc/php/conf.d/opcache.ini \
|
||||||
|
&& echo "opcache.max_accelerated_files=4000" >> /usr/local/etc/php/conf.d/opcache.ini \
|
||||||
|
&& echo "opcache.revalidate_freq=60" >> /usr/local/etc/php/conf.d/opcache.ini \
|
||||||
|
&& echo "opcache.fast_shutdown=1" >> /usr/local/etc/php/conf.d/opcache.ini
|
||||||
|
|
||||||
# Set the working directory in the container
|
|
||||||
WORKDIR /var/www
|
WORKDIR /var/www
|
||||||
|
|
||||||
# Clear cache
|
# Copy vendor & app code from build stage
|
||||||
# RUN apt-get clean && rm -rf /var/lib/apt/lists/*
|
COPY --from=composer /app/vendor ./vendor
|
||||||
|
|
||||||
# Copy the Laravel application files to the container
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
# Set appropriate permissions for Laravel storage and bootstrap cache
|
# Set appropriate permissions and create required directories
|
||||||
RUN chown -R www-data:www-data storage bootstrap
|
RUN chown -R www-data:www-data storage bootstrap \
|
||||||
|
&& mkdir -p /run/php \
|
||||||
|
&& chown www-data:www-data /run/php \
|
||||||
|
&& php artisan key:generate || true
|
||||||
|
|
||||||
# Install Composer
|
# Healthcheck (FPM listens on 9000; adjust as needed if behind nginx)
|
||||||
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
HEALTHCHECK --interval=30s --timeout=5s CMD php -m > /dev/null || exit 1
|
||||||
|
|
||||||
# Install Laravel dependencies
|
|
||||||
RUN composer install --no-plugins --no-scripts
|
|
||||||
|
|
||||||
# Generate Laravel application key
|
|
||||||
RUN php artisan key:generate
|
|
||||||
|
|
||||||
# Create directory for the socket and set permissions
|
|
||||||
RUN mkdir -p /run/php && chown www-data:www-data /run/php
|
|
||||||
|
|
||||||
# Copy the www.conf file to PHP-FPM pool.d directory
|
|
||||||
# COPY www.conf /usr/local/etc/php-fpm.d/www.conf
|
|
||||||
|
|
||||||
# Expose port 9000 and start php-fpm server
|
|
||||||
EXPOSE 9000
|
EXPOSE 9000
|
||||||
CMD ["php-fpm"]
|
CMD ["php-fpm"]
|
||||||
72
cloudrun/Dockerfile.cloudrun
Normal file
72
cloudrun/Dockerfile.cloudrun
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
# Combined image for Cloud Run: nginx + php-fpm (PHP 5.6) for legacy Laravel 5
|
||||||
|
# NOTE: PHP 5.6 is EOL; use only for legacy maintenance. Consider upgrading.
|
||||||
|
|
||||||
|
FROM php:5.6-fpm
|
||||||
|
|
||||||
|
# Set build args/env
|
||||||
|
ARG APP_ENV=production
|
||||||
|
ENV APP_ENV=${APP_ENV} \
|
||||||
|
APP_DEBUG=false \
|
||||||
|
OPCACHE_VALIDATE_TIMESTAMPS=0 \
|
||||||
|
COMPOSER_ALLOW_SUPERUSER=1 \
|
||||||
|
PORT=8080 \
|
||||||
|
PATH="/var/www/artisan:$PATH"
|
||||||
|
|
||||||
|
WORKDIR /var/www
|
||||||
|
|
||||||
|
# Install system deps (Debian variant easier than alpine for mixed services)
|
||||||
|
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
|
||||||
|
git curl unzip zip supervisor nginx \
|
||||||
|
libmcrypt4 libmcrypt-dev \
|
||||||
|
libpng-dev libjpeg62-turbo-dev libfreetype6-dev libzip-dev zlib1g-dev \
|
||||||
|
&& docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ \
|
||||||
|
&& docker-php-ext-install gd mcrypt mbstring pdo pdo_mysql zip opcache \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Install Composer (v1)
|
||||||
|
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
|
||||||
|
&& composer self-update --1
|
||||||
|
|
||||||
|
# Copy composer files & install deps first (cache layer)
|
||||||
|
COPY composer.* ./
|
||||||
|
RUN composer config platform.php 5.6.40 \
|
||||||
|
&& composer install --no-dev --no-scripts --no-autoloader --prefer-dist
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
COPY . .
|
||||||
|
RUN composer dump-autoload --optimize --no-dev --classmap-authoritative || true
|
||||||
|
|
||||||
|
# Nginx config
|
||||||
|
COPY cloudrun/nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|
||||||
|
# Supervisord config
|
||||||
|
COPY cloudrun/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||||
|
|
||||||
|
# Remove default nginx site configs if present
|
||||||
|
RUN rm -f /etc/nginx/sites-enabled/default /etc/nginx/conf.d/default.conf || true
|
||||||
|
|
||||||
|
# Create runtime dirs
|
||||||
|
RUN mkdir -p /run/php /var/log/supervisor /var/www/storage /var/www/bootstrap/cache \
|
||||||
|
&& chown -R www-data:www-data /var/www/storage /var/www/bootstrap/cache
|
||||||
|
|
||||||
|
# PHP production ini tweaks
|
||||||
|
RUN { \
|
||||||
|
echo "opcache.enable=1"; \
|
||||||
|
echo "opcache.memory_consumption=128"; \
|
||||||
|
echo "opcache.interned_strings_buffer=8"; \
|
||||||
|
echo "opcache.max_accelerated_files=4000"; \
|
||||||
|
echo "opcache.revalidate_freq=60"; \
|
||||||
|
echo "opcache.fast_shutdown=1"; \
|
||||||
|
echo "date.timezone=UTC"; \
|
||||||
|
} > /usr/local/etc/php/conf.d/zz-custom.ini
|
||||||
|
|
||||||
|
# Generate app key if missing (non-fatal if artisan fails early)
|
||||||
|
RUN php artisan key:generate || true
|
||||||
|
|
||||||
|
# Cloud Run listens on $PORT
|
||||||
|
EXPOSE 8080
|
||||||
|
|
||||||
|
# Health check path suggestion: /healthz (configure in Cloud Run if desired)
|
||||||
|
|
||||||
|
# Start supervisor (manages php-fpm + nginx)
|
||||||
|
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]
|
||||||
42
cloudrun/nginx.conf
Normal file
42
cloudrun/nginx.conf
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
user nginx;
|
||||||
|
worker_processes auto;
|
||||||
|
error_log /dev/stderr warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events { worker_connections 1024; }
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
access_log /dev/stdout main;
|
||||||
|
sendfile on;
|
||||||
|
keepalive_timeout 65;
|
||||||
|
server_tokens off;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 8080 default_server;
|
||||||
|
listen [::]:8080 default_server;
|
||||||
|
root /var/www/public;
|
||||||
|
index index.php index.html;
|
||||||
|
|
||||||
|
location /healthz { return 200 'ok'; add_header Content-Type text/plain; }
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_pass 127.0.0.1:9000; # php-fpm
|
||||||
|
fastcgi_index index.php;
|
||||||
|
fastcgi_buffers 16 16k;
|
||||||
|
fastcgi_buffer_size 32k;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
|
||||||
|
expires 30d;
|
||||||
|
access_log off;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
cloudrun/supervisord.conf
Normal file
24
cloudrun/supervisord.conf
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
[supervisord]
|
||||||
|
nodaemon=true
|
||||||
|
logfile=/dev/stdout
|
||||||
|
logfile_maxbytes=0
|
||||||
|
|
||||||
|
[program:php-fpm]
|
||||||
|
command=/usr/sbin/php-fpm5.6 -F
|
||||||
|
priority=10
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
stdout_logfile=/dev/stdout
|
||||||
|
stdout_logfile_maxbytes=0
|
||||||
|
stderr_logfile=/dev/stderr
|
||||||
|
stderr_logfile_maxbytes=0
|
||||||
|
|
||||||
|
[program:nginx]
|
||||||
|
command=/usr/sbin/nginx -g 'daemon off;'
|
||||||
|
priority=20
|
||||||
|
autostart=true
|
||||||
|
autorestart=true
|
||||||
|
stdout_logfile=/dev/stdout
|
||||||
|
stdout_logfile_maxbytes=0
|
||||||
|
stderr_logfile=/dev/stderr
|
||||||
|
stderr_logfile_maxbytes=0
|
||||||
@@ -1,4 +1,3 @@
|
|||||||
version: '3'
|
|
||||||
services:
|
services:
|
||||||
|
|
||||||
#PHP Service
|
#PHP Service
|
||||||
@@ -6,34 +5,64 @@ services:
|
|||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: Dockerfile
|
dockerfile: Dockerfile
|
||||||
|
args:
|
||||||
|
- APP_ENV=production
|
||||||
image: digitalocean.com/php
|
image: digitalocean.com/php
|
||||||
container_name: app
|
container_name: app
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
tty: true
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '0.50'
|
||||||
|
memory: 512M
|
||||||
|
reservations:
|
||||||
|
cpus: '0.25'
|
||||||
|
memory: 256M
|
||||||
environment:
|
environment:
|
||||||
SERVICE_NAME: app
|
APP_ENV: production
|
||||||
SERVICE_TAGS: dev
|
APP_DEBUG: 'false'
|
||||||
|
PHP_OPCACHE_VALIDATE_TIMESTAMPS: 0
|
||||||
working_dir: /var/www
|
working_dir: /var/www
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/var/www
|
- ./storage:/var/www/storage
|
||||||
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
|
- ./php/local.ini:/usr/local/etc/php/conf.d/local.ini
|
||||||
networks:
|
networks:
|
||||||
- app-network
|
- app-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:9000/"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 3
|
||||||
|
|
||||||
#Nginx Service
|
#Nginx Service
|
||||||
webserver:
|
webserver:
|
||||||
image: nginx:alpine
|
image: nginx:alpine
|
||||||
container_name: webserver
|
container_name: webserver
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
tty: true
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpus: '0.30'
|
||||||
|
memory: 256M
|
||||||
|
reservations:
|
||||||
|
cpus: '0.10'
|
||||||
|
memory: 128M
|
||||||
ports:
|
ports:
|
||||||
- "10003:80"
|
- "10003:80"
|
||||||
- "10443:443"
|
- "10443:443"
|
||||||
volumes:
|
volumes:
|
||||||
- ./:/var/www
|
- ./public:/var/www/public
|
||||||
- ./nginx/conf.d/:/etc/nginx/conf.d/
|
- ./nginx/conf.d/:/etc/nginx/conf.d/
|
||||||
networks:
|
networks:
|
||||||
- app-network
|
- app-network
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "curl", "-f", "http://localhost:80/"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 3s
|
||||||
|
retries: 3
|
||||||
|
depends_on:
|
||||||
|
app:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
#Docker Networks
|
#Docker Networks
|
||||||
networks:
|
networks:
|
||||||
|
|||||||
@@ -1,9 +1,30 @@
|
|||||||
server {
|
server {
|
||||||
listen 80;
|
listen 80;
|
||||||
index index.php index.html;
|
server_tokens off;
|
||||||
error_log /var/log/nginx/error.log;
|
|
||||||
access_log /var/log/nginx/access.log;
|
# Compression
|
||||||
root /var/www;
|
gzip on;
|
||||||
|
gzip_comp_level 5;
|
||||||
|
gzip_min_length 256;
|
||||||
|
gzip_proxied any;
|
||||||
|
gzip_vary on;
|
||||||
|
gzip_types
|
||||||
|
application/javascript
|
||||||
|
application/json
|
||||||
|
application/x-javascript
|
||||||
|
application/xml
|
||||||
|
text/css
|
||||||
|
text/javascript
|
||||||
|
text/plain
|
||||||
|
text/xml;
|
||||||
|
|
||||||
|
client_max_body_size 100M;
|
||||||
|
fastcgi_read_timeout 1800;
|
||||||
|
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
access_log /var/log/nginx/access.log combined buffer=512k flush=1m;
|
||||||
|
|
||||||
|
root /var/www/public;
|
||||||
index index.php index.html;
|
index index.php index.html;
|
||||||
|
|
||||||
location / {
|
location / {
|
||||||
|
|||||||
68
run.sh
Executable file
68
run.sh
Executable file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Helper script for docker compose workflow
|
||||||
|
# Usage examples:
|
||||||
|
# ./run.sh up # build (if needed) and start in background
|
||||||
|
# ./run.sh rebuild # force full rebuild (no cache) and start
|
||||||
|
# ./run.sh down # stop and remove containers
|
||||||
|
# ./run.sh logs # follow logs
|
||||||
|
# ./run.sh artisan migrate
|
||||||
|
# ./run.sh sh # shell into PHP app container
|
||||||
|
# ./run.sh restart # restart containers
|
||||||
|
# ./run.sh build # build images (uses cache)
|
||||||
|
|
||||||
|
CMD=${1:-up}
|
||||||
|
shift || true
|
||||||
|
|
||||||
|
case "$CMD" in
|
||||||
|
build)
|
||||||
|
echo "[build] Building images (with cache)..."
|
||||||
|
docker compose build
|
||||||
|
;;
|
||||||
|
up)
|
||||||
|
echo "[up] Starting services (build if needed)..."
|
||||||
|
docker compose up -d --build
|
||||||
|
;;
|
||||||
|
rebuild)
|
||||||
|
echo "[rebuild] Full rebuild without cache..."
|
||||||
|
docker compose down || true
|
||||||
|
docker compose build --no-cache
|
||||||
|
docker compose up -d
|
||||||
|
;;
|
||||||
|
down)
|
||||||
|
echo "[down] Stopping and removing services..."
|
||||||
|
docker compose down
|
||||||
|
;;
|
||||||
|
restart)
|
||||||
|
echo "[restart] Restarting services..."
|
||||||
|
docker compose restart
|
||||||
|
;;
|
||||||
|
logs)
|
||||||
|
echo "[logs] Following logs (Ctrl+C to exit)..."
|
||||||
|
docker compose logs -f --tail=200 "$@"
|
||||||
|
;;
|
||||||
|
artisan)
|
||||||
|
echo "[artisan] php artisan $*"
|
||||||
|
docker compose exec app php artisan "$@"
|
||||||
|
;;
|
||||||
|
sh)
|
||||||
|
echo "[sh] Opening shell in app container..."
|
||||||
|
docker compose exec app sh
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
cat <<EOF
|
||||||
|
Usage: ./run.sh <command> [args]
|
||||||
|
Commands:
|
||||||
|
up Build (if needed) and start containers
|
||||||
|
build Build images using cache
|
||||||
|
rebuild Rebuild images without cache then start
|
||||||
|
down Stop and remove containers
|
||||||
|
restart Restart running containers
|
||||||
|
logs Follow logs (pass service names optionally)
|
||||||
|
artisan Run php artisan <args>
|
||||||
|
sh Shell into app container
|
||||||
|
EOF
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
Reference in New Issue
Block a user