Add podman compose dev environment #1

Merged
myrmidex merged 2 commits from setup/container-env into main 2026-08-23 00:03:54 +02:00
5 changed files with 314 additions and 3 deletions
Showing only changes of commit f69f284840 - Show all commits

22
.dockerignore Normal file
View file

@ -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

96
Dockerfile.dev Normal file
View file

@ -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"]

11
docker/.env.example Normal file
View file

@ -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

View file

@ -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:

114
shell.nix
View file

@ -6,10 +6,16 @@ pkgs.mkShell {
php84 php84
php84Packages.composer php84Packages.composer
# Node.js and npm
nodejs_22
# Container tools # Container tools
podman podman
podman-compose podman-compose
# Database client (for direct DB access)
mariadb.client
# Utilities # Utilities
git git
curl curl
@ -18,5 +24,113 @@ pkgs.mkShell {
shellHook = '' shellHook = ''
export PATH="$HOME/.config/composer/vendor/bin:$PATH" 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 <cmd> Run artisan command"
echo " dev-composer <cmd> 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 ""
''; '';
} }