Deployment Guide
ContextLoom Enterprise: Deployment Guide
Section titled “ContextLoom Enterprise: Deployment Guide”Version: 1.0.0 Target Audience: System Administrators / DevOps Engineers
This guide details the steps to deploy the ContextLoom Appliance in an on-premise or air-gapped environment.
Prerequisites
Section titled “Prerequisites”- Container Runtime: Docker Engine (v20.10+) or Podman (v4.0+).
- Database (BYODB): PostgreSQL 15+ accessible from the container host.
- Network: outbound access to your Git Providers (GitHub/GitLab/Bitbucket) and Identity Provider (Okta/Azure AD).
Step 1: Obtain the Configuration Files
Section titled “Step 1: Obtain the Configuration Files”The ContextLoom appliance is deployed using Docker Compose (or Podman Compose) and its configuration files.
- Download from GitHub: Obtain the
compose.ymland.env.templatefiles directly from the root of our public GitHub repository: https://github.com/kpruntov/context-loom - Place Files: Create a directory on your server (e.g.,
/opt/contextloom) and place bothcompose.ymland.env.templateinside it.
Step 2: Configure the Environment
Section titled “Step 2: Configure the Environment”Create a deployment directory and prepare your configuration.
- Create
.envfile: Copy the.env.templateto a new file named.envin the same directory. - Generate Secret Key: The appliance needs a unique, secure key for signing tokens. Generate one and add it to your
.envfile.Copy the output into theTerminal window # Generate a 32-byte (256-bit) hex keyopenssl rand -hex 32SECRET_KEYvariable in your.envfile. - Configure Database URL: Set the
DATABASE_URLin your.envfile to point to your existing PostgreSQL instance.
Example .env:
# --- SECURITY (Required) ---# Paste your generated key hereSECRET_KEY=e8f9a0d1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9
# --- DATABASE (Required) ---# Connection string to your PostgreSQL instance.# Ensure the user has CREATE privileges on the database.DATABASE_URL=postgresql+asyncpg://db_user:db_password@db.internal:5432/contextloom_db
# --- IDENTITY (Optional: SSO) ---# Required if you purchased the "Identity Shield" module.OIDC_CLIENT_ID=your-client-idOIDC_CLIENT_SECRET=your-client-secretOIDC_DISCOVERY_URL=https://company.okta.com/.well-known/openid-configurationStep 3: Configure Deployment (docker-compose.yml)
Section titled “Step 3: Configure Deployment (docker-compose.yml)”The standard deployment model for ContextLoom is Bring Your Own Database (BYODB). The compose.yml file is minimal, defining only the ContextLoom appliance itself.
The compose.yml you downloaded (from kpruntov/context-loom) is already configured to pull the latest image automatically.
Create a docker-compose.yml file:
version: '3.8'
services: contextloom: # Image will be automatically pulled from ghcr.io image: ghcr.io/kpruntov/contextloom:latest container_name: contextloom-appliance restart: always env_file: - .env # Port 8000 is internal only, accessed via the Proxy service. # ports: # - "8000:8000" volumes: # [Optional] Custom CA Bundle for Intranet Link # - ./certs/corporate-ca.crt:/app/certs/custom-ca.crt:ro extra_hosts: # [Optional] DNS resolution for internal services if needed # - "gitlab.internal:10.10.1.5"
proxy: image: docker.io/library/caddy:alpine restart: always ports: - "80:80" - "443:443" volumes: - ./Caddyfile:/etc/caddy/Caddyfile - caddy_data:/data - caddy_config:/config depends_on: - contextloom
volumes: caddy_data: caddy_config:Step 3.1: Configure HTTPS (Caddyfile)
Section titled “Step 3.1: Configure HTTPS (Caddyfile)”Create a file named Caddyfile in the same directory:
# Option 1: Automatic HTTPS (Public Domain)# loom.example.com {# reverse_proxy contextloom:8000# }
# Option 2: Internal/Self-Signed HTTPS (Default):443 { reverse_proxy contextloom:8000 tls internal}
# Option 3: HTTP (Port 80):80 { reverse_proxy contextloom:8000}Optional: Running a Local Database for Small Teams
Section titled “Optional: Running a Local Database for Small Teams”If you do not have an existing PostgreSQL database and want to run one alongside the appliance for evaluation or a small team, you can add a db service to your compose.yml.
1. Update compose.yml:
Add the db service definition to your compose.yml:
version: '3.8'
# ... volumes definition ...
services: contextloom: # ... depends_on: - db # ...
proxy: # ... Caddy definition ...
db: image: postgres:15-alpine restart: always environment: POSTGRES_DB: contextloom_db POSTGRES_USER: contextloom_user POSTGRES_PASSWORD: your-strong-password volumes: - db_data:/var/lib/postgresql/data ports: - "5432:5432"2. Update your .env file:
Ensure your DATABASE_URL matches the credentials used in the db service.
DATABASE_URL=postgresql+asyncpg://contextloom_user:your-strong-password@db:5432/contextloom_dbNote: The hostname db works because Docker Compose creates a network where services can reach each other by their service name.
Custom CA Configuration (Intranet Link): If your internal Git servers use self-signed certificates:
- Uncomment the
volumesline in thecontextloomservice to mount your CA file. - Add
SSL_CA_BUNDLE_PATH=/app/certs/custom-ca.crtto your.envfile.
Offline / Air-Gapped Installation
Section titled “Offline / Air-Gapped Installation”If your server does not have internet access to pull the images from GitHub Container Registry:
- Transfer Artifacts: Copy
contextloom-1.0.0.tar(provided in the release package) to the server. - Load Image:
Terminal window # Dockerdocker load -i contextloom-1.0.0.tar# Podmanpodman load -i contextloom-1.0.0.tar - Start: Run
docker compose up -d. The engine will use the locally loaded image.
Step 4: Start the Appliance
Section titled “Step 4: Start the Appliance”Launch the container.
docker compose up -dThe first time you run this, Docker (or Podman) Compose will automatically pull the ghcr.io/kpruntov/context-loom:latest image for you.
Check the logs to ensure it started correctly and connected to the database:
docker compose logs -fSuccess: You should see JSON logs indicating Application startup complete.
Step 5: Initialize Database (Run Migrations)
Section titled “Step 5: Initialize Database (Run Migrations)”The database starts empty. You must apply the schema migrations to create the necessary tables.
Run the following command:
docker compose exec contextloom python -m alembic upgrade headExpected Output:
You will see a list of migrations being applied (e.g., ... Running upgrade -> fbc9bcfa705f ...).
Step 6: Initialize the Superuser
Section titled “Step 6: Initialize the Superuser”The appliance comes with a locked-down “Distroless” runtime, so you cannot SSH into it. To create the initial Administrator account, you must run the ephemeral admin tool attached to the container’s network/environment.
Run the following command while the appliance is running:
docker compose exec contextloom python /app/admin_tools/create_superuser.pyExpected Output:
User admin@admin.com not found. Creating...Superuser admin@admin.com created successfully.Note: The default password is password. You must change this immediately upon login.
Step 7: Verification
Section titled “Step 7: Verification”- Navigate to
https://<your-server-ip>(orhttpif configured). - Log in with:
- Email:
admin@admin.com - Password:
password
- Email:
- Go to Settings > Users and change your password.
Troubleshooting
Section titled “Troubleshooting”Database Connection Failed:
- Ensure the
DATABASE_URLis correct. - Ensure the container host can reach the database port (Firewall/VPC Peering).
SSO Errors:
- Check the
OIDC_DISCOVERY_URLis reachable from inside the container. - Verify the
OIDC_REDIRECT_URLin your Identity Provider matcheshttps://<your-domain>/auth/oidc/callback.