Move docker-compose to docker/dev, modernize shell.nix, migrate to Forgejo registry
This commit is contained in:
parent
0f02939f27
commit
5614fc3915
3 changed files with 146 additions and 237 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
# Production Docker Compose
|
# Production Docker Compose
|
||||||
services:
|
services:
|
||||||
app:
|
app:
|
||||||
image: codeberg.org/lvl0/buckets:latest
|
image: forge.lvl0.xyz/lvl0/buckets:latest
|
||||||
container_name: buckets_app
|
container_name: buckets_app
|
||||||
restart: always
|
restart: always
|
||||||
ports:
|
ports:
|
||||||
|
|
|
||||||
|
|
@ -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:
|
services:
|
||||||
app:
|
app:
|
||||||
build:
|
build:
|
||||||
context: .
|
context: ../..
|
||||||
dockerfile: Dockerfile.dev
|
dockerfile: Dockerfile.dev
|
||||||
container_name: buckets_app
|
container_name: buckets_dev_app
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
# Remove user directive to run as root in container
|
|
||||||
# The container will handle permissions internally
|
|
||||||
ports:
|
ports:
|
||||||
- "8100:8000" # Laravel app
|
- "8100:8000"
|
||||||
- "5174:5173" # Vite dev server
|
- "5174:5173"
|
||||||
|
volumes:
|
||||||
|
- ../..:/app
|
||||||
|
- app_vendor:/app/vendor
|
||||||
|
- app_node_modules:/app/node_modules
|
||||||
environment:
|
environment:
|
||||||
# Laravel
|
|
||||||
APP_NAME: "${APP_NAME:-buckets}"
|
APP_NAME: "${APP_NAME:-buckets}"
|
||||||
APP_ENV: "${APP_ENV:-local}"
|
APP_ENV: "${APP_ENV:-local}"
|
||||||
APP_KEY: "${APP_KEY:-base64:YOUR_KEY_HERE}"
|
APP_KEY: "${APP_KEY:-base64:YOUR_KEY_HERE}"
|
||||||
APP_DEBUG: "${APP_DEBUG:-true}"
|
APP_DEBUG: "${APP_DEBUG:-true}"
|
||||||
APP_URL: "${APP_URL:-http://localhost:8100}"
|
APP_URL: "${APP_URL:-http://localhost:8100}"
|
||||||
|
|
||||||
# Database
|
|
||||||
DB_CONNECTION: mysql
|
DB_CONNECTION: mysql
|
||||||
DB_HOST: db
|
DB_HOST: db
|
||||||
DB_PORT: 3306
|
DB_PORT: 3306
|
||||||
DB_DATABASE: "${DB_DATABASE:-buckets}"
|
DB_DATABASE: "${DB_DATABASE:-buckets}"
|
||||||
DB_USERNAME: "${DB_USERNAME:-buckets}"
|
DB_USERNAME: "${DB_USERNAME:-buckets}"
|
||||||
DB_PASSWORD: "${DB_PASSWORD:-buckets}"
|
DB_PASSWORD: "${DB_PASSWORD:-buckets}"
|
||||||
|
|
||||||
# Session & Cache
|
|
||||||
SESSION_DRIVER: "${SESSION_DRIVER:-file}"
|
SESSION_DRIVER: "${SESSION_DRIVER:-file}"
|
||||||
CACHE_DRIVER: "${CACHE_DRIVER:-file}"
|
CACHE_DRIVER: "${CACHE_DRIVER:-file}"
|
||||||
QUEUE_CONNECTION: "${QUEUE_CONNECTION:-sync}"
|
QUEUE_CONNECTION: "${QUEUE_CONNECTION:-sync}"
|
||||||
|
|
||||||
# Mail (for development)
|
|
||||||
MAIL_MAILER: "${MAIL_MAILER:-log}"
|
MAIL_MAILER: "${MAIL_MAILER:-log}"
|
||||||
|
|
||||||
# Vite
|
|
||||||
VITE_HOST: "0.0.0.0"
|
VITE_HOST: "0.0.0.0"
|
||||||
VITE_PORT: "5174"
|
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:
|
depends_on:
|
||||||
- db
|
db:
|
||||||
|
condition: service_healthy
|
||||||
networks:
|
networks:
|
||||||
- buckets
|
- buckets-network
|
||||||
|
|
||||||
db:
|
db:
|
||||||
image: mariadb:11
|
image: mariadb:11
|
||||||
container_name: buckets_db
|
container_name: buckets_dev_db
|
||||||
hostname: db
|
hostname: db
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
|
|
@ -65,39 +58,28 @@ services:
|
||||||
MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD:-root}"
|
MYSQL_ROOT_PASSWORD: "${DB_ROOT_PASSWORD:-root}"
|
||||||
volumes:
|
volumes:
|
||||||
- db_data:/var/lib/mysql
|
- db_data:/var/lib/mysql
|
||||||
# Initialize with SQL scripts
|
- ../../docker/mysql-init:/docker-entrypoint-initdb.d
|
||||||
- ./docker/mysql-init:/docker-entrypoint-initdb.d
|
|
||||||
healthcheck:
|
healthcheck:
|
||||||
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
||||||
interval: 10s
|
interval: 10s
|
||||||
timeout: 5s
|
timeout: 5s
|
||||||
retries: 3
|
retries: 5
|
||||||
|
start_period: 30s
|
||||||
networks:
|
networks:
|
||||||
- buckets
|
- buckets-network
|
||||||
|
|
||||||
# Optional: Mailhog for email testing
|
|
||||||
mailhog:
|
mailhog:
|
||||||
image: mailhog/mailhog
|
image: mailhog/mailhog
|
||||||
container_name: buckets_mailhog
|
container_name: buckets_dev_mailhog
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
ports:
|
ports:
|
||||||
- "1026:1025" # SMTP server
|
- "1026:1025"
|
||||||
- "8026:8025" # Web UI
|
- "8026:8025"
|
||||||
networks:
|
networks:
|
||||||
- buckets
|
- buckets-network
|
||||||
|
|
||||||
# Optional: Redis for caching/sessions
|
|
||||||
# redis:
|
|
||||||
# image: redis:alpine
|
|
||||||
# container_name: buckets_redis
|
|
||||||
# restart: unless-stopped
|
|
||||||
# ports:
|
|
||||||
# - "6379:6379"
|
|
||||||
# networks:
|
|
||||||
# - buckets
|
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
buckets:
|
buckets-network:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
257
shell.nix
257
shell.nix
|
|
@ -7,14 +7,14 @@ pkgs.mkShell {
|
||||||
php83Packages.composer
|
php83Packages.composer
|
||||||
|
|
||||||
# Node.js and npm
|
# Node.js and npm
|
||||||
nodejs_20
|
nodejs_22
|
||||||
|
|
||||||
# Container tools
|
# Container tools
|
||||||
podman
|
podman
|
||||||
podman-compose
|
podman-compose
|
||||||
|
|
||||||
# Database client (optional, for direct DB access)
|
# Database client (for direct DB access)
|
||||||
mariadb-client
|
mariadb.client
|
||||||
|
|
||||||
# Utilities
|
# Utilities
|
||||||
git
|
git
|
||||||
|
|
@ -23,198 +23,125 @@ pkgs.mkShell {
|
||||||
];
|
];
|
||||||
|
|
||||||
shellHook = ''
|
shellHook = ''
|
||||||
# Export user/group IDs for Docker permission matching
|
|
||||||
export USER_ID=$(id -u)
|
export USER_ID=$(id -u)
|
||||||
export GROUP_ID=$(id -g)
|
export GROUP_ID=$(id -g)
|
||||||
# Use keep-id for proper permission mapping in rootless podman
|
|
||||||
export PODMAN_USERNS=keep-id
|
export PODMAN_USERNS=keep-id
|
||||||
|
|
||||||
# Define helper functions
|
# Compose file location
|
||||||
dev-rebuild() {
|
COMPOSE_FILE="$PWD/docker/dev/docker-compose.yml"
|
||||||
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
|
# ALIASES
|
||||||
echo " Waiting for containers to be ready..."
|
# ===================
|
||||||
sleep 5
|
alias pc='podman-compose -f $COMPOSE_FILE'
|
||||||
|
|
||||||
# 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!"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
# ===================
|
||||||
|
# DEV COMMANDS
|
||||||
|
# ===================
|
||||||
dev-up() {
|
dev-up() {
|
||||||
echo "🚀 Starting development environment..."
|
echo "Starting services..."
|
||||||
PODMAN_USERNS=keep-id podman-compose up -d
|
PODMAN_USERNS=keep-id podman-compose -f $COMPOSE_FILE up -d "$@"
|
||||||
echo "✅ Dev environment started!"
|
|
||||||
echo ""
|
echo ""
|
||||||
echo "📍 Services available at:"
|
podman-compose -f $COMPOSE_FILE ps
|
||||||
echo " App: http://localhost:8100"
|
echo ""
|
||||||
echo " Vite: http://localhost:5174"
|
echo "App available at: http://localhost:8100"
|
||||||
echo " Mailhog: http://localhost:8026"
|
|
||||||
echo " MariaDB: localhost:3307"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dev-down() {
|
dev-down() {
|
||||||
echo "🛑 Stopping development environment..."
|
if [[ "$1" == "-v" ]]; then
|
||||||
podman-compose down
|
echo "Stopping services and removing volumes..."
|
||||||
echo "✅ Dev environment stopped!"
|
podman-compose -f $COMPOSE_FILE down -v
|
||||||
|
else
|
||||||
|
echo "Stopping services..."
|
||||||
|
podman-compose -f $COMPOSE_FILE down
|
||||||
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
dev-restart() {
|
dev-restart() {
|
||||||
echo "🔄 Restarting development environment..."
|
echo "Restarting services..."
|
||||||
podman-compose restart
|
podman-compose -f $COMPOSE_FILE restart "$@"
|
||||||
echo "✅ Dev environment restarted!"
|
}
|
||||||
|
|
||||||
|
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() {
|
dev-logs() {
|
||||||
podman-compose logs -f "$@"
|
podman-compose -f $COMPOSE_FILE logs -f app "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
dev-logs-db() {
|
||||||
|
podman-compose -f $COMPOSE_FILE logs -f db "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
dev-shell() {
|
dev-shell() {
|
||||||
podman-compose exec app sh
|
podman-compose -f $COMPOSE_FILE exec app sh
|
||||||
}
|
}
|
||||||
|
|
||||||
dev-artisan() {
|
dev-artisan() {
|
||||||
podman-compose exec app php artisan "$@"
|
podman-compose -f $COMPOSE_FILE exec app php artisan "$@"
|
||||||
}
|
}
|
||||||
|
|
||||||
dev-fix-permissions() {
|
# ===================
|
||||||
echo "🔧 Fixing file permissions..."
|
# BUILD COMMANDS
|
||||||
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
|
base-build() {
|
||||||
echo "✅ Permissions fixed!"
|
local image="forge.lvl0.xyz/lvl0/buckets:latest"
|
||||||
}
|
|
||||||
|
|
||||||
prod-build() {
|
# Check if logged in, prompt if not
|
||||||
local TAG="''${1:-latest}"
|
if ! podman login --get-login forge.lvl0.xyz &>/dev/null; then
|
||||||
local REGISTRY="codeberg.org"
|
echo "Not logged in to forge.lvl0.xyz"
|
||||||
local NAMESPACE="lvl0"
|
podman login forge.lvl0.xyz || return 1
|
||||||
local IMAGE_NAME="buckets"
|
fi
|
||||||
|
|
||||||
echo "🔨 Building production image..."
|
echo "Building image: $image"
|
||||||
podman build -f Dockerfile -t ''${REGISTRY}/''${NAMESPACE}/''${IMAGE_NAME}:''${TAG} .
|
if ! podman build -t "$image" -f Dockerfile .; then
|
||||||
|
echo "Build failed!"
|
||||||
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}"
|
|
||||||
else
|
|
||||||
echo "❌ Failed to push image. Did you run 'prod-build' first?"
|
|
||||||
echo " Also make sure you're logged in with 'prod-login'"
|
|
||||||
return 1
|
return 1
|
||||||
fi
|
fi
|
||||||
}
|
|
||||||
|
|
||||||
prod-build-push() {
|
echo ""
|
||||||
local TAG="''${1:-latest}"
|
echo "Pushing to registry..."
|
||||||
prod-build "$TAG" && prod-push "$TAG"
|
if ! podman push "$image"; then
|
||||||
}
|
echo "Push failed!"
|
||||||
|
return 1
|
||||||
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"
|
|
||||||
fi
|
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 <cmd> 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 ""
|
||||||
'';
|
'';
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue