Add frontend and Caddy to Docker Compose dev environment
Containerize the frontend dev server (Vite) and add a Caddy reverse proxy for HTTPS termination, replacing the manual local setup. The Caddy config proxies /api/* to the backend and everything else to the frontend dev server. Also simplify start.sh: remove --local Poetry mode, extract get_compose_cmd helper, and document new services and DEV_HOST env var.
This commit is contained in:
parent
2626870396
commit
e55902d813
3 changed files with 89 additions and 92 deletions
|
|
@ -1,5 +1,3 @@
|
|||
version: "3.8"
|
||||
|
||||
services:
|
||||
redis:
|
||||
image: redis:8
|
||||
|
|
@ -111,6 +109,37 @@ services:
|
|||
networks:
|
||||
- rec-network
|
||||
|
||||
frontend:
|
||||
image: node:24-alpine
|
||||
container_name: rec-frontend
|
||||
working_dir: /app
|
||||
ports:
|
||||
- "5173:5173"
|
||||
volumes:
|
||||
- ./frontend:/app
|
||||
- frontend_node_modules:/app/node_modules
|
||||
environment:
|
||||
- DEV_HOST=${DEV_HOST:-localhost}
|
||||
command: sh -c "npm ci && npm run dev -- --host"
|
||||
networks:
|
||||
- rec-network
|
||||
|
||||
caddy:
|
||||
image: caddy:alpine
|
||||
container_name: rec-caddy
|
||||
ports:
|
||||
- "443:443"
|
||||
volumes:
|
||||
- ./frontend/Caddyfile.dev:/etc/caddy/Caddyfile
|
||||
- caddy_data:/data
|
||||
environment:
|
||||
- DEV_HOST=${DEV_HOST:-localhost}
|
||||
depends_on:
|
||||
- frontend
|
||||
- app
|
||||
networks:
|
||||
- rec-network
|
||||
|
||||
networks:
|
||||
rec-network:
|
||||
driver: bridge
|
||||
|
|
@ -119,3 +148,5 @@ volumes:
|
|||
redis_data:
|
||||
mysql_data:
|
||||
app_venv:
|
||||
frontend_node_modules:
|
||||
caddy_data:
|
||||
|
|
|
|||
11
crawler/frontend/Caddyfile.dev
Normal file
11
crawler/frontend/Caddyfile.dev
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{$DEV_HOST:localhost}:443 {
|
||||
tls internal
|
||||
|
||||
handle /api/* {
|
||||
reverse_proxy app:5001
|
||||
}
|
||||
|
||||
handle {
|
||||
reverse_proxy frontend:5173
|
||||
}
|
||||
}
|
||||
135
crawler/start.sh
135
crawler/start.sh
|
|
@ -2,9 +2,13 @@
|
|||
set -eu
|
||||
|
||||
# Real Estate Crawler - Development Server
|
||||
# Starts all backend services + frontend + Caddy HTTPS proxy via Docker Compose.
|
||||
#
|
||||
# Usage:
|
||||
# ./start.sh - Start with Docker (recommended)
|
||||
# ./start.sh --local - Start locally (requires Poetry and dependencies)
|
||||
# ./start.sh - Start all services (backend + frontend)
|
||||
# ./start.sh --build - Rebuild images before starting
|
||||
# ./start.sh --down - Stop and remove all containers
|
||||
# ./start.sh --logs - Follow logs from all services
|
||||
# ./start.sh --help - Show help
|
||||
|
||||
show_help() {
|
||||
|
|
@ -14,16 +18,40 @@ show_help() {
|
|||
echo ""
|
||||
echo "Options:"
|
||||
echo " (default) Start all services with Docker Compose"
|
||||
echo " --local Run locally with Poetry (requires local deps)"
|
||||
echo " --build Rebuild Docker images before starting"
|
||||
echo " --down Stop and remove all containers"
|
||||
echo " --logs Follow logs from all services"
|
||||
echo " --help Show this help message"
|
||||
echo ""
|
||||
echo "Services started:"
|
||||
echo " redis Redis broker + cache (port 6379)"
|
||||
echo " mysql MySQL database (port 3306)"
|
||||
echo " app FastAPI backend (hot-reload) (port 5001)"
|
||||
echo " celery Celery background worker"
|
||||
echo " celery-beat Celery periodic scheduler"
|
||||
echo " frontend Vite dev server (hot-reload) (port 5173)"
|
||||
echo " caddy HTTPS reverse proxy (port 443)"
|
||||
echo ""
|
||||
echo "Environment variables:"
|
||||
echo " DEV_HOST Hostname for HTTPS access (default: localhost)"
|
||||
echo " Set this to your dev machine's hostname for OIDC auth."
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " ./start.sh # Start with Docker"
|
||||
echo " ./start.sh --build # Rebuild and start"
|
||||
echo " ./start.sh --local # Run locally with Poetry"
|
||||
echo " ./start.sh # Start everything"
|
||||
echo " ./start.sh --build # Rebuild and start"
|
||||
echo " DEV_HOST=devvm.local ./start.sh # Start with custom hostname"
|
||||
}
|
||||
|
||||
get_compose_cmd() {
|
||||
if command -v docker &> /dev/null; then
|
||||
echo "docker compose"
|
||||
elif command -v podman-compose &> /dev/null; then
|
||||
echo "podman-compose"
|
||||
else
|
||||
echo "❌ Error: Neither docker nor podman-compose found." >&2
|
||||
echo " Install Docker: https://docs.docker.com/get-docker/" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
start_docker() {
|
||||
|
|
@ -32,96 +60,26 @@ start_docker() {
|
|||
build_flag="--build"
|
||||
fi
|
||||
|
||||
echo "🐳 Starting services with Docker Compose..."
|
||||
echo "Starting all services with Docker Compose..."
|
||||
echo ""
|
||||
|
||||
# Check if docker/podman is available
|
||||
if command -v docker &> /dev/null; then
|
||||
COMPOSE_CMD="docker compose"
|
||||
elif command -v podman-compose &> /dev/null; then
|
||||
COMPOSE_CMD="podman-compose"
|
||||
else
|
||||
echo "❌ Error: Neither docker nor podman-compose found."
|
||||
echo " Install Docker: https://docs.docker.com/get-docker/"
|
||||
echo " Or run locally: ./start.sh --local"
|
||||
exit 1
|
||||
fi
|
||||
local compose_cmd
|
||||
compose_cmd=$(get_compose_cmd)
|
||||
|
||||
$COMPOSE_CMD up $build_flag
|
||||
$compose_cmd up $build_flag
|
||||
}
|
||||
|
||||
stop_docker() {
|
||||
echo "🛑 Stopping all containers..."
|
||||
if command -v docker &> /dev/null; then
|
||||
docker compose down
|
||||
elif command -v podman-compose &> /dev/null; then
|
||||
podman-compose down
|
||||
fi
|
||||
echo "Stopping all containers..."
|
||||
local compose_cmd
|
||||
compose_cmd=$(get_compose_cmd)
|
||||
$compose_cmd down
|
||||
}
|
||||
|
||||
show_logs() {
|
||||
if command -v docker &> /dev/null; then
|
||||
docker compose logs -f
|
||||
elif command -v podman-compose &> /dev/null; then
|
||||
podman-compose logs -f
|
||||
fi
|
||||
}
|
||||
|
||||
start_local() {
|
||||
echo "🛠️ Starting locally with Poetry..."
|
||||
echo ""
|
||||
|
||||
# Check Poetry is available
|
||||
if ! command -v poetry &> /dev/null; then
|
||||
echo "❌ Error: Poetry not found."
|
||||
echo " Install: curl -sSL https://install.python-poetry.org | python3 -"
|
||||
echo " Or use Docker: ./start.sh"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Source .env if it exists
|
||||
if [[ -f .env ]]; then
|
||||
set -a
|
||||
source .env
|
||||
set +a
|
||||
fi
|
||||
|
||||
ENV_MODE=${ENV:-"dev"}
|
||||
|
||||
# Ensure Redis is running
|
||||
if ! nc -z localhost 6379 2>/dev/null; then
|
||||
echo "📦 Starting Redis container..."
|
||||
docker run -d --rm --name rec-redis-local -p 6379:6379 redis:latest || true
|
||||
sleep 2
|
||||
fi
|
||||
|
||||
echo "✅ Redis OK"
|
||||
|
||||
# Test celery connection
|
||||
poetry run python celery_app.py
|
||||
|
||||
# Start Celery worker in background
|
||||
echo "🔧 Starting Celery worker..."
|
||||
if [[ "$ENV_MODE" == "dev" ]]; then
|
||||
poetry run celery -A celery_app worker --loglevel=info &
|
||||
else
|
||||
poetry run alembic upgrade head
|
||||
poetry run celery -A celery_app worker --beat --loglevel=info &
|
||||
fi
|
||||
CELERY_PID=$!
|
||||
|
||||
cleanup() {
|
||||
echo ""
|
||||
echo "🛑 Stopping Celery worker (PID: $CELERY_PID)..."
|
||||
kill "$CELERY_PID" 2>/dev/null || true
|
||||
wait "$CELERY_PID" 2>/dev/null || true
|
||||
}
|
||||
trap cleanup EXIT SIGINT SIGTERM
|
||||
|
||||
# Start uvicorn
|
||||
echo "🚀 Starting API server on http://localhost:5001"
|
||||
echo ""
|
||||
poetry run uvicorn api.app:app --host 0.0.0.0 --port 5001 --reload
|
||||
local compose_cmd
|
||||
compose_cmd=$(get_compose_cmd)
|
||||
$compose_cmd logs -f
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
|
|
@ -129,9 +87,6 @@ case "${1:-}" in
|
|||
--help|-h)
|
||||
show_help
|
||||
;;
|
||||
--local)
|
||||
start_local
|
||||
;;
|
||||
--down)
|
||||
stop_docker
|
||||
;;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue