2026-04-23 03:00:07 +02:00
# Development Dockerfile with FrankenPHP
FROM dunglas/frankenphp:latest-php8.3-alpine
# Install system dependencies
RUN apk add --no-cache \
git \
postgresql-client \
vim \
bash \
nano \
curl
2026-04-23 03:13:33 +02:00
# Install Node.js 20.19.0+ from unofficial builds (musl-compatible for Alpine)
2026-04-23 03:00:07 +02:00
RUN curl -fsSL https://unofficial-builds.nodejs.org/download/release/v20.19.0/node-v20.19.0-linux-x64-musl.tar.xz | tar -xJ -C /usr/local --strip-components=1
# Install PHP extensions including xdebug for development
RUN install-php-extensions \
pdo_pgsql \
opcache \
zip \
gd \
intl \
redis \
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
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
# 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 composer dependencies if vendor is empty
if [ ! -f "vendor/autoload.php" ]; then
echo "Installing Composer dependencies..."
composer install --no-interaction
fi
2026-04-23 17:45:43 +02:00
# Install npm dependencies if node_modules lacks an install marker.
# Can't use `[ ! -d node_modules ]` — the dir is always present because it's a
# named volume mount. Check for npm's post-install marker file instead.
if [ -f "package.json" ] && [ ! -f "node_modules/.package-lock.json" ]; then
2026-04-23 03:00:07 +02:00
echo "Installing npm dependencies..."
npm install
fi
# Clear Laravel caches
php artisan config:clear || true
php artisan cache:clear || true
# Wait for database
echo "Waiting for database..."
2026-04-23 03:13:33 +02:00
until pg_isready -h db -U "${DB_USERNAME:-trove}" -q; do
2026-04-23 03:00:07 +02:00
echo "Database not ready, retrying..."
sleep 2
done
echo "Database is ready!"
# Generate app key if not set
if grep -q "^APP_KEY=$" .env 2>/dev/null; then
echo "Generating application key..."
php artisan key:generate
fi
# Run migrations
php artisan migrate --force
# Start Vite dev server in background (if package.json exists)
if [ -f "package.json" ]; then
npm run dev &
fi
# 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"]