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:
|
services:
|
||||||
redis:
|
redis:
|
||||||
image: redis:8
|
image: redis:8
|
||||||
|
|
@ -111,6 +109,37 @@ services:
|
||||||
networks:
|
networks:
|
||||||
- rec-network
|
- 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:
|
networks:
|
||||||
rec-network:
|
rec-network:
|
||||||
driver: bridge
|
driver: bridge
|
||||||
|
|
@ -119,3 +148,5 @@ volumes:
|
||||||
redis_data:
|
redis_data:
|
||||||
mysql_data:
|
mysql_data:
|
||||||
app_venv:
|
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
|
set -eu
|
||||||
|
|
||||||
# Real Estate Crawler - Development Server
|
# Real Estate Crawler - Development Server
|
||||||
|
# Starts all backend services + frontend + Caddy HTTPS proxy via Docker Compose.
|
||||||
|
#
|
||||||
# Usage:
|
# Usage:
|
||||||
# ./start.sh - Start with Docker (recommended)
|
# ./start.sh - Start all services (backend + frontend)
|
||||||
# ./start.sh --local - Start locally (requires Poetry and dependencies)
|
# ./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
|
# ./start.sh --help - Show help
|
||||||
|
|
||||||
show_help() {
|
show_help() {
|
||||||
|
|
@ -14,16 +18,40 @@ show_help() {
|
||||||
echo ""
|
echo ""
|
||||||
echo "Options:"
|
echo "Options:"
|
||||||
echo " (default) Start all services with Docker Compose"
|
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 " --build Rebuild Docker images before starting"
|
||||||
echo " --down Stop and remove all containers"
|
echo " --down Stop and remove all containers"
|
||||||
echo " --logs Follow logs from all services"
|
echo " --logs Follow logs from all services"
|
||||||
echo " --help Show this help message"
|
echo " --help Show this help message"
|
||||||
echo ""
|
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 "Examples:"
|
||||||
echo " ./start.sh # Start with Docker"
|
echo " ./start.sh # Start everything"
|
||||||
echo " ./start.sh --build # Rebuild and start"
|
echo " ./start.sh --build # Rebuild and start"
|
||||||
echo " ./start.sh --local # Run locally with Poetry"
|
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() {
|
start_docker() {
|
||||||
|
|
@ -32,96 +60,26 @@ start_docker() {
|
||||||
build_flag="--build"
|
build_flag="--build"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "🐳 Starting services with Docker Compose..."
|
echo "Starting all services with Docker Compose..."
|
||||||
echo ""
|
echo ""
|
||||||
|
|
||||||
# Check if docker/podman is available
|
local compose_cmd
|
||||||
if command -v docker &> /dev/null; then
|
compose_cmd=$(get_compose_cmd)
|
||||||
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
|
|
||||||
|
|
||||||
$COMPOSE_CMD up $build_flag
|
$compose_cmd up $build_flag
|
||||||
}
|
}
|
||||||
|
|
||||||
stop_docker() {
|
stop_docker() {
|
||||||
echo "🛑 Stopping all containers..."
|
echo "Stopping all containers..."
|
||||||
if command -v docker &> /dev/null; then
|
local compose_cmd
|
||||||
docker compose down
|
compose_cmd=$(get_compose_cmd)
|
||||||
elif command -v podman-compose &> /dev/null; then
|
$compose_cmd down
|
||||||
podman-compose down
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
show_logs() {
|
show_logs() {
|
||||||
if command -v docker &> /dev/null; then
|
local compose_cmd
|
||||||
docker compose logs -f
|
compose_cmd=$(get_compose_cmd)
|
||||||
elif command -v podman-compose &> /dev/null; then
|
$compose_cmd logs -f
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parse arguments
|
# Parse arguments
|
||||||
|
|
@ -129,9 +87,6 @@ case "${1:-}" in
|
||||||
--help|-h)
|
--help|-h)
|
||||||
show_help
|
show_help
|
||||||
;;
|
;;
|
||||||
--local)
|
|
||||||
start_local
|
|
||||||
;;
|
|
||||||
--down)
|
--down)
|
||||||
stop_docker
|
stop_docker
|
||||||
;;
|
;;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue