Environment Management¶
SPOT Platform uses a simple environment system with APP_ENV as the single source of truth for determining which configuration and Docker Compose profiles to use.
Available Environments¶
| Environment | Purpose | Docker Compose Profiles | Default |
|---|---|---|---|
prod | Production deployment | None | Yes |
dev | Development with hot reload | dev | No |
test | Integration / E2E testing | dev, test | No |
How It Works¶
Precedence Chain¶
The system determines the active environment using this precedence (highest to lowest):
- Environment variable on the command line:
APP_ENV=dev make service:start .envfile:APP_ENV=prod- Default:
prod(if not set anywhere)
Environment Variable Flow¶
APP_ENV (command-line export or .env)
|
v
Docker Compose profiles selected
|
v
Containers started with the matching configuration
Switching Environments¶
Important: Explicit Restart Required¶
Changing APP_ENV requires an explicit container restart. There is no automatic hot-swap.
Method 1: Inline override (recommended for one-offs)¶
# Start in dev mode for one command
APP_ENV=dev make service:start
# Check status against the current containers
make service:status
The override only applies to that single command and does not modify your .env.
Method 2: Persistent change in .env¶
# 1. Edit .env
vim .env
# Change: APP_ENV=prod
# To: APP_ENV=dev
# 2. Restart so containers pick up the new profile set
make service:restart
Common Workflows¶
Development¶
# Start in dev mode with hot reload
APP_ENV=dev make service:start
# Make code changes (services hot-reload in dev)
# Edit services/api-gateway/src/main.py
# Tail the logs
make dev:logs
# When done
make service:stop
Testing¶
# Integration tests (the target sets APP_ENV=test automatically)
make test:integration
# Or run unit + integration in one go
make test
Production¶
Production deployments do not use this Makefile ; they run from the deploy repository with docker compose directly:
APP_ENV=prod is the default and the deploy compose file does not load any dev/test profile.
Environment-Specific Behaviour¶
Production (prod)¶
- Optimized for: stability, performance, security.
- Hot reload: disabled.
- Debug tools: disabled (no Adminer, no Mailhog).
- Dev dependencies: not installed.
- Compose profiles: none (base services only).
Development (dev)¶
- Optimized for: developer productivity.
- Hot reload: enabled (
uvicorn --reload). - Debug tools: enabled (Adminer, Mailhog, devtools container).
- Dev dependencies: installed.
- Volume mounts: read-write for source code.
- Debug ports: exposed (8091, 8092).
- Compose profiles:
--profile dev.
Test (test)¶
- Optimized for: isolated testing.
- Mock analyzers: included (
analyzer-mock-nlp,analyzer-mock-llm). - Log level:
WARNING(reduced verbosity). - Compose profiles:
--profile dev --profile test.
Safety Features¶
pytest Safety Check¶
Integration tests fail if APP_ENV != test:
# tests/conftest.py
def pytest_configure(config):
app_env = os.getenv("APP_ENV", "")
if app_env != "test":
raise RuntimeError("Integration tests must run in test environment")
This prevents accidental execution against development or production databases.
Troubleshooting¶
Services started in the wrong environment¶
# Stop services
make service:stop
# Verify .env has the correct APP_ENV
grep APP_ENV .env
# Start with the correct environment (inline override or edit .env)
APP_ENV=dev make service:start
Can't tell which environment is running¶
# APP_ENV is exported into every service container; inspect one:
docker compose exec api-gateway printenv APP_ENV
Want to force-restart with a new environment¶
# Complete teardown and restart
make service:stop
docker compose down -v # WARNING: destroys data
# Edit .env to set APP_ENV if needed
make service:start
Tests failing with environment error¶
# Error: Integration tests must run in test environment
# Solution: use the test target (it sets APP_ENV automatically)
make test:integration
# DO NOT run pytest directly:
# pytest tests/integration/ # this will fail
Best Practices¶
- Inline override for one-offs
-
APP_ENV=dev make service:startis clearer than editing.envwhen the change is temporary. -
Use the test targets for testing
-
make test:integrationandmake testsetAPP_ENV=testautomatically. Don't run pytest directly for integration tests. -
Keep
.envin sync with reality -
If you frequently use command-line overrides, consider updating
.envinstead. -
Document environment in deployment scripts
-
Explicitly set
APP_ENV=prod(or rely on the default) in production deployment scripts. -
Restart after changing
.env - Docker Compose needs to reload with the new environment.
FAQ¶
Q: Can I set APP_ENV via environment variable instead of .env?¶
A: Yes, the command-line value takes precedence:
Q: Do I need to restart when switching environments?¶
A: Yes, always. Docker Compose needs to:
- Load different profiles (dev/test).
- Apply different environment variables.
- Recreate containers with the new configuration.
Q: What happens if I change .env while services are running?¶
A: Nothing. Changes to .env only take effect when you restart:
Q: Can I run multiple environments simultaneously?¶
A: No, by design. The system uses a single set of containers. To run multiple environments:
- Use different directories.
- Or use different Docker Compose project names.
Q: Why is prod the default instead of dev?¶
A: Safety first. Production defaults force developers to explicitly opt into development mode, reducing the risk of:
- Accidentally running dev tools in production.
- Missing production-specific configurations.
- Security misconfigurations.
Management Commands¶
The dev loop wraps docker compose through make:
make service:start; start containers with the currentAPP_ENV.make service:stop; stop all containers.make service:status; show container status.make service:restart; restart all containers.make service:logs; view service logs.
Inline APP_ENV=... overrides any of those commands.
Related Documentation¶
- Developer Guide ; development workflows.
- Testing Guide ; testing guide.
- Admin Guide ; production operations.
- Configuration Reference ; environment variables reference.