Defines the mental model and configuration contract for Development, LocalDevelopment, Test, and Production environments. Use to correctly configure environment-specific settings, understand DNS and configuration resolution, and avoid breaking environment parity during development, testing, and deployment.
This skill defines how environments are conceptualized and configured, not just how they are named.
An environment is not just an ASPNETCORE_ENVIRONMENT value.
An environment is the combination of:
Correctly understanding this contract is mandatory to avoid configuration drift and “works on my machine” failures.
| Environment | API Location | Dependencies | Config Source | Purpose |
|---|---|---|---|---|
| Development | Local process | localhost | appsettings.Development.json |
| Debugging with minimal setup |
| LocalDevelopment | Docker | Docker DNS | appsettings.LocalDevelopment.json | Full-stack, production-like E2E |
| Test | In-memory | Testcontainers | Code | Isolated, reproducible tests |
| Production | AWS (Lambda/ECS) | AWS networking | AWS Parameter Store | Live system |
The application code must not change between environments.
Only the following are allowed to vary:
localhost vs Docker DNS vs AWS endpoints)If behavior changes beyond that, the environment boundary is broken.
Run the API locally as a process with a debugger attached, while dependencies run in Docker.
This is the lowest-friction environment and the fastest feedback loop.
localhostASPNETCORE_ENVIRONMENT: Development
{
"Database": {
"ConnectionStrings": {
"XXTemplateXXPostgreSql": "Host=localhost;Port=5432;..."
}
},
"Cognito": {
"Domain": "http://localhost:8080",
"RedirectUri": "http://localhost:5000/auth/oauth/callback"
},
"Localstack": {
"ServiceUrl": "http://localhost:4566/"
}
}
Start dependencies only:
pnpm docker:up
Run API locally:
dotnet run
Run frontend:
pnpm dev
Run the entire stack inside Docker to surface issues related to networking, DNS, and container boundaries.
This is the first environment that behaves like production.
localhost internallyASPNETCORE_ENVIRONMENT: LocalDevelopment
{
"Database": {
"ConnectionStrings": {
"XXTemplateXXPostgreSql": "Host=postgre-database;Port=5432;..."
}
},
"Cognito": {
"Domain": "http://wiremock:8080",
"RedirectUri": "http://xxtemplatexx-api:80/auth/oauth/callback"
},
"Localstack": {
"ServiceUrl": "http://localstack:4566/"
}
}
| Service | Internal Name | External Port |
|---|---|---|
| API | xxtemplatexx-api | 81 |
| Frontend | xxtemplatexx-web | 80 |
| PostgreSQL | postgre-database | 5432 |
| LocalStack | localstack | 4566 |
| WireMock | wiremock | 8080 |
pnpm docker:up
Execute isolated, reproducible integration tests without relying on shared infrastructure.
appsettings.*.json files are usedpublic class ApiServicesFactory
: WebApplicationFactory<IMinimalApiMarker>, IAsyncLifetime
{
private readonly PostgreSqlContainer _postgresContainer;
private readonly LocalStackContainer _localStackContainer;
private readonly WireMockContainer _wireMockContainer;
public async Task InitializeAsync()
{
await _postgresContainer.StartAsync();
await _localStackContainer.StartAsync();
await _wireMockContainer.StartAsync();
}
}
Run with:
dotnet test
Run the system in AWS using real managed services with secure configuration.
builder.Host.ConfigureParameterStore<IMinimalApiMarker>();
WireMock is a shared dependency across environments, not a test-only tool.
Used in:
Same mappings. Same behavior. Same OAuth contract.
Location:
scripts/development/wiremock/
├── mappings/
└── __files/
This guarantees parity between local debugging, Docker E2E, and tests.
appsettings.json
├── appsettings.Development.json
├── appsettings.LocalDevelopment.json
├── appsettings.Production.json
└── AWS Parameter Store (Production only)
Priority (highest wins):
appsettings.{Environment}.jsonappsettings.json| Aspect | Development | LocalDevelopment | Test | Production |
|---|---|---|---|---|
| API runs in | Local process | Docker | In-memory | AWS |
| DNS | localhost | Docker DNS | Container ports | AWS |
| Database | Docker | Docker | Testcontainer | RDS |
| Mocks | WireMock | WireMock | WireMock | None |
| Config source | JSON | JSON | Code | Parameter Store |
If an issue appears in LocalDevelopment or Test but not in Development, the code was relying on an invalid assumption.
That is the point of having multiple environments.