From c0acf1e227b99abf08764e835f4eb2350e2257fe Mon Sep 17 00:00:00 2001 From: Robert Perez Date: Fri, 10 Jul 2026 23:57:50 +0000 Subject: [PATCH] Add sandbox Docker compose stack, project structure, and user manual --- README.md | 122 ++++++++++++++++++++++++++++++++++++ docker-compose.override.yml | 23 +++++++ docker-compose.yml | 70 +++++++++++++++++++++ start-sandbox.sh | 4 ++ 4 files changed, 219 insertions(+) create mode 100644 README.md create mode 100644 docker-compose.override.yml create mode 100644 docker-compose.yml create mode 100644 start-sandbox.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..b256113 --- /dev/null +++ b/README.md @@ -0,0 +1,122 @@ +# Petmaster Dev Sandbox + +Docker-based development environment for the petmaster project. + +## Quick Start + +```bash +# Start the dev stack +bash start-sandbox.sh + +# Or manually: +sudo -g docker docker compose up -d +``` + +## Architecture + +The sandbox provides four services: + +| Service | Image | Port | Purpose | +|---------|-------|------|---------| +| **PostgreSQL 16** | `postgres:16-alpine` | 5432 | Development database | +| **Redis 7** | `redis:7-alpine` | 6379 | Caching / session store | +| **Node.js 22 (Dev)** | `node:22-alpine` | 9229 | Backend dev environment | +| **Node.js 22 (React)** | `node:22-alpine` | 3000 | Frontend dev server | + +## Configuration + +### Database Connection + +``` +PostgreSQL: postgresql://postgres:postgres@localhost:5432/petmaster_dev +Redis: redis://localhost:6379 +``` + +### Docker Auth + +Because our container doesn't own `/run/docker.sock`, all Docker commands must run with: + +```bash +sudo -g docker docker +``` + +The `start-sandbox.sh` script wraps this for convenience. + +## Managing the Sandbox + +### Start the stack +```bash +sudo -g docker docker compose up -d +``` + +### Stop the stack +```bash +sudo -g docker docker compose down +``` + +### Stop and clean volumes +```bash +sudo -g docker docker compose down -v +``` + +### View logs +```bash +sudo -g docker docker compose logs -f +``` + +### Run commands in containers +```bash +# Shell in the Node dev container +sudo -g docker docker exec -it petmaster-node-dev sh + +# Shell in PostgreSQL +sudo -g docker docker exec -it petmaster-postgres psql -U postgres + +# Redis CLI +sudo -g docker docker exec -it petmaster-redis redis-cli +``` + +### Frontend hot reload + +The override config maps `./frontend/src` into the React container. +Files on the host are visible at `/app/src` inside the container. +For full hot-reload, replace the placeholder container command with your actual dev server start command. + +## Health Checks + +Run the included healthcheck script to validate everything: + +```bash +bash healthcheck.sh +``` + +This checks: +- Container status (all running) +- PostgreSQL connectivity and query execution +- Redis PING/PONG +- Port reachability for all services + +## Volume Data + +Persistent data is stored in Docker volumes: +- `petmaster_postgres-data` — PostgreSQL data +- `petmaster_redis-data` — Redis data + +Node.js containers use ephemeral bind mounts (`./node-data`) for temporary files. + +## Troubleshooting + +### Permission denied on docker.sock +Ensure you're using `sudo -g docker` prefix: +```bash +sudo -g docker docker ps +``` + +### Port conflicts +If ports 5432, 6379, or 3000 are already in use, modify the port mappings in `docker-compose.yml`. + +### Stale containers +```bash +sudo -g docker docker compose down -v --remove-orphans +sudo -g docker docker compose up -d +``` diff --git a/docker-compose.override.yml b/docker-compose.override.yml new file mode 100644 index 0000000..948a98a --- /dev/null +++ b/docker-compose.override.yml @@ -0,0 +1,23 @@ +version: "3.8" + +services: + node-dev: + volumes: + - ./src:/app/src:cached + - ./package.json:/app/package.json + - ./package-lock.json:/app/package-lock.json + - ./tsconfig.json:/app/tsconfig.json + environment: + - NODE_ENV=development + - CHOKIDAR_USEPOLLING=true + + react-frontend: + volumes: + - ./frontend/src:/app/src:cached + - ./frontend/package.json:/app/package.json + - ./frontend/package-lock.json:/app/package-lock.json + - ./frontend/tsconfig.json:/app/tsconfig.json + environment: + - NODE_ENV=development + - CHOKIDAR_USEPOLLING=true + - FAST_REFRESH=false diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..f4b8169 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,70 @@ +version: "3.8" + +services: + postgres: + image: postgres:16-alpine + container_name: petmaster-postgres + restart: unless-stopped + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: petmaster_dev + ports: + - "5432:5432" + volumes: + - postgres-data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 + + redis: + image: redis:7-alpine + container_name: petmaster-redis + restart: unless-stopped + ports: + - "6379:6379" + volumes: + - redis-data:/data + healthcheck: + test: ["CMD", "redis-cli", "ping"] + interval: 10s + timeout: 5s + retries: 5 + + node-dev: + image: node:22-alpine + container_name: petmaster-node-dev + restart: unless-stopped + working_dir: /app + ports: + - "9229:9229" + volumes: + - ./node-data:/tmp/node-tmp + command: sh -c "while true; do sleep 3600; done" + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + + react-frontend: + image: node:22-alpine + container_name: petmaster-react-frontend + restart: unless-stopped + working_dir: /app + ports: + - "3000:3000" + volumes: + - ./node-data:/tmp/node-tmp + command: sh -c "while true; do sleep 3600; done" + depends_on: + postgres: + condition: service_healthy + redis: + condition: service_healthy + +volumes: + postgres-data: + redis-data: diff --git a/start-sandbox.sh b/start-sandbox.sh new file mode 100644 index 0000000..129f89b --- /dev/null +++ b/start-sandbox.sh @@ -0,0 +1,4 @@ +#!/bin/bash +cd /home/robert/petmaster +sudo -g docker docker compose up -d 2>&1 +echo "EXIT_CODE=$?"