Deployment
What ships with the Wrapsfer API today for running it as a container, and what you need to think about before exposing it beyond local development. The repository includes a Dockerfile and a docker-compose.yml. There is no infrastructure-as-code, no platform-specific deploy manifest, and no CI/CD pipeline. This page describes only what exists.
For local non-Docker runs, see Getting Started. For configuration the runtime reads, see Configuration.
Container Port
The container exposes a single HTTP port: 8080. Verified in:
Dockerfile—EXPOSE 8080.docker-compose.yml—ASPNETCORE_URLS: http://+:8080and ports"8080:8080".
ASP.NET Core needs ASPNETCORE_URLS to bind on 8080 inside the container. The published image's entry point is dotnet Wrapsfer.Api.dll, so without ASPNETCORE_URLS the host would fall back to its default ports (typically 5000/5001) and the published port mapping would not match.
Run With Docker Compose
docker-compose.yml defines a single api service that builds from the local Dockerfile, runs in Development, and publishes on host port 8080:
services:
api:
build:
context: .
dockerfile: Dockerfile
environment:
ASPNETCORE_ENVIRONMENT: Development
ASPNETCORE_URLS: http://+:8080
ports:
- "8080:8080"
From the API repository root:
docker compose up --build # build the image and start the service
docker compose up -d --build # same, detached
docker compose logs -f api # follow logs
docker compose down # stop and remove the container
The Compose flow is intended for local execution. ASPNETCORE_ENVIRONMENT=Development is set, which means appsettings.Development.json is loaded and OpenAPI is mapped (see Production Considerations).
Smoke check the running container:
curl http://localhost:8080/health
curl "http://localhost:8080/api/greetings?name=Vernon"
Build And Run The Image Directly
The Dockerfile is a standard multi-stage build (mcr.microsoft.com/dotnet/sdk:10.0 for build, mcr.microsoft.com/dotnet/aspnet:10.0 for the runtime image). Verified contents:
WORKDIR /app,EXPOSE 8080.- Restores
src/Wrapsfer.Api/Wrapsfer.Api.csproj(which transitively pulls in Application, Infrastructure, and Domain). - Publishes
-c Release -o /app/publish --no-restore. - Final image entry point:
ENTRYPOINT ["dotnet", "Wrapsfer.Api.dll"].
Build the image:
docker build -t wrapsfer-api .
Run it:
docker run --rm -p 8080:8080 -e ASPNETCORE_URLS=http://+:8080 wrapsfer-api
Run with a non-Development environment (OpenAPI will not be mapped):
docker run --rm \
-p 8080:8080 \
-e ASPNETCORE_URLS=http://+:8080 \
-e ASPNETCORE_ENVIRONMENT=Production \
wrapsfer-api
Override configuration values the same way you would locally — environment variables use double-underscore syntax for nested keys (see Configuration → Environment Variable Reference):
docker run --rm \
-p 8080:8080 \
-e ASPNETCORE_URLS=http://+:8080 \
-e ASPNETCORE_ENVIRONMENT=Production \
-e Cors__AllowedOrigins__0=https://app.example.com \
-e AllowedHosts=api.example.com \
wrapsfer-api
Production Considerations
The boilerplate is not production-ready as shipped. The following items need explicit attention before any deployment outside local development. Each one is a known gap, not a recommendation that is already implemented.
CORS
Cors:AllowedOrigins is [] in appsettings.json. The DefaultCors policy in Program.cs falls back to AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod() when the list is empty. Set Cors:AllowedOrigins to the explicit origin list before exposing the service. See Configuration → CORS Security Note.
Environment Configuration
ASPNETCORE_ENVIRONMENT=Developmentis set bydocker-compose.yml. For non-local runs, set this toStagingorProductionsoappsettings.Development.jsonis not loaded and OpenAPI is not mapped.- Override anything sensitive (connection strings, secrets) through environment variables rather than committing them to
appsettings.*. There is no secrets store wired in today (noUserSecretsId, no Azure Key Vault provider). AllowedHostsis"*"inappsettings.json. Restrict it to the hostnames you actually serve.
OpenAPI Exposure
MapOpenApi() is gated behind app.Environment.IsDevelopment() in Program.cs, so /openapi/v1.json is automatically not exposed when the environment is set to anything other than Development. Do not move this call outside the IsDevelopment() branch without first deciding how the document should be protected (auth, network restrictions, static artifact instead of live endpoint). See OpenAPI → Production Exposure.
Authentication
There is no authentication scheme today. Every endpoint is publicly callable. app.UseAuthorization() is wired but no policies or [Authorize] attributes exist. Do not deploy publicly without first adding authentication and authorization. See Development Workflow → Adding Authentication Later.
TLS
app.UseHttpsRedirection() is in the pipeline, but the container only exposes HTTP on 8080. Production deployments should terminate TLS upstream (load balancer, ingress, reverse proxy) and forward to the container on 8080. If TLS termination happens at the container, supply HTTPS bindings via ASPNETCORE_URLS and the appropriate certificate configuration.
Observability
The repository ships:
- ASP.NET Core's default logging (Console, Debug, EventSource on Linux/macOS).
ExceptionHandlingMiddlewarewriting exceptions toILogger<ExceptionHandlingMiddleware>.
It does not ship:
- Structured logging (Serilog, NLog, or similar).
- Metrics (OpenTelemetry, Prometheus, App Insights).
- Distributed tracing.
- A health-check UI or readiness/liveness split (
/healthis a single aggregate endpoint with no custom checks registered).
Pick observability infrastructure separately and wire it before relying on the service in production.
Persistence And State
The API has no database, no persistent storage, and no in-memory state that needs to survive restarts. Containers can be restarted or replaced freely today. When persistence is added (see Development Workflow → Adding Persistence Later), revisit this section.
Deployment Platform
The Dockerfile and docker-compose.yml make no assumptions about a specific cloud or orchestrator. The image is a standard ASP.NET Core 10 container image and can be run anywhere a container can run — Kubernetes, ECS, Cloud Run, Azure Container Apps, a single VM with Docker, etc. Pick a target deliberately and supply the platform-specific manifests separately; nothing in this repo is tailored to one.
See Also
- Getting Started — local non-Docker runs and Docker Compose smoke tests.
- Configuration — keys, environment variables, CORS, host filtering.
- OpenAPI — Development-only gating of
/openapi/v1.json. - Development Workflow — future-work guidance for persistence and authentication.