Fix prod scripts

This commit is contained in:
myrmidex 2025-08-12 12:17:27 +02:00
parent 9d6e20b4f1
commit 1e70525f73
5 changed files with 89 additions and 111 deletions

View file

@ -3,17 +3,14 @@ FROM node:22-alpine AS frontend-builder
WORKDIR /app WORKDIR /app
# Copy package files # Copy frontend package files
COPY package*.json ./ COPY frontend/package*.json ./
# Install Node dependencies # Install Node dependencies
RUN npm ci RUN npm ci
# Copy frontend source # Copy frontend source
COPY resources/ resources/ COPY frontend/ ./
COPY public/ public/
COPY vite.config.js ./
COPY tsconfig.json ./
# Build frontend assets # Build frontend assets
RUN npm run build RUN npm run build
@ -55,14 +52,18 @@ COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Set working directory # Set working directory
WORKDIR /var/www/html WORKDIR /var/www/html
# Copy application code first # Copy application code
COPY . . COPY . .
# Install PHP dependencies after copying all files # Install PHP dependencies in backend directory
WORKDIR /var/www/html/backend
RUN composer install --no-dev --optimize-autoloader --no-interaction RUN composer install --no-dev --optimize-autoloader --no-interaction
# Copy built frontend assets from builder stage # Copy built frontend assets from builder stage to frontend dist
COPY --from=frontend-builder /app/public/build/ ./public/build/ COPY --from=frontend-builder /app/dist/ /var/www/html/frontend/dist/
# Back to main directory
WORKDIR /var/www/html
# Copy nginx and supervisor configurations # Copy nginx and supervisor configurations
COPY docker/production/nginx.conf /etc/nginx/http.d/default.conf COPY docker/production/nginx.conf /etc/nginx/http.d/default.conf
@ -70,8 +71,9 @@ COPY docker/production/supervisord.conf /etc/supervisord.conf
COPY docker/production/start-app.sh /usr/local/bin/start-app COPY docker/production/start-app.sh /usr/local/bin/start-app
# Set proper permissions # Set proper permissions
RUN chown -R www-data:www-data storage bootstrap/cache public/build \ RUN chown -R www-data:www-data /var/www/html \
&& chmod -R 755 storage bootstrap/cache \ && chmod -R 755 /var/www/html/backend/storage \
&& chmod -R 755 /var/www/html/backend/bootstrap/cache \
&& chmod +x /usr/local/bin/start-app && chmod +x /usr/local/bin/start-app
# Expose port 80 for nginx # Expose port 80 for nginx
@ -79,7 +81,7 @@ EXPOSE 80
# Health check # Health check
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD php artisan --version || exit 1 CMD cd /var/www/html/backend && php artisan --version || exit 1
# Start the application # Start the application
CMD ["/usr/local/bin/start-app"] CMD ["/usr/local/bin/start-app"]

View file

@ -1,27 +1,26 @@
services: services:
app: app:
image: codeberg.org/lvl0/ffr:latest image: codeberg.org/lvl0/ffr:v1.0.0-rc1
# build:
# context: ../..
# dockerfile: docker/production/Dockerfile
container_name: ffr-app container_name: ffr-app
restart: unless-stopped restart: unless-stopped
working_dir: /var/www/html
environment: environment:
- APP_ENV=production - APP_ENV=production
- APP_DEBUG=false - APP_DEBUG=false
- APP_KEY=${APP_KEY}
- APP_URL=${APP_URL}
- DB_CONNECTION=mysql - DB_CONNECTION=mysql
- DB_HOST=db - DB_HOST=db
- DB_PORT=3306 - DB_PORT=3306
- DB_DATABASE=ffr - DB_DATABASE=ffr
- DB_USERNAME=ffr_user - DB_USERNAME=ffr_user
- DB_PASSWORD=ffr_password - DB_PASSWORD=${DB_PASSWORD}
- REDIS_HOST=redis - REDIS_HOST=redis
- REDIS_PORT=6379 - REDIS_PORT=6379
- CACHE_DRIVER=redis - CACHE_DRIVER=redis
- SESSION_DRIVER=redis - SESSION_DRIVER=redis
- QUEUE_CONNECTION=redis - QUEUE_CONNECTION=redis
volumes: [] - TELEGRAM_BOT_TOKEN=${TELEGRAM_BOT_TOKEN}
- TELEGRAM_CHANNEL_ID=${TELEGRAM_CHANNEL_ID}
ports: ports:
- "8000:80" - "8000:80"
depends_on: depends_on:
@ -32,62 +31,6 @@ services:
networks: networks:
- ffr-network - ffr-network
queue:
image: codeberg.org/lvl0/ffr:latest
container_name: ffr-queue
restart: unless-stopped
working_dir: /var/www/html
environment:
- APP_ENV=production
- APP_DEBUG=false
- DB_CONNECTION=mysql
- DB_HOST=db
- DB_PORT=3306
- DB_DATABASE=ffr
- DB_USERNAME=ffr_user
- DB_PASSWORD=ffr_password
- REDIS_HOST=redis
- REDIS_PORT=6379
- CACHE_DRIVER=redis
- SESSION_DRIVER=redis
- QUEUE_CONNECTION=redis
command: ["php", "artisan", "horizon"]
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
networks:
- ffr-network
scheduler:
image: codeberg.org/lvl0/ffr:latest
container_name: ffr-scheduler
restart: unless-stopped
working_dir: /var/www/html
environment:
- APP_ENV=production
- APP_DEBUG=false
- DB_CONNECTION=mysql
- DB_HOST=db
- DB_PORT=3306
- DB_DATABASE=ffr
- DB_USERNAME=ffr_user
- DB_PASSWORD=ffr_password
- REDIS_HOST=redis
- REDIS_PORT=6379
- CACHE_DRIVER=redis
- SESSION_DRIVER=redis
- QUEUE_CONNECTION=redis
command: ["sh", "-c", "while true; do php artisan schedule:run --verbose --no-interaction; sleep 60; done"]
depends_on:
db:
condition: service_healthy
redis:
condition: service_started
networks:
- ffr-network
db: db:
image: docker.io/library/mysql:8.4 image: docker.io/library/mysql:8.4
container_name: ffr-db container_name: ffr-db
@ -95,14 +38,12 @@ services:
environment: environment:
- MYSQL_DATABASE=ffr - MYSQL_DATABASE=ffr
- MYSQL_USER=ffr_user - MYSQL_USER=ffr_user
- MYSQL_PASSWORD=ffr_password - MYSQL_PASSWORD=${DB_PASSWORD}
- MYSQL_ROOT_PASSWORD=root_password - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASSWORD}
volumes: volumes:
- db_data:/var/lib/mysql - db_data:/var/lib/mysql
ports:
- "3306:3306"
healthcheck: healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "ffr_user", "-pffr_password"] test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "ffr_user", "-p${DB_PASSWORD}"]
timeout: 5s timeout: 5s
retries: 5 retries: 5
interval: 3s interval: 3s
@ -127,4 +68,4 @@ volumes:
db_data: db_data:
driver: local driver: local
redis_data: redis_data:
driver: local driver: local

