This document describes the development environment setup and best practices for AI agents working on this Rails application.
Before making ANY changes, always:
# 1. Check if containers are running
docker-compose ps
# 2. If web container is running, use it:
docker-compose exec web <your-command>
# 3. After code changes, restart if needed:
docker-compose exec web touch tmp/restart.txt
# 4. DO NOT rebuild unless Gemfile/Dockerfile changed!This project uses Docker Compose for local development. There are two primary workflows:
# Start only the dependencies (database and Redis)
docker-compose up -d db redis
# Start an interactive bash session in the web container with port forwarding
docker-compose run --service-ports web /bin/bash
# Inside the container, start the Rails server manually
rails s -b 0.0.0.0This allows you to run commands interactively and manually control when the server starts/stops.
# Start all services (web server starts automatically)
docker-compose upThis starts all services including the Rails server automatically.
Rails is configured for automatic code reloading in development:
- Automatic reloading: Rails automatically reloads code changes. No restart needed for most changes.
- Manual restart trigger: If you need to manually trigger a restart, touch the restart file:
This works because Puma has the
touch tmp/restart.txt
tmp_restartplugin enabled.
ALWAYS check if a development server is already running:
-
Check for running containers:
docker-compose ps
Look for a
webservice that shows as "Up" or "running" -
Check if port 3000 is in use:
lsof -i :3000 # or netstat -tulpn | grep :3000
DO NOT start a new container or server instance! DO NOT rebuild Docker containers unless absolutely necessary!
Instead:
-
Use the existing container:
# Get the container name/ID docker-compose ps web # Execute commands in the existing container docker-compose exec web <command>
-
After making code changes, trigger a reload:
docker-compose exec web touch tmp/restart.txtOr if you're in the same container, just:
touch tmp/restart.txt
-
Most code changes auto-reload, but restart file is useful for:
- Configuration changes
- Initializer changes
- Gem changes (though these may require a full restart)
IMPORTANT: When to Rebuild Containers
ONLY rebuild Docker containers when:
- Gemfile or Gemfile.lock changed (new gems added)
- Dockerfile changed
- Docker-compose.yml changed in ways that affect the build
DO NOT rebuild for:
- Application code changes (use
touch tmp/restart.txt) - Configuration file changes (use
touch tmp/restart.txt) - Database schema changes (run migrations in existing container)
- Most development work (code auto-reloads)
-
Start dependencies first:
docker-compose up -d db redis
-
Wait for services to be healthy:
docker-compose ps # Check db and redis are healthy -
Start the web service:
# Option A: Start with docker-compose (auto-starts server) docker-compose up web # Option B: Interactive mode (recommended for development) docker-compose run --service-ports web /bin/bash # Then inside: rails s -b 0.0.0.0
When running database commands, use the existing container if available:
# If server is running
docker-compose exec web rails db:migrate
docker-compose exec web rails db:seed
docker-compose exec web rails console
# If server is not running
docker-compose run --rm web rails db:migrate
docker-compose run --rm web rails db:seed
docker-compose run --rm web rails consoledocker-compose ps# All services
docker-compose logs -f
# Specific service
docker-compose logs -f web
docker-compose logs -f db
docker-compose logs -f redis
docker-compose logs -f sidekiq# Stop all services
docker-compose down
# Stop specific service
docker-compose stop webOnly rebuild when Gemfile, Dockerfile, or docker-compose.yml changes:
# Rebuild images (ONLY after Gemfile/Dockerfile changes)
docker-compose build
# Rebuild and restart
docker-compose up --buildFor most code changes, just use the restart file:
docker-compose exec web touch tmp/restart.txtKey environment variables are set in docker-compose.yml:
DATABASE_URL: PostgreSQL connection stringREDIS_URL: Redis connection stringRAILS_ENV: Set todevelopment
- Web server: http://localhost:3000
- PostgreSQL: localhost:5432
- Redis: localhost:6379
- Sidekiq: Runs as a background service (no web UI by default)
If port 3000 is already in use:
- Check what's using it:
lsof -i :3000 - Use the existing container, or stop the conflicting service
Ensure db service is healthy:
docker-compose ps db
# Should show "healthy" status- Check that Rails reloading is enabled (it is by default in development)
- Try manual restart:
touch tmp/restart.txt - Check for syntax errors in logs:
docker-compose logs web
Before any development work:
- ✅ Check if server is running:
docker-compose ps - ✅ If running: Use existing container with
docker-compose exec web - ✅ If not running: Start with
docker-compose run --service-ports web /bin/bash - ✅ After code changes: Most auto-reload; use
touch tmp/restart.txtfor config/initializer changes - ✅ NEVER rebuild containers unless Gemfile/Dockerfile changed - use
touch tmp/restart.txtinstead - ✅ Never start conflicting services or containers