Parallel Environments Setup - Portugal Odyssey Platform¶
⚠️ Historical doc. References
infrastructure/scripts/ci-deploy.shretired in Riff#50(2026-04-30). Current deploy doctrine: GitLab CI auto-deploys qual on push to main; prod is a manual CI job (Riff#10). Seedocs/reference/makefile.mdfor the current Makefile surface.
Purpose: Configure qualification and production environments to run in parallel on the same server, sharing the existing Traefik instance while maintaining security and isolation.
Date: 2025-01-03
Current Server State¶
Existing Services¶
- Traefik Instance (
/opt/traefik-standalone) - Container:
traefik - Network:
traefik(bridge) - Ports: 80, 443, 8080
-
Email: zmeireles@gmail.com
-
Existing Webapp (
/opt/experiencias100fim) - Services: web, strapi, db
- Network:
traefik(external) - Domains:
x100f.codecomedy.dev,cms.x100f.codecomedy.dev
Required Changes¶
- Network Configuration
- All environments must use the existing
traefiknetwork (notpo-traefik-public) - Each environment needs isolated internal networks
-
Production should use named external networks for shared infrastructure
-
Container Naming
- All containers must have unique names with environment suffix
-
Format:
po-<service>-<env>(e.g.,po-postgres-qual,po-postgres-prod) -
Volume Naming
- All volumes must be environment-specific
-
Format:
po-<service>-<env>(e.g.,po-postgres-data-qual) -
Traefik Router Names
- All router names must be unique across all environments
-
Format:
<service>-<env>(e.g.,public-fo-qual,public-fo-prod) -
Port Conflicts
- No services should expose ports directly (only Traefik)
- All services communicate internally via Docker networks
Configuration Changes Required¶
1. Update Production Compose File¶
File: infrastructure/compose/production.yml
Changes:
- Change po-traefik-public to use existing traefik network
- Ensure all networks are properly isolated
- Add environment suffix to all container names
- Add environment suffix to all volume names
- Ensure all Traefik router names are unique
2. Update Qualification Compose File¶
File: infrastructure/compose/qualification.yml
Changes:
- Change po-traefik-public to use existing traefik network
- Ensure all networks are properly isolated
- Verify all container names have -qual suffix
- Verify all volume names have -qual suffix
- Verify all Traefik router names have -qual suffix
3. Update Infrastructure Compose File¶
File: infrastructure/compose/infrastructure.yml
Changes:
- Remove Traefik service (using existing one)
- Update network references to use existing traefik network
- Ensure infrastructure services can be shared or isolated
4. Update Deployment Scripts¶
File: infrastructure/scripts/ci-deploy.sh
Changes: - Ensure script doesn't try to start Traefik - Verify network creation logic - Update health check endpoints
Network Architecture¶
┌─────────────────────────────────────────────────────────┐
│ Traefik (Shared) │
│ Network: traefik (bridge) │
│ Container: traefik │
└─────────────────────────────────────────────────────────┘
│
┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Existing │ │ PO Platform │ │ PO Platform │
│ Webapp │ │ Qual │ │ Prod │
│ │ │ │ │ │
│ Network: │ │ Network: │ │ Network: │
│ traefik │ │ traefik │ │ traefik │
│ │ │ + internal │ │ + internal │
└──────────────┘ └──────────────┘ └──────────────┘
Network Isolation Strategy¶
- Shared Network:
traefik(external, existing) - Used by: Traefik, all frontend services, all services with Traefik labels
-
Purpose: Allow Traefik to route to services
-
Qualification Internal Networks:
po-postgres-network-qual(bridge, isolated)po-redis-network-qual(bridge, isolated)po-rabbitmq-network-qual(bridge, isolated)po-elasticsearch-network-qual(bridge, isolated)-
po-internal-qual(bridge, isolated) -
Production Internal Networks:
po-postgres-network-prod(bridge, isolated)po-redis-network-prod(bridge, isolated)po-rabbitmq-network-prod(bridge, isolated)po-elasticsearch-network-prod(bridge, isolated)po-internal-prod(bridge, isolated)
Container Naming Convention¶
All containers must follow this pattern:
- Qualification:
po-<service>-qual - Production:
po-<service>-prod
Examples:
- po-postgres-qual, po-postgres-prod
- po-api-gateway-qual, po-api-gateway-prod
- po-strapi-cms-qual, po-strapi-cms-prod
Volume Naming Convention¶
All volumes must follow this pattern:
- Qualification:
po-<service>-<env>-qual - Production:
po-<service>-<env>-prod
Examples:
- po-postgres-data-qual, po-postgres-data-prod
- po-redis-data-qual, po-redis-data-prod
- po-strapi-uploads-qual, po-strapi-uploads-prod
Traefik Router Naming Convention¶
All Traefik router names must be unique:
- Qualification:
<service>-qual - Production:
<service>-prod
Examples:
- public-fo-qual, public-fo-prod
- api-gateway-qual, api-gateway-prod
- strapi-cms-qual, strapi-cms-prod
Domain Naming Convention¶
- Qualification:
*-qual.portugalodyssey.pt - Production:
*.portugalodyssey.pt(no suffix)
Examples:
- Qual: api-qual.portugalodyssey.pt, cms-qual.portugalodyssey.pt
- Prod: api.portugalodyssey.pt, cms.portugalodyssey.pt
Changes Required in Existing Services¶
Traefik Configuration¶
No changes required - The existing Traefik instance will automatically discover new services via Docker labels.
Existing Webapp¶
No changes required - The existing webapp will continue to work as-is since:
- It uses the same traefik network
- Router names are different (x100f-* vs po-*-qual/po-*-prod)
- Domains are different (*.codecomedy.dev vs *.portugalodyssey.pt)
Security Considerations¶
- Network Isolation: Each environment's internal services are isolated in separate networks
- Volume Isolation: Each environment has separate volumes
- Database Isolation: Separate databases per environment
- Traefik Routing: Traefik routes based on domain names, ensuring no cross-environment access
- Container Isolation: Containers cannot communicate across environments except via Traefik
Deployment Checklist¶
Before deploying:
- [ ] Verify existing Traefik network exists:
docker network ls | grep traefik - [ ] Verify no port conflicts (all services use internal networking)
- [ ] Verify all container names are unique
- [ ] Verify all volume names are unique
- [ ] Verify all Traefik router names are unique
- [ ] Verify DNS records point to correct domains
- [ ] Test qualification deployment first
- [ ] Test production deployment after qualification is stable
Testing Parallel Deployment¶
-
Start Qualification:
-
Verify Qualification:
-
Start Production (while qualification is running):
-
Verify Both Running:
-
Verify No Conflicts:
Troubleshooting¶
Issue: Container name already exists¶
Solution: Ensure all container names include environment suffix
Issue: Volume name conflict¶
Solution: Ensure all volume names include environment suffix
Issue: Traefik routing to wrong service¶
Solution: Verify router names are unique and domain names are correct
Issue: Services can't communicate¶
Solution: Verify services are on the same internal network
Issue: Port conflicts¶
Solution: Ensure no services expose ports directly (only Traefik should expose ports)
Last Updated: 2025-01-03