View file

@ -1,22 +1,19 @@
server { server {
listen 80; listen 80;
server_name localhost; server_name localhost;
root /var/www/html/public;
index index.php index.html; # Serve static React build files
root /var/www/html/frontend/dist;
index index.html;
# Security headers # API requests to Laravel backend
add_header X-Frame-Options "SAMEORIGIN"; location /api/ {
add_header X-Content-Type-Options "nosniff"; root /var/www/html/backend/public;
add_header X-XSS-Protection "1; mode=block"; try_files /index.php =404;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000; fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php; fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name; fastcgi_param SCRIPT_FILENAME /var/www/html/backend/public/index.php;
include fastcgi_params; include fastcgi_params;
# Increase timeouts for long-running requests # Increase timeouts for long-running requests
@ -24,6 +21,30 @@ server {
fastcgi_send_timeout 300; fastcgi_send_timeout 300;
} }
# Serve Laravel public assets (images, etc.)
location /images/ {
alias /var/www/html/backend/public/images/;
expires 1y;
add_header Cache-Control "public, immutable";
}
# React app - catch all routes
location / {
try_files $uri $uri/ /index.html;
}
# Static assets with far-future expiry
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|map)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";
add_header X-XSS-Protection "1; mode=block";
# Deny access to hidden files # Deny access to hidden files
location ~ /\.ht { location ~ /\.ht {
deny all; deny all;
@ -34,14 +55,6 @@ server {
deny all; deny all;
} }
# Static assets with far-future expiry
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot|map)$ {
expires 1y;
add_header Cache-Control "public, immutable";
access_log off;
}
# Laravel specific optimizations
location = /favicon.ico { location = /favicon.ico {
access_log off; access_log off;
log_not_found off; log_not_found off;

View file

@ -1,8 +1,8 @@
#!/bin/sh #!/bin/sh
# Create .env file if it doesn't exist # Create .env file if it doesn't exist
if [ ! -f /var/www/html/.env ]; then if [ ! -f /var/www/html/backend/.env ]; then
cp /var/www/html/.env.example /var/www/html/.env 2>/dev/null || touch /var/www/html/.env cp /var/www/html/backend/.env.example /var/www/html/backend/.env 2>/dev/null || touch /var/www/html/backend/.env
fi fi
# Wait for database to be ready # Wait for database to be ready
@ -14,21 +14,23 @@ done
echo "Database connection established!" echo "Database connection established!"
# Generate app key if not set # Generate app key if not set
if ! grep -q "APP_KEY=base64:" /var/www/html/.env; then if ! grep -q "APP_KEY=base64:" /var/www/html/backend/.env; then
php artisan key:generate --force cd /var/www/html/backend && php artisan key:generate --force
fi fi
# Laravel optimizations for production # Laravel optimizations for production
cd /var/www/html/backend
php artisan config:cache php artisan config:cache
php artisan route:cache php artisan route:cache
php artisan view:cache php artisan view:cache
# Run migrations # Run migrations
cd /var/www/html/backend
php artisan migrate --force php artisan migrate --force
# Run seeders (only if needed for production data) # Run all seeders (same as dev)
php artisan db:seed --force --class=PlatformInstanceSeeder cd /var/www/html/backend
php artisan db:seed --force --class=SettingsSeeder php artisan db:seed --force
# Start supervisor to manage nginx and php-fpm # Start supervisor to manage nginx and php-fpm
supervisord -c /etc/supervisord.conf supervisord -c /etc/supervisord.conf

View file

@ -22,4 +22,24 @@ stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0 stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0 stderr_logfile_maxbytes=0
priority=10 priority=10
[program:horizon]
command=php /var/www/html/backend/artisan horizon
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
priority=20
[program:scheduler]
command=sh -c "while true; do php /var/www/html/backend/artisan schedule:run --verbose --no-interaction; sleep 60; done"
autostart=true
autorestart=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stderr_logfile=/dev/stderr
stderr_logfile_maxbytes=0
priority=20