Skip to content
This repository was archived by the owner on Oct 10, 2025. It is now read-only.

Commit 0f8c151

Browse files
committed
docs: [#28] finalize configuration architecture standardization plan
- Document comprehensive per-environment configuration architecture - Create ADR-008 for per-environment application configuration storage - Establish enhanced deployment workflow with validation gates - Define per-environment storage structure in application/config/{environment}/ - Add environment-configuration matching validation system - Remove alternative simplified approach documentation - Set foundation for Phase 1 implementation (infrastructure scope reduction) Addresses architectural inconsistency blocking staging deployment in Issue #28
1 parent cd0e5e5 commit 0f8c151

File tree

4 files changed

+728
-8
lines changed

4 files changed

+728
-8
lines changed

application/config/templates/.gitkeep

Lines changed: 0 additions & 3 deletions
This file was deleted.

application/storage/compose/.gitignore

Lines changed: 0 additions & 5 deletions
This file was deleted.
Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
# ADR-008: Per-Environment Application Configuration Storage
2+
3+
## Status
4+
5+
Proposed
6+
7+
## Date
8+
9+
2025-08-06
10+
11+
## Context
12+
13+
During the configuration architecture standardization for Issue #28 (Hetzner infrastructure
14+
implementation), we needed to decide how to store and manage application configuration files
15+
that are generated from templates.
16+
17+
### Previous Approach
18+
19+
The original approach considered using a single shared storage location (`application/storage/`)
20+
for all application configurations with runtime environment detection to prevent mismatches.
21+
22+
This approach had several limitations:
23+
24+
1. **No Configuration Tracking**: Generated configurations weren't stored per environment
25+
2. **No Customization Support**: Users couldn't customize configuration per environment
26+
3. **No Backup Capability**: Configuration couldn't be version-controlled or backed up
27+
4. **Complex Mismatch Prevention**: Required runtime validation and metadata files
28+
5. **Limited Testing**: Couldn't easily test environment-specific configurations locally
29+
30+
### Configuration Management Requirements
31+
32+
The system needs to support:
33+
34+
- **Multiple Environments**: Local testing, staging, production deployments
35+
- **Configuration Customization**: Users should be able to modify configs per environment
36+
- **Version Control**: Configuration changes should be trackable
37+
- **Local Testing**: Ability to test environment configurations without VM deployment
38+
- **Backup and Restore**: Easy backup of environment-specific configurations
39+
- **Clear Audit Trail**: Visibility into configuration changes per environment
40+
41+
## Decision
42+
43+
We will store application configurations in **per-environment folders** under
44+
`application/config/{environment}/` where `{environment}` matches the environment file name
45+
from `infrastructure/config/environments/`.
46+
47+
### Directory Structure
48+
49+
```text
50+
application/config/
51+
├── e2e-libvirt/ # Local testing environment
52+
│ ├── tracker/etc/tracker.toml
53+
│ ├── proxy/etc/nginx.conf
54+
│ ├── prometheus/etc/prometheus.yml
55+
│ ├── compose/.env
56+
│ └── .environment # Environment metadata
57+
├── staging-hetzner/ # Staging environment
58+
│ ├── tracker/etc/tracker.toml
59+
│ ├── proxy/etc/nginx.conf
60+
│ ├── prometheus/etc/prometheus.yml
61+
│ ├── compose/.env
62+
│ └── .environment # Environment metadata
63+
└── production-hetzner/ # Production environment
64+
├── tracker/etc/tracker.toml
65+
├── proxy/etc/nginx.conf
66+
├── prometheus/etc/prometheus.yml
67+
├── compose/.env
68+
└── .environment # Environment metadata
69+
```
70+
71+
### Environment Naming Convention
72+
73+
Environment folder names **must match** the environment file names in
74+
`infrastructure/config/environments/`:
75+
76+
- `e2e-libvirt``infrastructure/config/environments/e2e-libvirt.env`
77+
- `staging-hetzner``infrastructure/config/environments/staging-hetzner.env`
78+
- `production-hetzner``infrastructure/config/environments/production-hetzner.env`
79+
80+
## Rationale
81+
82+
### Benefits of Per-Environment Storage
83+
84+
1. **Configuration Customization**:
85+
86+
- Users can manually modify configurations per environment
87+
- Changes persist across regeneration cycles
88+
- Environment-specific tuning and optimization
89+
90+
2. **Version Control and Backup**:
91+
92+
- Each environment's configuration can be committed to git
93+
- Easy to track configuration changes over time
94+
- Backup and restore capabilities per environment
95+
96+
3. **Local Testing Support**:
97+
98+
- Users can copy environment configs to `application/storage/` for local testing
99+
- Test production configurations without VM overhead
100+
- Debug configuration issues before deployment
101+
102+
4. **Clear Environment Separation**:
103+
104+
- No risk of configuration pollution between environments
105+
- Visual separation of environment concerns
106+
- Easy to compare configurations across environments
107+
108+
5. **Simplified Deployment**:
109+
110+
- No runtime environment detection needed
111+
- Clear mapping between environment file and configuration folder
112+
- Reduced complexity in deployment scripts
113+
114+
6. **Audit Trail**:
115+
- Clear visibility into what configuration each environment uses
116+
- Easy to see configuration differences between environments
117+
- Trackable configuration evolution per environment
118+
119+
### Environment Validation
120+
121+
The deployment process validates environment-configuration matching:
122+
123+
```bash
124+
# Generate configuration for specific environment
125+
make app-config ENVIRONMENT_FILE=staging-hetzner
126+
127+
# Deploy using that environment's configuration
128+
make app-deploy ENVIRONMENT_FILE=staging-hetzner
129+
```
130+
131+
The system validates that:
132+
133+
1. Configuration folder `application/config/staging-hetzner/` exists
134+
2. Environment metadata matches the deployment target
135+
3. All required configuration files are present and valid
136+
137+
### Local Testing Workflow
138+
139+
Users can test environment-specific configurations locally:
140+
141+
```bash
142+
# Generate staging configuration
143+
make app-config ENVIRONMENT_FILE=staging-hetzner
144+
145+
# Copy to storage for local testing
146+
cp -r application/config/staging-hetzner/* application/storage/
147+
148+
# Test locally
149+
cd application
150+
docker compose up -d
151+
```
152+
153+
## Consequences
154+
155+
### Positive
156+
157+
- **Environment Isolation**: Clear separation between environment configurations
158+
- **Customization Support**: Users can modify configurations per environment
159+
- **Version Control**: Configuration changes are trackable and revertible
160+
- **Local Testing**: Easy to test environment configurations without deployment
161+
- **Backup Capability**: Environment configurations can be backed up and restored
162+
- **Simplified Deployment**: Clear environment-to-configuration mapping
163+
- **Better Debugging**: Easy to inspect and compare environment configurations
164+
165+
### Negative
166+
167+
- **Disk Usage**: Multiple copies of similar configurations consume more disk space
168+
- **Synchronization**: Need to regenerate configurations when templates change
169+
- **Directory Management**: More complex directory structure to maintain
170+
171+
### Neutral
172+
173+
- **Git Repository Size**: Configuration files may increase repository size
174+
- **Learning Curve**: Users need to understand per-environment configuration model
175+
176+
## Implementation
177+
178+
### Configuration Generation
179+
180+
The `make app-config` command generates configurations for the specified environment:
181+
182+
```bash
183+
# Generate application configuration for staging
184+
make app-config ENVIRONMENT_FILE=staging-hetzner
185+
186+
# Result: application/config/staging-hetzner/ contains all configs
187+
```
188+
189+
### Deployment Integration
190+
191+
The `make app-deploy` command uses the environment-specific configuration:
192+
193+
```bash
194+
# Deploy using pre-generated staging configuration
195+
make app-deploy ENVIRONMENT_FILE=staging-hetzner
196+
197+
# Copies from: application/config/staging-hetzner/
198+
# To VM location: /var/lib/torrust/
199+
```
200+
201+
### Environment Metadata
202+
203+
Each configuration includes metadata for validation:
204+
205+
```bash
206+
# application/config/staging-hetzner/.environment
207+
ENVIRONMENT_FILE=staging-hetzner
208+
GENERATED_AT=2025-08-06T10:30:00Z
209+
SOURCE_TEMPLATES_HASH=abc123def456
210+
```
211+
212+
### Error Handling
213+
214+
If environment mismatch is detected during deployment:
215+
216+
```text
217+
ERROR: Configuration not found for environment 'staging-hetzner'
218+
219+
Please generate configuration first:
220+
make app-config ENVIRONMENT_FILE=staging-hetzner
221+
222+
Or check environment file exists:
223+
infrastructure/config/environments/staging-hetzner.env
224+
```
225+
226+
## Alternatives Considered
227+
228+
### Single Shared Storage
229+
230+
Store all configurations in `application/storage/` with runtime environment validation.
231+
232+
**Rejected because:**
233+
234+
- No configuration tracking per environment
235+
- No customization support
236+
- Complex runtime validation required
237+
- No backup capability
238+
239+
### Environment Detection in Storage
240+
241+
Use single storage with environment metadata files for mismatch detection.
242+
243+
**Rejected because:**
244+
245+
- Still doesn't support per-environment customization
246+
- Adds complexity without solving core issues
247+
- No clear environment separation
248+
249+
### Template-Only Approach
250+
251+
Generate configurations at deployment time from templates.
252+
253+
**Rejected because:**
254+
255+
- No ability to customize configurations
256+
- No pre-deployment validation
257+
- Longer deployment times
258+
- No local testing capability
259+
260+
## Related Decisions
261+
262+
- [ADR-004: Configuration Approach Files vs Environment Variables](./004-configuration-approach-files-vs-environment-variables.md)
263+
- [ADR-007: Two-Level Environment Variable Structure](./007-two-level-environment-variable-structure.md)
264+
- [Configuration Architecture Standardization](../refactoring/configuration-architecture-standardization.md)
265+
266+
## References
267+
268+
- [Issue #28: Phase 4 Hetzner Infrastructure Implementation](../issues/28-phase-4-hetzner-infrastructure-implementation.md)
269+
- [Twelve-Factor App Configuration](https://12factor.net/config)
270+
- [Configuration Architecture Standardization Plan](../refactoring/configuration-architecture-standardization.md)
271+
272+
## Revision History
273+
274+
- **2025-08-06**: Initial decision document created
275+
- **Decision maker**: Development team based on staging deployment requirements
276+
- **Reviewed by**: Architecture review (pending)

0 commit comments

Comments
 (0)