Skip to main content

Quickstart

Spin up Terragnos Core in less than 20 minutes with a single-host Docker Compose stack. This walkthrough assumes you want to evaluate the product or prepare a proof-of-concept before wiring it into your day-to-day workflows. For deeper operational guidance (Kubernetes, HA, zero-downtime upgrades) continue to the Deployment section.

Prerequisites

  • Docker Engine 24+ with the docker compose plugin (or Docker Desktop on macOS/Windows).
  • 8 GB RAM, 4 vCPUs, and at least 10 GB free disk space (the PostGIS data directory can grow quickly during experimentation).
  • A terminal with access to curl for quick verification steps.

Tip: Podman users can adapt the same commands with podman compose, but the sample snippets below use the Docker CLI.

1. Get the Docker Compose configuration

Download or create a docker-compose.yml file for Terragnos Core. The configuration file defines the container images and services needed to run the platform.

2. Configure environment variables

Create a .env file next to docker-compose.yml. This keeps secrets and runtime settings outside of the Compose definition. The values below are safe defaults for local evaluation:

# Database
POSTGRES_DB=terragnos
POSTGRES_USER=terragnos
POSTGRES_PASSWORD=terragnos
DATABASE_URL=postgres://terragnos:terragnos@db:5432/terragnos

# Authentication
AUTH_JWT_SECRET=dev-secret-change-me
AUTH_DEFAULT_TENANT=default
AUTH_DISABLED=false

# Licensing (provided by Terragnos)
# The vendor-delivered package contains LICENSE_PUBLIC_KEY and LICENSE_KEY values.
LICENSE_PUBLIC_KEY=-----BEGIN PUBLIC KEY-----...-----END PUBLIC KEY-----
LICENSE_KEY=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
LICENSE_STORAGE_SECRET=

# Optional services
REDIS_URL=
RATE_LIMIT_TTL=60
RATE_LIMIT_LIMIT=120

Terragnos delivers the LICENSE_PUBLIC_KEY and LICENSE_KEY strings with your enterprise agreement. Customers never generate keys themselves; license keys are issued by Terragnos.

Keep AUTH_DISABLED=false so you exercise the full JWT flow; you can temporarily set it to true if you just need to confirm connectivity.

3. Boot the database

You have two options for the database:

Start the PostGIS container and wait for the health check to pass:

docker compose up -d db
docker compose logs -f db

Once you see database system is ready to accept connections, press Ctrl+C to stop tailing logs (the container keeps running).

Option B: Use your own PostgreSQL + PostGIS database

If you prefer to use your own existing PostgreSQL + PostGIS instance:

  1. Ensure your database has the required extensions:

    CREATE EXTENSION IF NOT EXISTS postgis;
    CREATE EXTENSION IF NOT EXISTS pgcrypto;
    CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
    CREATE EXTENSION IF NOT EXISTS pg_trgm;
  2. Update your .env file to point to your database:

    DATABASE_URL=postgres://your_user:your_password@your_host:5432/your_database
  3. Skip the docker compose up -d db step and proceed directly to running migrations (step 4).

Note: The terragnos-core-db image is provided for convenience, but Terragnos Core works with any PostgreSQL 15+ instance that has PostGIS 3.4+ installed. This allows you to integrate with existing database infrastructure, managed database services, or high-availability setups.

4. Run migrations and seed data

The db-setup profile builds a lightweight Node.js image that runs the migration and seed scripts. Trigger it once per environment (you can rerun without side effects if something fails):

docker compose --profile setup up --build db-setup

The command exits automatically after inserting initial schemas, demo object types, and sample data. Tear it down:

docker compose --profile setup down

5. Launch API and worker

Start the two runtime containers in detached mode:

docker compose up -d api worker

Tail logs if you want to observe boot messages:

docker compose logs -f api worker

Both services are ready when the API reports Nest application successfully started and the worker indicates Ready - listening for automation events.

6. Verify the stack

  1. Health endpoints

    curl http://localhost:3000/v1/health/live
    curl http://localhost:3000/v1/health/ready

    Both should respond with HTTP 200.

  2. Authenticate

    • Generate a development JWT using the helper script:

      pnpm generate:dev:token

      Copy the token from the output (or craft your own with the desired claims).

    • Store it in the console UI via Settings → Configure JWT token, or use it directly with curl:

      curl -H "Authorization: Bearer <token>" http://localhost:3000/v1/object-types
  3. List objects and workflows

    curl -H "Authorization: Bearer <token>" http://localhost:3000/v1/objects?limit=5
    curl -H "Authorization: Bearer <token>" http://localhost:3000/v1/workflows

    You should see the seeded data returned in JSON.

  4. Try your first workflow transition

    # Get an object ID from the previous step
    OBJECT_ID="<object-id-from-list>"

    # Explain available transitions
    curl -H "Authorization: Bearer <token>" \
    http://localhost:3000/v1/objects/$OBJECT_ID/workflow/explain-transitions

    # Trigger a transition (if available)
    curl -X POST \
    -H "Authorization: Bearer <token>" \
    -H "Content-Type: application/json" \
    -d '{"targetState": "review"}' \
    http://localhost:3000/v1/objects/$OBJECT_ID/workflow/transitions
  5. Visit the Admin Console (optional)

    If the Admin Console is included in your deployment, access it at the configured URL and sign in with the same token to confirm the UI can read/write data.

7. Tear down

Shut down the containers while keeping the database volume for future runs:

docker compose down

If you also want to remove the PostGIS data volume:

docker compose down --volumes

Troubleshooting

SymptomLikely causeFix
db container never becomes healthyPort conflict or slow diskCheck docker compose logs db; ensure nothing else uses port 5432, increase resources, or delete/recreate the terragnos-db-data volume.
api fails with ECONNREFUSEDAPI started before DB was readyRestart with docker compose up -d api; the health-based depends_on should prevent this once the DB is healthy.
401 Unauthorized on every requestMissing/bad JWTRun pnpm generate:dev:token, set it in the console settings, or export it as AUTH_TOKEN and pass via Authorization header.
Stale data after schema editsMigrations not rerunRebuild and rerun docker compose --profile setup up --build db-setup.

Where to go next