From 5614fc391592b52c62d1456bcd2f033a48267f42 Mon Sep 17 00:00:00 2001 From: myrmidex Date: Thu, 19 Mar 2026 00:38:13 +0100 Subject: [PATCH] Move docker-compose to docker/dev, modernize shell.nix, migrate to Forgejo registry --- docker-compose.prod.yml | 2 +- .../dev/docker-compose.yml | 74 ++--- shell.nix | 307 +++++++----------- 3 files changed, 146 insertions(+), 237 deletions(-) rename docker-compose.yml => docker/dev/docker-compose.yml (58%) diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml index 399f834..e27c07e 100644 --- a/docker-compose.prod.yml +++ b/docker-compose.prod.yml @@ -1,7 +1,7 @@ # Production Docker Compose services: app: - image: codeberg.org/lvl0/buckets:latest + image: forge.lvl0.xyz/lvl0/buckets:latest container_name: buckets_app restart: always ports: diff --git a/docker-compose.yml b/docker/dev/docker-compose.yml similarity index 58% rename from docker-compose.yml rename to docker/dev/docker-compose.yml index fdc44b7..3cf9032 100644 --- a/docker-compose.yml +++ b/docker/dev/docker-compose.yml @@ -1,59 +1,52 @@ -# Local Development Docker Compose -version: '3.8' +# =================== +# Buckets Development Services +# =================== +# Port allocation: +# App: 8100 (frankenphp), 5174 (vite) +# DB: 3307 (mysql) +# Mailhog: 8026 (web), 1026 (smtp) services: app: build: - context: . + context: ../.. dockerfile: Dockerfile.dev - container_name: buckets_app + container_name: buckets_dev_app restart: unless-stopped - # Remove user directive to run as root in container - # The container will handle permissions internally ports: - - "8100:8000" # Laravel app - - "5174:5173" # Vite dev server + - "8100:8000" + - "5174:5173" + volumes: + - ../..:/app + - app_vendor:/app/vendor + - app_node_modules:/app/node_modules environment: - # Laravel APP_NAME: "${APP_NAME:-buckets}" APP_ENV: "${APP_ENV:-local}" APP_KEY: "${APP_KEY:-base64:YOUR_KEY_HERE}" APP_DEBUG: "${APP_DEBUG:-true}" APP_URL: "${APP_URL:-http://localhost:8100}" - - # Database DB_CONNECTION: mysql DB_HOST: db DB_PORT: 3306 DB_DATABASE: "${DB_DATABASE:-buckets}" DB_USERNAME: "${DB_USERNAME:-buckets}" DB_PASSWORD: "${DB_PASSWORD:-buckets}" - - # Session & Cache SESSION_DRIVER: "${SESSION_DRIVER:-file}" CACHE_DRIVER: "${CACHE_DRIVER:-file}" QUEUE_CONNECTION: "${QUEUE_CONNECTION:-sync}" - - # Mail (for development) MAIL_MAILER: "${MAIL_MAILER:-log}" - - # Vite VITE_HOST: "0.0.0.0" VITE_PORT: "5174" - volumes: - # Mount entire project for hot reload with SELinux context - - .:/app:Z - # Named volumes for performance and permission isolation - - app_vendor:/app/vendor - - app_node_modules:/app/node_modules depends_on: - - db + db: + condition: service_healthy networks: - - buckets + - buckets-network db: image: mariadb:11 - container_name: buckets_db + container_name: buckets_dev_db hostname: db restart: unless-stopped ports: @@ -65,39 +58,28 @@ services: MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD:-root}" volumes: - db_data:/var/lib/mysql - # Initialize with SQL scripts - - ./docker/mysql-init:/docker-entrypoint-initdb.d + - ../../docker/mysql-init:/docker-entrypoint-initdb.d healthcheck: test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"] interval: 10s timeout: 5s - retries: 3 + retries: 5 + start_period: 30s networks: - - buckets + - buckets-network - # Optional: Mailhog for email testing mailhog: image: mailhog/mailhog - container_name: buckets_mailhog + container_name: buckets_dev_mailhog restart: unless-stopped ports: - - "1026:1025" # SMTP server - - "8026:8025" # Web UI + - "1026:1025" + - "8026:8025" networks: - - buckets - - # Optional: Redis for caching/sessions - # redis: - # image: redis:alpine - # container_name: buckets_redis - # restart: unless-stopped - # ports: - # - "6379:6379" - # networks: - # - buckets + - buckets-network networks: - buckets: + buckets-network: driver: bridge volumes: diff --git a/shell.nix b/shell.nix index 9e3ad63..6105d81 100644 --- a/shell.nix +++ b/shell.nix @@ -5,216 +5,143 @@ pkgs.mkShell { # PHP and tools php83 php83Packages.composer - + # Node.js and npm - nodejs_20 - + nodejs_22 + # Container tools podman podman-compose - - # Database client (optional, for direct DB access) - mariadb-client + + # Database client (for direct DB access) + mariadb.client # Utilities git curl gnumake ]; - + shellHook = '' - # Export user/group IDs for Docker permission matching export USER_ID=$(id -u) export GROUP_ID=$(id -g) - # Use keep-id for proper permission mapping in rootless podman export PODMAN_USERNS=keep-id - - # Define helper functions - dev-rebuild() { - echo "🔨 Rebuilding development environment..." - PODMAN_USERNS=keep-id podman-compose down -v - PODMAN_USERNS=keep-id podman-compose build --no-cache app - PODMAN_USERNS=keep-id podman-compose up -d - - echo "📦 Installing dependencies..." - # Wait for containers to be ready - echo " Waiting for containers to be ready..." - sleep 5 - - # Wait for database to be healthy - echo " Waiting for database to be ready..." - for i in {1..30}; do - if podman-compose exec db mariadb -u root -proot -e "SELECT 1" > /dev/null 2>&1; then - echo " Database is ready!" - break - fi - if [ $i -eq 30 ]; then - echo " ⚠️ Database not ready after 30 seconds" - fi - sleep 1 - done - - # Install composer dependencies - echo " Installing composer packages..." - podman-compose exec app composer install --no-interaction || echo "⚠️ Composer install failed" - - # Install npm dependencies - echo " Installing npm packages..." - podman-compose exec app npm install || echo "⚠️ NPM install failed" - - # Run migrations - echo " Running database migrations..." - sleep 2 # Extra wait to ensure DB is fully ready - podman-compose exec app php artisan migrate --force || echo "⚠️ Migrations failed" - - # Restart app container to ensure Vite picks up all changes - echo " Restarting app container..." - podman-compose restart app - - echo "✅ Rebuild complete! Check logs with: dev-logs" - echo "" - echo "📍 Services available at:" - echo " App: http://localhost:8100" - echo " Vite: http://localhost:5174" - echo " Mailhog: http://localhost:8026" - echo " MariaDB: localhost:3307" - } - - dev-rebuild-quick() { - echo "⚡ Quick rebuild (keeping volumes)..." - PODMAN_USERNS=keep-id podman-compose down - PODMAN_USERNS=keep-id podman-compose build app - PODMAN_USERNS=keep-id podman-compose up -d - echo "✅ Quick rebuild complete!" - } - + + # 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 development environment..." - PODMAN_USERNS=keep-id podman-compose up -d - echo "✅ Dev environment started!" + echo "Starting services..." + PODMAN_USERNS=keep-id podman-compose -f $COMPOSE_FILE up -d "$@" echo "" - echo "📍 Services available at:" - echo " App: http://localhost:8100" - echo " Vite: http://localhost:5174" - echo " Mailhog: http://localhost:8026" - echo " MariaDB: localhost:3307" + podman-compose -f $COMPOSE_FILE ps + echo "" + echo "App available at: http://localhost:8100" } - + dev-down() { - echo "🛑 Stopping development environment..." - podman-compose down - echo "✅ Dev environment stopped!" - } - - dev-restart() { - echo "🔄 Restarting development environment..." - podman-compose restart - echo "✅ Dev environment restarted!" - } - - dev-logs() { - podman-compose logs -f "$@" - } - - dev-shell() { - podman-compose exec app sh - } - - dev-artisan() { - podman-compose exec app php artisan "$@" - } - - dev-fix-permissions() { - echo "🔧 Fixing file permissions..." - echo "This will require sudo to fix Docker-created files" - sudo chown -R $(id -u):$(id -g) storage/ bootstrap/cache/ vendor/ node_modules/ 2>/dev/null || true - echo "✅ Permissions fixed!" - } - - prod-build() { - local TAG="''${1:-latest}" - local REGISTRY="codeberg.org" - local NAMESPACE="lvl0" - local IMAGE_NAME="buckets" - - echo "🔨 Building production image..." - podman build -f Dockerfile -t ''${REGISTRY}/''${NAMESPACE}/''${IMAGE_NAME}:''${TAG} . - - echo "✅ Build complete: ''${REGISTRY}/''${NAMESPACE}/''${IMAGE_NAME}:''${TAG}" - echo "Run 'prod-push' to push to Codeberg" - } - - prod-push() { - local TAG="''${1:-latest}" - local REGISTRY="codeberg.org" - local NAMESPACE="lvl0" - local IMAGE_NAME="buckets" - - echo "📤 Pushing to Codeberg registry..." - if podman push ''${REGISTRY}/''${NAMESPACE}/''${IMAGE_NAME}:''${TAG}; then - echo "✅ Image pushed to ''${REGISTRY}/''${NAMESPACE}/''${IMAGE_NAME}:''${TAG}" + if [[ "$1" == "-v" ]]; then + echo "Stopping services and removing volumes..." + podman-compose -f $COMPOSE_FILE down -v else - echo "❌ Failed to push image. Did you run 'prod-build' first?" - echo " Also make sure you're logged in with 'prod-login'" + 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:8100" + } + + 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 "$@" + } + + # =================== + # BUILD COMMANDS + # =================== + base-build() { + local image="forge.lvl0.xyz/lvl0/buckets: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 - } - - prod-build-push() { - local TAG="''${1:-latest}" - prod-build "$TAG" && prod-push "$TAG" - } - - prod-login() { - echo "📝 Logging into Codeberg registry..." - podman login codeberg.org - } - - echo "🚀 Buckets Development Environment" - echo "=======================================" - echo "PHP: $(php --version | head -n1)" - echo "Node: $(node --version)" - echo "Podman: $(podman --version)" - echo "Podman-compose: $(podman-compose --version 2>/dev/null || echo 'checking...')" - echo "" - echo "Development commands:" - echo " dev-up - Start development environment" - echo " dev-down - Stop development environment" - echo " dev-restart - Restart containers" - echo " dev-rebuild - Full rebuild (removes volumes)" - echo " dev-rebuild-quick - Quick rebuild (keeps volumes)" - echo " dev-logs [svc] - Follow logs (default: all)" - echo " dev-shell - Enter app container" - echo " dev-artisan - Run artisan commands" - echo " dev-fix-permissions - Fix Docker-created file permissions" - echo "" - echo "Production commands:" - echo " prod-login - Login to Codeberg registry" - echo " prod-build [tag] - Build production image (default: latest)" - echo " prod-push [tag] - Push image to Codeberg" - echo " prod-build-push - Build and push in one command" - echo "" - - # Auto-start prompt - if [ -f "docker-compose.yml" ]; then - read -p "Start development containers? (y/N) " -n 1 -r - echo - if [[ $REPLY =~ ^[Yy]$ ]]; then - echo "Starting containers..." - podman-compose up -d - - # Wait a moment for containers to start - sleep 3 - - echo "" - echo "✅ Services should be available at:" - echo " App: http://localhost:8100" - echo " Vite: http://localhost:5174" - echo " Mailhog: http://localhost:8026" - echo " MariaDB: localhost:3307" - echo "" - echo "Run 'podman-compose logs -f app' to follow logs" + + echo "" + echo "Pushing to registry..." + if ! podman push "$image"; then + echo "Push failed!" + return 1 fi - fi + + echo "" + echo "Done! Image pushed: $image" + } + + # =================== + # WELCOME MESSAGE + # =================== + echo "" + echo "=================================================" + echo " Buckets 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-shell Shell into app container" + echo " dev-artisan Run artisan command" + echo " base-build Build and push image" + echo "" + echo "Services:" + echo " app Laravel + Vite http://localhost:8100" + echo " db MariaDB localhost:3307" + echo " mailhog Web UI http://localhost:8026" + echo "" ''; -} \ No newline at end of file +}