73 - Fix dev environment
This commit is contained in:
parent
638983d42a
commit
4e0f0bb072
11 changed files with 327 additions and 484 deletions
127
Dockerfile.dev
Normal file
127
Dockerfile.dev
Normal file
|
|
@ -0,0 +1,127 @@
|
||||||
|
# Development Dockerfile with FrankenPHP
|
||||||
|
FROM dunglas/frankenphp:latest-php8.3-alpine
|
||||||
|
|
||||||
|
# Install system dependencies + development tools
|
||||||
|
RUN apk add --no-cache \
|
||||||
|
nodejs \
|
||||||
|
npm \
|
||||||
|
git \
|
||||||
|
mysql-client \
|
||||||
|
vim \
|
||||||
|
bash \
|
||||||
|
nano
|
||||||
|
|
||||||
|
# Install PHP extensions including xdebug for development
|
||||||
|
RUN install-php-extensions \
|
||||||
|
pdo_mysql \
|
||||||
|
opcache \
|
||||||
|
zip \
|
||||||
|
gd \
|
||||||
|
intl \
|
||||||
|
bcmath \
|
||||||
|
redis \
|
||||||
|
pcntl \
|
||||||
|
xdebug
|
||||||
|
|
||||||
|
# Install Composer
|
||||||
|
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer
|
||||||
|
|
||||||
|
# Set working directory
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Configure PHP for development
|
||||||
|
RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini"
|
||||||
|
|
||||||
|
# Configure Xdebug (disabled by default to reduce noise)
|
||||||
|
RUN echo "xdebug.mode=off" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
|
||||||
|
&& echo ";xdebug.mode=debug" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
|
||||||
|
&& echo ";xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \
|
||||||
|
&& echo ";xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
|
||||||
|
|
||||||
|
# Configure Caddy for development (simpler, no worker mode)
|
||||||
|
RUN cat > /etc/caddy/Caddyfile <<EOF
|
||||||
|
{
|
||||||
|
frankenphp
|
||||||
|
order php_server before file_server
|
||||||
|
}
|
||||||
|
|
||||||
|
:8000 {
|
||||||
|
root * /app/public
|
||||||
|
|
||||||
|
php_server {
|
||||||
|
index index.php
|
||||||
|
}
|
||||||
|
|
||||||
|
encode gzip
|
||||||
|
|
||||||
|
file_server
|
||||||
|
|
||||||
|
# Less strict headers for development
|
||||||
|
header {
|
||||||
|
X-Frame-Options "SAMEORIGIN"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# Install Node development dependencies globally
|
||||||
|
RUN npm install -g nodemon
|
||||||
|
|
||||||
|
# Create startup script for development
|
||||||
|
RUN cat > /start.sh <<'EOF'
|
||||||
|
#!/bin/sh
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Create .env file if it doesn't exist
|
||||||
|
if [ ! -f ".env" ]; then
|
||||||
|
echo "Creating .env file from .env.example..."
|
||||||
|
cp .env.example .env
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Install dependencies if volumes are empty
|
||||||
|
if [ ! -f "vendor/autoload.php" ]; then
|
||||||
|
echo "Installing composer dependencies..."
|
||||||
|
composer install
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Always reinstall node_modules in container to get correct native binaries for Alpine/musl
|
||||||
|
echo "Installing npm dependencies..."
|
||||||
|
rm -rf node_modules 2>/dev/null || true
|
||||||
|
rm -rf /app/.npm 2>/dev/null || true
|
||||||
|
npm install --cache /tmp/.npm
|
||||||
|
|
||||||
|
# Clear Laravel caches
|
||||||
|
php artisan config:clear || true
|
||||||
|
php artisan cache:clear || true
|
||||||
|
|
||||||
|
# Wait for database and run migrations
|
||||||
|
echo "Waiting for database..."
|
||||||
|
sleep 5
|
||||||
|
php artisan migrate --force || echo "Migration failed or not needed"
|
||||||
|
|
||||||
|
# Run seeders
|
||||||
|
echo "Running seeders..."
|
||||||
|
php artisan db:seed --force || echo "Seeding skipped or already done"
|
||||||
|
|
||||||
|
# Generate app key if not set
|
||||||
|
if [ -z "$APP_KEY" ] || [ "$APP_KEY" = "base64:YOUR_KEY_HERE" ]; then
|
||||||
|
echo "Generating application key..."
|
||||||
|
php artisan key:generate
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start Vite dev server in background
|
||||||
|
npm run dev &
|
||||||
|
|
||||||
|
# Start Horizon (queue worker) in background
|
||||||
|
php artisan horizon &
|
||||||
|
|
||||||
|
# Start FrankenPHP
|
||||||
|
exec frankenphp run --config /etc/caddy/Caddyfile
|
||||||
|
EOF
|
||||||
|
|
||||||
|
RUN chmod +x /start.sh
|
||||||
|
|
||||||
|
# Expose ports
|
||||||
|
EXPOSE 8000 5173
|
||||||
|
|
||||||
|
# Use the startup script
|
||||||
|
CMD ["/start.sh"]
|
||||||
82
docker/dev/docker-compose.yml
Normal file
82
docker/dev/docker-compose.yml
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
# ===================
|
||||||
|
# FFR Development Services
|
||||||
|
# ===================
|
||||||
|
# Port allocation:
|
||||||
|
# App: 8000 (frankenphp), 5173 (vite)
|
||||||
|
# DB: 3307 (mysql)
|
||||||
|
# Redis: 6380
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: Dockerfile.dev
|
||||||
|
container_name: ffr_dev_app
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
- "5173:5173"
|
||||||
|
volumes:
|
||||||
|
- ../..:/app
|
||||||
|
environment:
|
||||||
|
APP_NAME: "FFR"
|
||||||
|
APP_ENV: "${APP_ENV:-local}"
|
||||||
|
APP_DEBUG: "${APP_DEBUG:-true}"
|
||||||
|
APP_URL: "${APP_URL:-http://localhost:8000}"
|
||||||
|
DB_CONNECTION: mysql
|
||||||
|
DB_HOST: db
|
||||||
|
DB_PORT: 3306
|
||||||
|
DB_DATABASE: "${DB_DATABASE:-ffr_dev}"
|
||||||
|
DB_USERNAME: "${DB_USERNAME:-ffr}"
|
||||||
|
DB_PASSWORD: "${DB_PASSWORD:-ffr}"
|
||||||
|
REDIS_HOST: redis
|
||||||
|
REDIS_PORT: 6379
|
||||||
|
SESSION_DRIVER: redis
|
||||||
|
CACHE_STORE: redis
|
||||||
|
QUEUE_CONNECTION: redis
|
||||||
|
VITE_HOST: "0.0.0.0"
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_started
|
||||||
|
networks:
|
||||||
|
- ffr-network
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: mariadb:11
|
||||||
|
container_name: ffr_dev_db
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "3307:3306"
|
||||||
|
environment:
|
||||||
|
MYSQL_DATABASE: "${DB_DATABASE:-ffr_dev}"
|
||||||
|
MYSQL_USER: "${DB_USERNAME:-ffr}"
|
||||||
|
MYSQL_PASSWORD: "${DB_PASSWORD:-ffr}"
|
||||||
|
MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD:-ffr_root_dev}"
|
||||||
|
volumes:
|
||||||
|
- db_data:/var/lib/mysql
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
|
networks:
|
||||||
|
- ffr-network
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: ffr_dev_redis
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "6380:6379"
|
||||||
|
networks:
|
||||||
|
- ffr-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
ffr-network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
db_data:
|
||||||
|
|
@ -1,62 +0,0 @@
|
||||||
APP_NAME="FFR Development"
|
|
||||||
APP_ENV=local
|
|
||||||
APP_KEY=
|
|
||||||
APP_DEBUG=true
|
|
||||||
APP_TIMEZONE=UTC
|
|
||||||
APP_URL=http://localhost:8000
|
|
||||||
|
|
||||||
APP_LOCALE=en
|
|
||||||
APP_FALLBACK_LOCALE=en
|
|
||||||
APP_FAKER_LOCALE=en_US
|
|
||||||
|
|
||||||
APP_MAINTENANCE_DRIVER=file
|
|
||||||
APP_MAINTENANCE_STORE=database
|
|
||||||
|
|
||||||
BCRYPT_ROUNDS=12
|
|
||||||
|
|
||||||
LOG_CHANNEL=stack
|
|
||||||
LOG_STACK=single
|
|
||||||
LOG_DEPRECATIONS_CHANNEL=null
|
|
||||||
LOG_LEVEL=debug
|
|
||||||
|
|
||||||
DB_CONNECTION=mysql
|
|
||||||
DB_HOST=db
|
|
||||||
DB_PORT=3306
|
|
||||||
DB_DATABASE=ffr_dev
|
|
||||||
DB_USERNAME=ffr_user
|
|
||||||
DB_PASSWORD=ffr_password
|
|
||||||
|
|
||||||
SESSION_DRIVER=redis
|
|
||||||
SESSION_LIFETIME=120
|
|
||||||
SESSION_ENCRYPT=false
|
|
||||||
SESSION_PATH=/
|
|
||||||
SESSION_DOMAIN=null
|
|
||||||
|
|
||||||
BROADCAST_CONNECTION=log
|
|
||||||
FILESYSTEM_DISK=local
|
|
||||||
QUEUE_CONNECTION=redis
|
|
||||||
|
|
||||||
CACHE_STORE=redis
|
|
||||||
CACHE_PREFIX=
|
|
||||||
|
|
||||||
REDIS_CLIENT=phpredis
|
|
||||||
REDIS_HOST=redis
|
|
||||||
REDIS_PASSWORD=null
|
|
||||||
REDIS_PORT=6379
|
|
||||||
|
|
||||||
MAIL_MAILER=log
|
|
||||||
MAIL_HOST=127.0.0.1
|
|
||||||
MAIL_PORT=2525
|
|
||||||
MAIL_USERNAME=null
|
|
||||||
MAIL_PASSWORD=null
|
|
||||||
MAIL_ENCRYPTION=null
|
|
||||||
MAIL_FROM_ADDRESS="hello@example.com"
|
|
||||||
MAIL_FROM_NAME="${APP_NAME}"
|
|
||||||
|
|
||||||
AWS_ACCESS_KEY_ID=
|
|
||||||
AWS_SECRET_ACCESS_KEY=
|
|
||||||
AWS_DEFAULT_REGION=us-east-1
|
|
||||||
AWS_BUCKET=
|
|
||||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
|
||||||
|
|
||||||
VITE_APP_NAME="${APP_NAME}"
|
|
||||||
|
|
@ -1,53 +0,0 @@
|
||||||
FROM docker.io/library/php:8.4-fpm
|
|
||||||
|
|
||||||
# Install system dependencies including nginx
|
|
||||||
RUN apt-get update && apt-get install -y \
|
|
||||||
git \
|
|
||||||
curl \
|
|
||||||
libpng-dev \
|
|
||||||
libonig-dev \
|
|
||||||
libxml2-dev \
|
|
||||||
zip \
|
|
||||||
unzip \
|
|
||||||
nginx \
|
|
||||||
default-mysql-client \
|
|
||||||
&& docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd \
|
|
||||||
&& pecl install redis xdebug \
|
|
||||||
&& docker-php-ext-enable redis xdebug
|
|
||||||
|
|
||||||
# Install Node.js 22.x LTS (latest LTS version)
|
|
||||||
RUN curl -fsSL https://deb.nodesource.com/setup_22.x | bash - \
|
|
||||||
&& apt-get install -y nodejs
|
|
||||||
|
|
||||||
# Install Composer
|
|
||||||
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
|
|
||||||
|
|
||||||
# Set working directory
|
|
||||||
WORKDIR /var/www/html
|
|
||||||
|
|
||||||
# Copy application code
|
|
||||||
COPY . .
|
|
||||||
|
|
||||||
# Install PHP dependencies in backend
|
|
||||||
WORKDIR /var/www/html/backend
|
|
||||||
RUN composer install --optimize-autoloader --no-scripts
|
|
||||||
|
|
||||||
# Build React frontend
|
|
||||||
WORKDIR /var/www/html/frontend
|
|
||||||
RUN npm install && npm run build
|
|
||||||
|
|
||||||
# Back to main directory
|
|
||||||
WORKDIR /var/www/html
|
|
||||||
|
|
||||||
# Set permissions
|
|
||||||
RUN chown -R www-data:www-data /var/www/html \
|
|
||||||
&& chmod -R 755 /var/www/html/backend/storage \
|
|
||||||
&& chmod -R 755 /var/www/html/backend/bootstrap/cache
|
|
||||||
|
|
||||||
# Copy and set up container start script
|
|
||||||
COPY docker/dev/podman/container-start.sh /usr/local/bin/container-start.sh
|
|
||||||
RUN chmod +x /usr/local/bin/container-start.sh
|
|
||||||
|
|
||||||
EXPOSE 80
|
|
||||||
|
|
||||||
CMD ["/usr/local/bin/container-start.sh"]
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Copy development environment configuration to backend
|
|
||||||
cp /var/www/html/docker/dev/podman/.env.dev /var/www/html/backend/.env
|
|
||||||
|
|
||||||
# Setup nginx configuration for development
|
|
||||||
cp /var/www/html/docker/dev/podman/nginx.conf /etc/nginx/sites-available/default
|
|
||||||
|
|
||||||
# Install/update dependencies
|
|
||||||
echo "Installing PHP dependencies..."
|
|
||||||
cd /var/www/html/backend
|
|
||||||
composer install --no-interaction
|
|
||||||
|
|
||||||
# Ensure APP_KEY is set in backend/.env
|
|
||||||
ENV_APP_KEY="${APP_KEY}"
|
|
||||||
if [ -n "$ENV_APP_KEY" ]; then
|
|
||||||
echo "Using APP_KEY from environment"
|
|
||||||
sed -i "s|^APP_KEY=.*|APP_KEY=${ENV_APP_KEY}|" /var/www/html/backend/.env || true
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Generate application key if still missing
|
|
||||||
CURRENT_APP_KEY=$(grep "^APP_KEY=" /var/www/html/backend/.env | cut -d'=' -f2)
|
|
||||||
if [ -z "$CURRENT_APP_KEY" ]; then
|
|
||||||
echo "Generating application key..."
|
|
||||||
php artisan key:generate --force
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Verify APP_KEY
|
|
||||||
APP_KEY=$(grep "^APP_KEY=" /var/www/html/backend/.env | cut -d'=' -f2)
|
|
||||||
if [ -n "$APP_KEY" ]; then
|
|
||||||
echo "✅ APP_KEY successfully set."
|
|
||||||
else
|
|
||||||
echo "❌ ERROR: APP_KEY not set!"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Wait for database to be ready
|
|
||||||
echo "Waiting for database..."
|
|
||||||
while ! mysql -h db -u ffr_user -pffr_password --connect-timeout=2 -e "SELECT 1" >/dev/null 2>&1; do
|
|
||||||
echo "Database not ready, waiting..."
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
echo "Database connection established!"
|
|
||||||
|
|
||||||
# Run migrations and seeders
|
|
||||||
php artisan migrate --force
|
|
||||||
php artisan db:seed --force
|
|
||||||
|
|
||||||
# Build frontend if not already built
|
|
||||||
cd /var/www/html/frontend
|
|
||||||
if [ ! -d "dist" ]; then
|
|
||||||
echo "Building React frontend..."
|
|
||||||
npm run build
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Start services
|
|
||||||
echo "Starting services..."
|
|
||||||
|
|
||||||
# Start React dev server
|
|
||||||
cd /var/www/html/frontend
|
|
||||||
npm run dev -- --host 0.0.0.0 --port 5173 &
|
|
||||||
|
|
||||||
# Start Laravel backend
|
|
||||||
cd /var/www/html/backend
|
|
||||||
php artisan serve --host=127.0.0.1 --port=8000 &
|
|
||||||
|
|
||||||
# Start Horizon (manages queue workers in dev)
|
|
||||||
php artisan horizon &
|
|
||||||
|
|
||||||
# Start nginx
|
|
||||||
nginx -g "daemon off;" &
|
|
||||||
|
|
||||||
# Wait for background processes
|
|
||||||
wait
|
|
||||||
|
|
@ -1,76 +0,0 @@
|
||||||
services:
|
|
||||||
app:
|
|
||||||
build:
|
|
||||||
context: ../../..
|
|
||||||
dockerfile: docker/dev/podman/Dockerfile
|
|
||||||
container_name: ffr-dev-app
|
|
||||||
restart: unless-stopped
|
|
||||||
working_dir: /var/www/html
|
|
||||||
environment:
|
|
||||||
- APP_ENV=local
|
|
||||||
- APP_DEBUG=true
|
|
||||||
- APP_KEY=base64:5VABFQKtzx6flRFn7rQUQYI/G8xLnkUSYPVaYz2s/4M=
|
|
||||||
- DB_CONNECTION=mysql
|
|
||||||
- DB_HOST=db
|
|
||||||
- DB_PORT=3306
|
|
||||||
- DB_DATABASE=ffr_dev
|
|
||||||
- DB_USERNAME=ffr_user
|
|
||||||
- DB_PASSWORD=ffr_password
|
|
||||||
- REDIS_HOST=redis
|
|
||||||
- REDIS_PORT=6379
|
|
||||||
- QUEUE_CONNECTION=redis
|
|
||||||
- CACHE_DRIVER=redis
|
|
||||||
- SESSION_DRIVER=redis
|
|
||||||
- VITE_PORT=5173
|
|
||||||
volumes:
|
|
||||||
- ../../../:/var/www/html:Z
|
|
||||||
- /var/www/html/node_modules
|
|
||||||
- /var/www/html/vendor
|
|
||||||
ports:
|
|
||||||
- "8000:80"
|
|
||||||
depends_on:
|
|
||||||
db:
|
|
||||||
condition: service_healthy
|
|
||||||
redis:
|
|
||||||
condition: service_started
|
|
||||||
networks:
|
|
||||||
- ffr-dev-network
|
|
||||||
|
|
||||||
db:
|
|
||||||
image: docker.io/library/mysql:8.4
|
|
||||||
container_name: ffr-dev-db
|
|
||||||
restart: unless-stopped
|
|
||||||
environment:
|
|
||||||
- MYSQL_DATABASE=ffr_dev
|
|
||||||
- MYSQL_USER=ffr_user
|
|
||||||
- MYSQL_PASSWORD=ffr_password
|
|
||||||
- MYSQL_ROOT_PASSWORD=root_password
|
|
||||||
volumes:
|
|
||||||
- db_data:/var/lib/mysql
|
|
||||||
ports:
|
|
||||||
- "3307:3306"
|
|
||||||
healthcheck:
|
|
||||||
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "ffr_user", "-pffr_password"]
|
|
||||||
timeout: 5s
|
|
||||||
retries: 5
|
|
||||||
interval: 3s
|
|
||||||
start_period: 30s
|
|
||||||
networks:
|
|
||||||
- ffr-dev-network
|
|
||||||
|
|
||||||
redis:
|
|
||||||
image: docker.io/library/redis:7-alpine
|
|
||||||
container_name: ffr-dev-redis
|
|
||||||
restart: unless-stopped
|
|
||||||
ports:
|
|
||||||
- "6380:6379"
|
|
||||||
networks:
|
|
||||||
- ffr-dev-network
|
|
||||||
|
|
||||||
networks:
|
|
||||||
ffr-dev-network:
|
|
||||||
driver: bridge
|
|
||||||
|
|
||||||
volumes:
|
|
||||||
db_data:
|
|
||||||
driver: local
|
|
||||||
|
|
@ -1,87 +0,0 @@
|
||||||
server {
|
|
||||||
listen 80;
|
|
||||||
server_name localhost;
|
|
||||||
|
|
||||||
# Proxy API requests to Laravel backend
|
|
||||||
location /api/ {
|
|
||||||
proxy_pass http://127.0.0.1:8000;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Serve Laravel public assets (images, etc.)
|
|
||||||
location /images/ {
|
|
||||||
alias /var/www/html/backend/public/images/;
|
|
||||||
expires 1y;
|
|
||||||
add_header Cache-Control "public, immutable";
|
|
||||||
}
|
|
||||||
|
|
||||||
# Proxy Vite dev server assets
|
|
||||||
location /@vite/ {
|
|
||||||
proxy_pass http://127.0.0.1:5173;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Proxy Vite HMR WebSocket
|
|
||||||
location /@vite/client {
|
|
||||||
proxy_pass http://127.0.0.1:5173;
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Proxy node_modules for Vite deps
|
|
||||||
location /node_modules/ {
|
|
||||||
proxy_pass http://127.0.0.1:5173;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Proxy /src/ for Vite source files
|
|
||||||
location /src/ {
|
|
||||||
proxy_pass http://127.0.0.1:5173;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Proxy React dev server for development (catch-all)
|
|
||||||
location / {
|
|
||||||
proxy_pass http://127.0.0.1:5173;
|
|
||||||
proxy_set_header Host $host;
|
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
# WebSocket support for HMR
|
|
||||||
proxy_http_version 1.1;
|
|
||||||
proxy_set_header Upgrade $http_upgrade;
|
|
||||||
proxy_set_header Connection "upgrade";
|
|
||||||
proxy_redirect off;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Security headers
|
|
||||||
add_header X-Content-Type-Options nosniff;
|
|
||||||
add_header X-Frame-Options DENY;
|
|
||||||
add_header X-XSS-Protection "1; mode=block";
|
|
||||||
|
|
||||||
# Gzip compression
|
|
||||||
gzip on;
|
|
||||||
gzip_vary on;
|
|
||||||
gzip_min_length 1024;
|
|
||||||
gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
|
|
||||||
}
|
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Podman aliases for Laravel Sail compatibility
|
|
||||||
# Source this file to use Sail commands with Podman
|
|
||||||
# Usage: source docker/dev/podman/podman-sail-alias.sh
|
|
||||||
|
|
||||||
# Create docker alias pointing to podman
|
|
||||||
alias docker='podman'
|
|
||||||
|
|
||||||
# Create docker-compose alias pointing to podman-compose
|
|
||||||
alias docker-compose='podman-compose'
|
|
||||||
|
|
||||||
# Sail wrapper function that uses podman-compose
|
|
||||||
sail() {
|
|
||||||
if [[ -f docker/dev/podman/docker-compose.yml ]]; then
|
|
||||||
podman-compose -f docker/dev/podman/docker-compose.yml "$@"
|
|
||||||
else
|
|
||||||
echo "❌ Podman compose file not found at docker/dev/podman/docker-compose.yml"
|
|
||||||
return 1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# FFR-specific helper functions
|
|
||||||
ffr-test() {
|
|
||||||
echo "🧪 Running FFR tests..."
|
|
||||||
podman exec ffr-dev-app php artisan test "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
ffr-artisan() {
|
|
||||||
echo "🔧 Running artisan command..."
|
|
||||||
podman exec ffr-dev-app php artisan "$@"
|
|
||||||
}
|
|
||||||
|
|
||||||
ffr-logs() {
|
|
||||||
echo "📋 Showing FFR application logs..."
|
|
||||||
podman-compose -f docker/dev/podman/docker-compose.yml logs -f app
|
|
||||||
}
|
|
||||||
|
|
||||||
ffr-shell() {
|
|
||||||
echo "🐚 Opening shell in FFR container..."
|
|
||||||
podman exec -it ffr-dev-app bash
|
|
||||||
}
|
|
||||||
|
|
||||||
echo "✅ FFR Podman aliases set up for Laravel Sail compatibility"
|
|
||||||
echo "🐳 'docker' → 'podman'"
|
|
||||||
echo "🔧 'docker-compose' → 'podman-compose'"
|
|
||||||
echo "⛵ 'sail' → uses podman-compose with dev configuration"
|
|
||||||
echo "🚀 FFR-specific commands:"
|
|
||||||
echo " 'ffr-test' → run tests"
|
|
||||||
echo " 'ffr-artisan' → run artisan commands"
|
|
||||||
echo " 'ffr-logs' → view application logs"
|
|
||||||
echo " 'ffr-shell' → open container shell"
|
|
||||||
|
|
@ -1,81 +0,0 @@
|
||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Podman development environment startup script for FFR
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "🚀 Starting FFR development environment with Podman..."
|
|
||||||
|
|
||||||
# Check if .env exists
|
|
||||||
if [ ! -f .env ]; then
|
|
||||||
echo "📋 Creating .env file from .env.example..."
|
|
||||||
cp .env.example .env
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check if podman-compose is available
|
|
||||||
if ! command -v podman-compose &> /dev/null; then
|
|
||||||
echo "❌ podman-compose not found."
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Start services
|
|
||||||
echo "🔧 Starting services..."
|
|
||||||
podman-compose -f docker/dev/podman/docker-compose.yml up -d
|
|
||||||
|
|
||||||
# Wait for database to be ready
|
|
||||||
echo "⏳ Waiting for database to be ready..."
|
|
||||||
sleep 10
|
|
||||||
|
|
||||||
# Install/update dependencies if needed
|
|
||||||
echo "📦 Installing dependencies..."
|
|
||||||
podman exec ffr-dev-app bash -c "cd /var/www/html/backend && composer install"
|
|
||||||
podman exec ffr-dev-app bash -c "cd /var/www/html/frontend && npm install"
|
|
||||||
|
|
||||||
# Run migrations and seeders
|
|
||||||
echo "🗃️ Running database migrations..."
|
|
||||||
podman exec ffr-dev-app bash -c "cd /var/www/html/backend && php artisan migrate --force"
|
|
||||||
echo "🌱 Running database seeders..."
|
|
||||||
podman exec ffr-dev-app bash -c "cd /var/www/html/backend && php artisan db:seed --force"
|
|
||||||
|
|
||||||
# Wait for container services to be fully ready
|
|
||||||
echo "⏳ Waiting for container services to initialize..."
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
# Start React dev server if not already running
|
|
||||||
echo "🚀 Starting React dev server..."
|
|
||||||
podman exec -d ffr-dev-app bash -c "cd /var/www/html/frontend && npm run dev -- --host 0.0.0.0 --port 5173 > /dev/null 2>&1 &"
|
|
||||||
sleep 5
|
|
||||||
|
|
||||||
# Verify Vite is running
|
|
||||||
if podman exec ffr-dev-app bash -c "curl -s http://localhost:5173 > /dev/null 2>&1"; then
|
|
||||||
echo "✅ Vite dev server is running"
|
|
||||||
else
|
|
||||||
echo "⚠️ Vite dev server may not have started properly"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check Laravel Horizon status inside the app container
|
|
||||||
echo "🔍 Checking Laravel Horizon in app container..."
|
|
||||||
HSTATUS="$(podman exec ffr-dev-app bash -lc "cd /var/www/html/backend && php artisan horizon:status" 2>/dev/null || echo "Horizon status: unknown")"
|
|
||||||
echo "$HSTATUS"
|
|
||||||
if echo "$HSTATUS" | grep -qi 'inactive'; then
|
|
||||||
echo "ℹ️ Horizon is inactive. Attempting to start..."
|
|
||||||
podman exec -d ffr-dev-app bash -lc "cd /var/www/html/backend && php artisan horizon > /dev/null 2>&1 &" || true
|
|
||||||
sleep 2
|
|
||||||
podman exec ffr-dev-app bash -lc "cd /var/www/html/backend && php artisan horizon:status" || true
|
|
||||||
else
|
|
||||||
echo "✅ Horizon appears to be running."
|
|
||||||
fi
|
|
||||||
# Show supervisors summary (non-fatal if unavailable)
|
|
||||||
podman exec ffr-dev-app bash -lc "cd /var/www/html/backend && php artisan horizon:supervisors | sed -n '1,80p'" || true
|
|
||||||
|
|
||||||
echo "✅ Development environment is ready!"
|
|
||||||
echo "🌐 Application: http://localhost:8000"
|
|
||||||
echo "🔥 Vite dev server: http://localhost:5173"
|
|
||||||
echo "💾 Database: localhost:3307"
|
|
||||||
echo "🔴 Redis: localhost:6380"
|
|
||||||
echo ""
|
|
||||||
echo "📋 Useful commands:"
|
|
||||||
echo " Stop: podman-compose -f docker/dev/podman/docker-compose.yml down"
|
|
||||||
echo " Logs: podman-compose -f docker/dev/podman/docker-compose.yml logs -f"
|
|
||||||
echo " Exec: podman exec -it ffr-dev-app bash"
|
|
||||||
echo " Tests: podman exec ffr-dev-app php artisan test"
|
|
||||||
109
shell.nix
Normal file
109
shell.nix
Normal file
|
|
@ -0,0 +1,109 @@
|
||||||
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
|
||||||
|
pkgs.mkShell {
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
# PHP and tools
|
||||||
|
php84
|
||||||
|
php84Packages.composer
|
||||||
|
|
||||||
|
# Node.js and npm
|
||||||
|
nodejs_22
|
||||||
|
|
||||||
|
# Container tools
|
||||||
|
podman
|
||||||
|
podman-compose
|
||||||
|
|
||||||
|
# Database client (for direct DB access)
|
||||||
|
mariadb.client
|
||||||
|
|
||||||
|
# Redis client
|
||||||
|
redis
|
||||||
|
|
||||||
|
# Utilities
|
||||||
|
git
|
||||||
|
curl
|
||||||
|
gnumake
|
||||||
|
];
|
||||||
|
|
||||||
|
shellHook = ''
|
||||||
|
export USER_ID=$(id -u)
|
||||||
|
export GROUP_ID=$(id -g)
|
||||||
|
export PODMAN_USERNS=keep-id
|
||||||
|
|
||||||
|
# Compose file location
|
||||||
|
COMPOSE_FILE="$PWD/docker/dev/docker-compose.yml"
|
||||||
|
|
||||||
|
# ===================
|
||||||
|
# ALIASES
|
||||||
|
# ===================
|
||||||
|
alias pc='podman-compose -f $COMPOSE_FILE'
|
||||||
|
|
||||||
|
# ===================
|
||||||
|
# DEV COMMANDS
|
||||||
|
# ===================
|
||||||
|
dev-up() {
|
||||||
|
echo "Starting services..."
|
||||||
|
PODMAN_USERNS=keep-id podman-compose -f $COMPOSE_FILE up -d "$@"
|
||||||
|
echo ""
|
||||||
|
podman-compose -f $COMPOSE_FILE ps
|
||||||
|
echo ""
|
||||||
|
echo "App available at: http://localhost:8000"
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-down() {
|
||||||
|
if [[ "$1" == "-v" ]]; then
|
||||||
|
echo "Stopping services and removing volumes..."
|
||||||
|
podman-compose -f $COMPOSE_FILE down -v
|
||||||
|
else
|
||||||
|
echo "Stopping services..."
|
||||||
|
podman-compose -f $COMPOSE_FILE down
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-restart() {
|
||||||
|
echo "Restarting services..."
|
||||||
|
podman-compose -f $COMPOSE_FILE restart "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-logs() {
|
||||||
|
podman-compose -f $COMPOSE_FILE logs -f app "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-logs-db() {
|
||||||
|
podman-compose -f $COMPOSE_FILE logs -f db "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-shell() {
|
||||||
|
podman-compose -f $COMPOSE_FILE exec app sh
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-artisan() {
|
||||||
|
podman-compose -f $COMPOSE_FILE exec app php artisan "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================
|
||||||
|
# WELCOME MESSAGE
|
||||||
|
# ===================
|
||||||
|
echo ""
|
||||||
|
echo "╔═══════════════════════════════════════════════════════════╗"
|
||||||
|
echo "║ FFR Dev Environment ║"
|
||||||
|
echo "╚═══════════════════════════════════════════════════════════╝"
|
||||||
|
echo ""
|
||||||
|
echo " Podman: $(podman --version | cut -d' ' -f3)"
|
||||||
|
echo ""
|
||||||
|
echo "Commands:"
|
||||||
|
echo " dev-up [services] Start all or specific services"
|
||||||
|
echo " dev-down [-v] Stop services (-v removes volumes)"
|
||||||
|
echo " dev-restart Restart services"
|
||||||
|
echo " dev-logs Tail app logs"
|
||||||
|
echo " dev-logs-db Tail database logs"
|
||||||
|
echo " dev-shell Shell into app container"
|
||||||
|
echo " dev-artisan <cmd> Run artisan command"
|
||||||
|
echo ""
|
||||||
|
echo "Services:"
|
||||||
|
echo " app Laravel + Vite http://localhost:8000"
|
||||||
|
echo " db MariaDB localhost:3307"
|
||||||
|
echo " redis Redis localhost:6380"
|
||||||
|
echo ""
|
||||||
|
'';
|
||||||
|
}
|
||||||
|
|
@ -8,4 +8,13 @@ export default defineConfig({
|
||||||
refresh: true,
|
refresh: true,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
|
server: {
|
||||||
|
host: '0.0.0.0',
|
||||||
|
port: 5173,
|
||||||
|
strictPort: true,
|
||||||
|
cors: true,
|
||||||
|
hmr: {
|
||||||
|
host: 'localhost',
|
||||||
|
},
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue