Development Environment¶
JIM provides a fully configured development environment through GitHub Codespaces and VS Code devcontainers. All dependencies (.NET 10.0 SDK, Docker, PostgreSQL, VS Code extensions, and shell aliases) are pre-installed and ready to use.
GitHub Codespaces¶
The fastest way to get started. Everything is pre-configured in the cloud; no local setup required:
- Open the JIM repository on GitHub
- Click Code > Codespaces > Create codespace on main
- Wait for provisioning (automatic setup via
.devcontainer/setup.sh) - Start developing; all tools and aliases are available immediately
The setup script automatically creates a .env file with development defaults. SSO is pre-configured for the bundled Keycloak instance; sign in with admin / admin.
Codespace machine type
The devcontainer configuration requests 8 cores, 32 GB RAM, and 120 GB storage via hostRequirements. GitHub Codespaces selects the closest matching preset, typically 8 cores and 32 GB RAM, but only 64 GB storage (the 120 GB request is not available as a Codespace preset). Verify the machine type in the selector before creating. This is sufficient for day-to-day development, but integration tests with larger template sizes are resource-intensive and may perform better in a local devcontainer where Docker has direct access to host resources without virtualisation overhead.
Custom Environment Variables in Codespaces¶
To restore your own .env file automatically in Codespaces, set a DOTENV_BASE64 secret in your GitHub Codespaces settings. The setup script will decode and apply it during provisioning.
Local Devcontainer¶
Recommended for integration testing and large-scale development work where you need more control over resource allocation:
- Clone the repository:
git clone https://github.com/TetronIO/JIM.git - Open the folder in VS Code
- Install the Dev Containers extension
- When prompted, click Reopen in Container (or use the command palette:
Dev Containers: Reopen in Container) - Wait for the container to build and configure
The devcontainer provides the same environment as Codespaces; all dependencies, extensions, and shell aliases are configured automatically.
Allocating resources
Integration tests with large template sizes (10,000+ objects) are memory and CPU intensive. Allocate as much as your host machine can spare: 24–32 GB RAM, 4 GB+ swap, and as many cores as possible. PostgreSQL tuning is applied automatically during setup and can be re-run with jim-postgres-tune after changing resource allocations.
Since host machine performance varies between developers, integration test timings and throughput figures are only directly comparable when run on the same configuration.
Bundled Keycloak¶
JIM ships a bundled Keycloak instance for development SSO, removing the need for an external identity provider during development.
| Setting | Value |
|---|---|
| Admin console URL | http://localhost:8181 |
| Admin credentials | admin / admin |
| Pre-configured realm | jim |
| Pre-configured test users | admin / admin, user / user |
Keycloak management aliases:
jim-keycloak
Start Keycloak only (for local debugging workflow)jim-keycloak-stop
Stop Keycloakjim-keycloak-logs
View Keycloak logs
Front-channel and back-channel URLs¶
The bundled Keycloak is configured so that the browser and JIM.Web each see the right endpoint URLs for their network path, without JIM.Web having to rewrite URLs itself. This makes sign-in and sign-out work identically whether you run JIM.Web natively (jim-build-light) or inside the full Docker stack (jim-build).
Three environment variables in docker-compose.override.yml make this work:
| Variable | Value | Purpose |
|---|---|---|
KC_HOSTNAME |
http://localhost:8181 |
The public, browser-facing URL. Advertised in the discovery document, iss claim, redirects, and the end_session_endpoint. |
KC_HOSTNAME_STRICT |
false |
Accept requests whose Host header doesn't match KC_HOSTNAME, so back-channel calls from inside the Docker network are not rejected. |
KC_HOSTNAME_BACKCHANNEL_DYNAMIC |
true |
Derive back-channel endpoint URLs (token, userinfo, JWKS) from each request's Host header, so JIM.Web in the Docker network receives jim.keycloak:8080 endpoints while the browser receives localhost:8181 endpoints. |
Do not change these without reading the comment block
The three KC_HOSTNAME* variables work as a set. Removing or changing any of them in isolation will break sign-in or sign-out (or both) in at least one of the three supported dev scenarios: Codespaces, devcontainer native debugging (jim-build-light), and devcontainer Docker stack (jim-build). See the inline comment in docker-compose.override.yml for the full rationale.
Shell Aliases¶
Aliases are automatically configured from .devcontainer/jim-aliases.sh. If aliases are not available, run source ~/.zshrc or restart the terminal.
Build and Test¶
| Alias | Description |
|---|---|
jim |
List all available jim aliases |
jim-compile |
Build entire solution (dotnet build JIM.sln) |
jim-test |
Run unit and workflow tests (excludes Explicit) |
jim-test-all |
Run all tests including Explicit and Pester |
Database¶
| Alias | Description |
|---|---|
jim-db |
Start PostgreSQL (for local debugging) |
jim-db-stop |
Stop PostgreSQL |
jim-migrate |
Apply EF Core migrations |
jim-postgres-tune |
Re-tune PostgreSQL for current CPU/RAM |
Docker Stack¶
| Alias | Description |
|---|---|
jim-stack |
Start the full Docker stack |
jim-stack-logs |
View Docker stack logs |
jim-stack-down |
Stop the Docker stack |
jim-restart |
Restart stack (re-reads .env, no rebuild) |
Docker Builds¶
Rebuild and restart services after code changes:
| Alias | Description |
|---|---|
jim-build |
Build all services and start |
jim-build-light |
Start db + Keycloak, run JIM.Web natively |
jim-build-web |
Build jim.web and start |
jim-build-worker |
Build jim.worker and start |
jim-build-scheduler |
Build jim.scheduler and start |
Other¶
| Alias | Description |
|---|---|
jim-reset |
Reset JIM (delete database and log volumes) |
jim-diagrams |
Export Structurizr C4 diagrams as SVG |
jim-prd |
Create a new PRD from template |
Development Workflows¶
Choose one of two workflows depending on your task:
Workflow 1: Local Debugging (Recommended)¶
Best for active development with breakpoints and hot reload.
- Run
jim-build-light(starts db + Keycloak, waits for readiness, launches JIM.Web natively) - Press F5 in VS Code to launch with the debugger, or access JIM at
https://localhost:7000, API reference at/api/reference
Workflow 2: Full Docker Stack¶
Best for integration testing or a production-like environment.
- Start all services:
jim-stack - Access JIM at
http://localhost:5200, API reference at/api/reference
Rebuilding after code changes
When running the Docker stack, compiled code changes require a container rebuild. Use jim-build-web, jim-build-worker, or jim-build-scheduler to rebuild affected services. Simply refreshing the browser is not sufficient.
Development URLs¶
| URL | Description |
|---|---|
http://localhost:5200 |
JIM Web UI (Docker stack) |
http://localhost:5200/api/reference |
Scalar API reference (development only) |
http://localhost:8181 |
Keycloak admin console (admin / admin) |
https://localhost:7000 |
JIM Web UI (local debugging) |
http://localhost:8000 |
MkDocs documentation preview |
Documentation Preview¶
The devcontainer includes MkDocs Material for previewing the documentation site locally. To start the preview server:
This runs mkdocs serve bound to 0.0.0.0:8000 and opens a live-reloading preview. Changes to files in docs/ or mkdocs.yml are reflected immediately in the browser.
To build the static site without serving:
Git Configuration¶
VS Code automatically copies your host machine's ~/.gitconfig into devcontainers (controlled by the dev.containers.copyGitConfig setting, enabled by default). Configure Git on your host machine and it will be available in all devcontainers automatically.
Required Setup (Host Machine)¶
Optional: SSH Commit Signing¶
git config --global gpg.format ssh
git config --global commit.gpgsign true
git config --global user.signingkey "key::ssh-ed25519 AAAA... your-comment"
Tip
Use the key:: prefix for user.signingkey so the key is stored as a literal string rather than a file path. File paths from the host will not exist inside the container.
VS Code automatically forwards the SSH agent into the container, so SSH authentication for git push and git pull works without copying keys. VS Code also injects a credential helper that forwards HTTPS credential requests back to the host.