From f69f2848409a8ac7e4d8ff12eaefae37d9b47e16 Mon Sep 17 00:00:00 2001 From: myrmidex Date: Sun, 23 Aug 2026 00:01:26 +0200 Subject: [PATCH] Add podman compose dev environment --- .dockerignore | 22 +++++++ Dockerfile.dev | 96 +++++++++++++++++++++++++++ docker/.env.example | 11 ++++ docker/dev/docker-compose.yml | 68 +++++++++++++++++++ shell.nix | 120 +++++++++++++++++++++++++++++++++- 5 files changed, 314 insertions(+), 3 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile.dev create mode 100644 docker/.env.example create mode 100644 docker/dev/docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..65c8a94 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,22 @@ +node_modules/ +npm-debug.log* +vendor/ + +.env +.env.* +!.env.example + +.git/ +.gitignore +.claude/ + +.idea/ +.vscode/ + +storage/logs/* +storage/framework/cache/* +storage/framework/sessions/* +storage/framework/views/* + +tests/ +README.md diff --git a/Dockerfile.dev b/Dockerfile.dev new file mode 100644 index 0000000..a9e3e2c --- /dev/null +++ b/Dockerfile.dev @@ -0,0 +1,96 @@ +FROM dunglas/frankenphp:latest-php8.4-alpine + +RUN apk add --no-cache \ + nodejs \ + npm \ + git \ + mariadb-client \ + bash \ + vim + +RUN install-php-extensions \ + pdo_mysql \ + opcache \ + zip \ + gd \ + intl \ + bcmath \ + pcntl \ + xdebug + +COPY --from=composer:2 /usr/bin/composer /usr/bin/composer + +WORKDIR /app + +RUN mv "$PHP_INI_DIR/php.ini-development" "$PHP_INI_DIR/php.ini" + +RUN echo "xdebug.mode=off" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini \ + && echo ";xdebug.client_host=host.containers.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 + +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 + + header { + X-Frame-Options "SAMEORIGIN" + } +} +EOF + +RUN cat > /start.sh <<'EOF' +#!/bin/sh +set -e + +if [ ! -f ".env" ]; then + echo "Creating .env from .env.example..." + cp .env.example .env +fi + +if [ ! -f "vendor/autoload.php" ]; then + echo "Installing composer dependencies..." + composer install +fi + +echo "Installing npm dependencies..." +rm -rf node_modules 2>/dev/null || true +npm install --cache /tmp/.npm + +php artisan config:clear || true +php artisan cache:clear || true + +if ! grep -q "^APP_KEY=base64:" .env 2>/dev/null; then + echo "Generating application key..." + php artisan key:generate +fi + +echo "Waiting for database..." +until mariadb -h "$DB_HOST" -u "$DB_USERNAME" -p"$DB_PASSWORD" -e "SELECT 1" >/dev/null 2>&1; do + sleep 2 +done + +php artisan migrate --force || echo "Migration failed or not needed" + +npm run dev & + +exec frankenphp run --config /etc/caddy/Caddyfile +EOF + +RUN chmod +x /start.sh + +EXPOSE 8000 5173 + +CMD ["/start.sh"] diff --git a/docker/.env.example b/docker/.env.example new file mode 100644 index 0000000..0e67ff1 --- /dev/null +++ b/docker/.env.example @@ -0,0 +1,11 @@ +# Overrides for the dev compose file. +# Copy to .env in this directory and adjust as needed. + +DB_DATABASE=anagram_dev +DB_USERNAME=anagram +DB_PASSWORD=anagram +DB_ROOT_PASSWORD=anagram_root_dev + +APP_ENV=local +APP_DEBUG=true +APP_URL=http://localhost:8001 diff --git a/docker/dev/docker-compose.yml b/docker/dev/docker-compose.yml new file mode 100644 index 0000000..4334a19 --- /dev/null +++ b/docker/dev/docker-compose.yml @@ -0,0 +1,68 @@ +# =================== +# Anagram Finder Web - Development Services +# =================== +# Port allocation: +# App: 8001 (frankenphp), 5174 (vite) +# DB: 3308 (mariadb) + +services: + app: + build: + context: ../.. + dockerfile: Dockerfile.dev + container_name: anagram_web_dev_app + restart: unless-stopped + ports: + - "8001:8000" + - "5174:5173" + volumes: + - ../..:/app + environment: + APP_NAME: "Anagram Finder" + APP_ENV: "${APP_ENV:-local}" + APP_DEBUG: "${APP_DEBUG:-true}" + APP_URL: "${APP_URL:-http://localhost:8001}" + DB_CONNECTION: mariadb + DB_HOST: db + DB_PORT: 3306 + DB_DATABASE: "${DB_DATABASE:-anagram_dev}" + DB_USERNAME: "${DB_USERNAME:-anagram}" + DB_PASSWORD: "${DB_PASSWORD:-anagram}" + SESSION_DRIVER: database + CACHE_STORE: database + QUEUE_CONNECTION: database + VITE_HOST: "0.0.0.0" + depends_on: + db: + condition: service_healthy + networks: + - anagram-network + + db: + image: mariadb:11 + container_name: anagram_web_dev_db + restart: unless-stopped + ports: + - "3308:3306" + environment: + MARIADB_DATABASE: "${DB_DATABASE:-anagram_dev}" + MARIADB_USER: "${DB_USERNAME:-anagram}" + MARIADB_PASSWORD: "${DB_PASSWORD:-anagram}" + MARIADB_ROOT_PASSWORD: "${DB_ROOT_PASSWORD:-anagram_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: + - anagram-network + +networks: + anagram-network: + driver: bridge + +volumes: + db_data: diff --git a/shell.nix b/shell.nix index 3bc1e26..910f056 100644 --- a/shell.nix +++ b/shell.nix @@ -5,11 +5,17 @@ pkgs.mkShell { # 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 + # Utilities git curl @@ -18,5 +24,113 @@ pkgs.mkShell { shellHook = '' export PATH="$HOME/.config/composer/vendor/bin:$PATH" - ''; + + 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:8001" + } + + 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 --build)..." + podman-compose -f $COMPOSE_FILE down -v + PODMAN_USERNS=keep-id podman-compose -f $COMPOSE_FILE up -d --build "$@" + echo "" + podman-compose -f $COMPOSE_FILE ps + echo "" + echo "App available at: http://localhost:8001" + } + + 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 "$@" + } + + dev-composer() { + podman-compose -f $COMPOSE_FILE exec app composer "$@" + } + + dev-test() { + podman-compose -f $COMPOSE_FILE exec -T app php vendor/bin/phpunit "$@" + } + + dev-db() { + podman-compose -f $COMPOSE_FILE exec db mariadb \ + -u "''${DB_USERNAME:-anagram}" \ + -p"''${DB_PASSWORD:-anagram}" \ + "''${DB_DATABASE:-anagram_dev}" "$@" + } + + # =================== + # WELCOME MESSAGE + # =================== + echo "" + echo "╔═══════════════════════════════════════════════════════════╗" + echo "║ Anagram Finder Web 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 --build)" + 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 Run artisan command" + echo " dev-composer Run composer in container" + echo " dev-test [path] Run PHPUnit suite" + echo " dev-db [args] MariaDB client on the dev database" + echo "" + echo "Services:" + echo " app Laravel + Vite http://localhost:8001" + echo " db MariaDB localhost:3308" + echo "" + ''; }