1 - Add Nix shell and Docker dev environment
This commit is contained in:
parent
d377f7601c
commit
541cc8a3e7
5 changed files with 376 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
/.idea/
|
||||||
125
Dockerfile.dev
Normal file
125
Dockerfile.dev
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# Install Node.js 20.19.0+ from unofficial builds (for Vite 7 compatibility)
|
||||||
|
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
|
||||||
|
|
||||||
|
# Install npm dependencies if node_modules is empty
|
||||||
|
if [ ! -d "node_modules" ] && [ -f "package.json" ]; then
|
||||||
|
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..."
|
||||||
|
until pg_isready -h db -U trove -q; do
|
||||||
|
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"]
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
# trove
|
# trove
|
||||||
|
|
||||||
|
A small web search engine.
|
||||||
|
|
|
||||||
96
docker/dev/docker-compose.yml
Normal file
96
docker/dev/docker-compose.yml
Normal file
|
|
@ -0,0 +1,96 @@
|
||||||
|
# ===================
|
||||||
|
# Trove Development Services
|
||||||
|
# ===================
|
||||||
|
# Port allocation:
|
||||||
|
# App: 8200 (frankenphp), 5175 (vite)
|
||||||
|
# DB: 5433 (postgresql)
|
||||||
|
# Redis: 6380
|
||||||
|
|
||||||
|
services:
|
||||||
|
app:
|
||||||
|
build:
|
||||||
|
context: ../..
|
||||||
|
dockerfile: Dockerfile.dev
|
||||||
|
container_name: trove_dev_app
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "8200:8000"
|
||||||
|
- "5175:5173"
|
||||||
|
volumes:
|
||||||
|
- ../..:/app
|
||||||
|
- app_vendor:/app/vendor
|
||||||
|
- app_node_modules:/app/node_modules
|
||||||
|
environment:
|
||||||
|
APP_NAME: "${APP_NAME:-Trove}"
|
||||||
|
APP_ENV: "${APP_ENV:-local}"
|
||||||
|
APP_DEBUG: "${APP_DEBUG:-true}"
|
||||||
|
APP_URL: "${APP_URL:-http://localhost:8200}"
|
||||||
|
DB_CONNECTION: pgsql
|
||||||
|
DB_HOST: db
|
||||||
|
DB_PORT: 5432
|
||||||
|
DB_DATABASE: "${DB_DATABASE:-trove}"
|
||||||
|
DB_USERNAME: "${DB_USERNAME:-trove}"
|
||||||
|
DB_PASSWORD: "${DB_PASSWORD:-trove}"
|
||||||
|
REDIS_HOST: redis
|
||||||
|
REDIS_PORT: 6379
|
||||||
|
SESSION_DRIVER: "${SESSION_DRIVER:-database}"
|
||||||
|
CACHE_STORE: "${CACHE_STORE:-redis}"
|
||||||
|
QUEUE_CONNECTION: "${QUEUE_CONNECTION:-redis}"
|
||||||
|
MAIL_MAILER: "${MAIL_MAILER:-log}"
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: service_healthy
|
||||||
|
redis:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- trove-network
|
||||||
|
|
||||||
|
db:
|
||||||
|
image: postgres:17-alpine
|
||||||
|
container_name: trove_dev_db
|
||||||
|
hostname: db
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "5433:5432"
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: "${DB_DATABASE:-trove}"
|
||||||
|
POSTGRES_USER: "${DB_USERNAME:-trove}"
|
||||||
|
POSTGRES_PASSWORD: "${DB_PASSWORD:-trove}"
|
||||||
|
volumes:
|
||||||
|
- db_data:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-trove}"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 10s
|
||||||
|
networks:
|
||||||
|
- trove-network
|
||||||
|
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
container_name: trove_dev_redis
|
||||||
|
hostname: redis
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "6380:6379"
|
||||||
|
volumes:
|
||||||
|
- redis_data:/data
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD", "redis-cli", "ping"]
|
||||||
|
interval: 10s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 5
|
||||||
|
start_period: 5s
|
||||||
|
networks:
|
||||||
|
- trove-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
trove-network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
db_data:
|
||||||
|
redis_data:
|
||||||
|
app_vendor:
|
||||||
|
app_node_modules:
|
||||||
153
shell.nix
Normal file
153
shell.nix
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
|
|
||||||
|
pkgs.mkShell {
|
||||||
|
buildInputs = with pkgs; [
|
||||||
|
# PHP and tools
|
||||||
|
php83
|
||||||
|
php83Packages.composer
|
||||||
|
|
||||||
|
# Node.js (needed for Tailwind CSS / Vite)
|
||||||
|
nodejs_22
|
||||||
|
|
||||||
|
# Container tools
|
||||||
|
podman
|
||||||
|
podman-compose
|
||||||
|
|
||||||
|
# Database client
|
||||||
|
postgresql
|
||||||
|
|
||||||
|
# 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:8200"
|
||||||
|
}
|
||||||
|
|
||||||
|
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-rebuild() {
|
||||||
|
echo "Rebuilding services (down -v + up)..."
|
||||||
|
podman-compose -f $COMPOSE_FILE down -v
|
||||||
|
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:8200"
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-logs() {
|
||||||
|
podman-compose -f $COMPOSE_FILE logs -f app "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-logs-db() {
|
||||||
|
podman-compose -f $COMPOSE_FILE logs -f db "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-logs-redis() {
|
||||||
|
podman-compose -f $COMPOSE_FILE logs -f redis "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-shell() {
|
||||||
|
podman-compose -f $COMPOSE_FILE exec app bash
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-artisan() {
|
||||||
|
podman-compose -f $COMPOSE_FILE exec app php artisan "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================
|
||||||
|
# BUILD COMMANDS
|
||||||
|
# ===================
|
||||||
|
base-build() {
|
||||||
|
local image="forge.lvl0.xyz/lvl0/trove:latest"
|
||||||
|
|
||||||
|
# Check if logged in, prompt if not
|
||||||
|
if ! podman login --get-login forge.lvl0.xyz &>/dev/null; then
|
||||||
|
echo "Not logged in to forge.lvl0.xyz"
|
||||||
|
podman login forge.lvl0.xyz || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Building image: $image"
|
||||||
|
if ! podman build -t "$image" -f Dockerfile .; then
|
||||||
|
echo "Build failed!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Pushing to registry..."
|
||||||
|
if ! podman push "$image"; then
|
||||||
|
echo "Push failed!"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Done! Image pushed: $image"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ===================
|
||||||
|
# WELCOME MESSAGE
|
||||||
|
# ===================
|
||||||
|
echo ""
|
||||||
|
echo "================================================="
|
||||||
|
echo " Trove 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-rebuild Fresh start (down -v + up)"
|
||||||
|
echo " dev-restart Restart services"
|
||||||
|
echo " dev-logs Tail app logs"
|
||||||
|
echo " dev-logs-db Tail database logs"
|
||||||
|
echo " dev-logs-redis Tail Redis logs"
|
||||||
|
echo " dev-shell Shell into app container"
|
||||||
|
echo " dev-artisan <cmd> Run artisan command"
|
||||||
|
echo " base-build Build and push image"
|
||||||
|
echo ""
|
||||||
|
echo "Services:"
|
||||||
|
echo " app Laravel http://localhost:8200"
|
||||||
|
echo " vite HMR http://localhost:5175"
|
||||||
|
echo " db PostgreSQL localhost:5433"
|
||||||
|
echo " redis Redis localhost:6380"
|
||||||
|
echo ""
|
||||||
|
'';
|
||||||
|
}
|
||||||
Loading…
Reference in a new issue