Building from Source¶
This page covers building JIM from source, managing database migrations, and working with Docker Compose.
Prerequisites¶
- .NET 10.0 SDK: Download
- Docker and Docker Compose: Required for the database and containerised services
Both are pre-installed in the devcontainer environment. See Development Environment for setup.
Building the Solution¶
Full Solution Build¶
Or use the shell alias:
Targeted Builds¶
During development, prefer building only the affected projects and their dependants. This is significantly faster than a full solution build.
# Build a specific test project (transitively builds its dependencies)
dotnet build test/JIM.Worker.Tests/
# Build the web project
dotnet build src/JIM.Web/
Tip
Use targeted builds during development and reserve dotnet build JIM.sln for the final pre-PR check.
Docker Builds¶
Build All Services¶
Build Individual Services¶
Use shell aliases to rebuild and restart specific services after code changes:
jim-build-web # Rebuild and restart jim.web
jim-build-worker # Rebuild and restart jim.worker
jim-build-scheduler # Rebuild and restart jim.scheduler
jim-build # Rebuild and restart all services
Container rebuilds required
When running the Docker stack, compiled code changes (Blazor pages, API controllers, worker processors) require a container rebuild. Simply refreshing the browser will not show changes.
Database Migrations¶
JIM uses Entity Framework Core migrations for schema management.
Adding a Migration¶
Applying Migrations¶
Locally:
In Docker:
Never squash or delete migrations
JIM is deployed in production environments. EF Core tracks applied migrations by name in the __EFMigrationsHistory table. Removing existing migrations and replacing them with a combined migration will cause failures on every deployed instance. Migrations are append-only; once committed to main, they are permanent.
Docker Compose File Layering¶
JIM uses a layered Docker Compose configuration:
| File | Purpose | Tracked |
|---|---|---|
docker-compose.yml |
Production/deployment defaults | Yes |
docker-compose.override.yml |
Development settings (ports, environment, conservative DB) | Yes |
docker-compose.local.yml |
Machine-specific DB tuning (auto-generated) | No (gitignored) |
The jim-* shell aliases automatically include the local overlay when present. Later files override earlier ones.
PostgreSQL Tuning¶
Development (Automatic)¶
In devcontainers (Codespaces and local), PostgreSQL is automatically tuned during setup. The script .devcontainer/postgres-tune.sh detects available CPU and RAM and generates gitignored overlay files with optimal OLTP settings.
To re-tune after changing devcontainer resources:
Production (Manual)¶
The default PostgreSQL settings in docker-compose.yml are tuned for a 64GB / 16-core system. For other environments, use PGTune to generate settings, then override command and shm_size in a compose override file.
Key settings to adjust:
shared_buffers: typically ~25% of available host RAMeffective_cache_size: typically ~75% of available host RAMshm_size(Docker): must be >=shared_bufferswith ~25% headroom
Sizing reference:
| Host RAM | shared_buffers |
shm_size |
|---|---|---|
| 8 GB | 2 GB | 3 GB |
| 16 GB | 4 GB | 5 GB |
| 32 GB | 8 GB | 10 GB |
| 64 GB | 16 GB | 20 GB |
| 128 GB | 32 GB | 40 GB |
Warning
If shm_size is smaller than shared_buffers, PostgreSQL will crash under load. Docker defaults shm_size to only 64 MB, which is insufficient for any non-trivial shared_buffers value.