⌘K

Core API Self-Hosting

Deploy nativeblocks-core-api on your own infrastructure using Docker.

This guide covers deploying nativeblocks-core-api on your own infrastructure.


Prerequisites

RequirementVersionNotes
Docker24+Recommended deployment method
PostgreSQL15+Primary database
Valkey / Redis7+Cache and event queue
S3-compatible storageAWS S3, DigitalOcean Spaces, MinIO, etc.
License keyObtain from nativeblocks.io

Database migrations run automatically at startup. No manual migration step is required.


Environment Variables

VariableRequiredDescription
PORTNoHTTP port (default: 8080)
POSTGRES_CONNECTION_URLYesPostgreSQL DSN, e.g. postgresql://user:pass@host:5432/dbname?sslmode=require
VALKEY_CONNECTION_URLYesValkey/Redis URL, e.g. redis://host:6379 or rediss://host:6380
S3_ACCESS_KEY_IDYesS3-compatible access key
S3_SECRET_ACCESS_KEYYesS3-compatible secret key
S3_ENDPOINTYesS3 endpoint URL, e.g. https://s3.amazonaws.com or https://fra1.digitaloceanspaces.com
LICENSE_KEYYesNativeblocks license key
ADMIN_ENDPOINTYesNativeblocks admin API — use https://admin.api.nativeblocks.io unless instructed otherwise
CORE_ENDPOINTYesPublicly reachable URL of this service, e.g. https://api.yourcompany.com
GATEWAYYesSDK delivery format: GRAPHQL
LOG_LEVELNoLog verbosity for stdout: verbose (default), warning, error
LOG_PROVIDERSNoComma-separated providers: stdout (default), sentry
SENTRY_DSNNoSentry DSN — required when sentry is in LOG_PROVIDERS. Sentry only receives error-level logs regardless of LOG_LEVEL

Logger Configuration

VariableValuesDefaultNotes
LOG_LEVELverbose · warning · errorverboseApplies to stdout only
LOG_PROVIDERScomma-separated: stdout, sentrystdout
SENTRY_DSNSentry DSN URLSentry always receives error-level logs only; LOG_LEVEL does not affect it

Examples:

# stdout only (development)
LOG_LEVEL=verbose
LOG_PROVIDERS=stdout

# stdout (verbose) + Sentry (production)
# Note: Sentry only captures errors regardless of LOG_LEVEL
LOG_LEVEL=verbose
LOG_PROVIDERS=stdout,sentry
SENTRY_DSN=https://..[email protected]/123

Docker Deployment

Pull and run

docker pull nativeblocks/core-api:latest

docker run -d \
  --name nativeblocks-core-api \
  --restart unless-stopped \
  -p 8080:8080 \
  -e PORT=8080 \
  -e POSTGRES_CONNECTION_URL="postgresql://user:pass@your-db-host:5432/nativeblocks?sslmode=require" \
  -e VALKEY_CONNECTION_URL="redis://your-valkey-host:6379" \
  -e S3_ACCESS_KEY_ID="<your-access-key>" \
  -e S3_SECRET_ACCESS_KEY="<your-secret-key>" \
  -e S3_ENDPOINT="https://s3.amazonaws.com" \
  -e GATEWAY=GRAPHQL \
  -e ADMIN_ENDPOINT=https://admin.api.nativeblocks.io \
  -e CORE_ENDPOINT=https://api.yourcompany.com \
  -e LICENSE_KEY="<your-license-key>" \
  -e LOG_LEVEL=error \
  -e LOG_PROVIDERS=stdout,sentry \
  -e SENTRY_DSN="<your-sentry-dsn>" \
  nativeblocks/core-api:latest

Docker Compose Deployment

Create a docker-compose.yml for a full self-contained stack:

version: "3.9"

volumes:
  postgres_data:
  valkey_data:

services:
  postgres:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_DB: nativeblocks
      POSTGRES_USER: nativeblocks
      POSTGRES_PASSWORD: <strong-password>
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U nativeblocks" ]
      interval: 10s
      timeout: 5s
      retries: 5

  valkey:
    image: valkey/valkey:8
    restart: unless-stopped
    volumes:
      - valkey_data:/data
    healthcheck:
      test: [ "CMD", "valkey-cli", "ping" ]
      interval: 10s
      timeout: 5s
      retries: 5

  core-api:
    image: nativeblocks/core-api:latest
    restart: unless-stopped
    ports:
      - "8080:8080"
    depends_on:
      postgres:
        condition: service_healthy
      valkey:
        condition: service_healthy
    environment:
      PORT: "8080"
      POSTGRES_CONNECTION_URL: "postgresql://nativeblocks:<strong-password>@postgres:5432/nativeblocks?sslmode=disable"
      VALKEY_CONNECTION_URL: "redis://valkey:6379"
      S3_ACCESS_KEY_ID: "<your-access-key>"
      S3_SECRET_ACCESS_KEY: "<your-secret-key>"
      S3_ENDPOINT: "https://s3.amazonaws.com"
      GATEWAY: "GRAPHQL"
      ADMIN_ENDPOINT: "https://admin.api.nativeblocks.io"
      CORE_ENDPOINT: "https://api.yourcompany.com"
      LICENSE_KEY: "<your-license-key>"
      LOG_LEVEL: "error"
      LOG_PROVIDERS: "stdout,sentry"
      SENTRY_DSN: "<your-sentry-dsn>"
docker compose up -d

Endpoints

PathPurpose
/graphqlMain GraphQL API
/graphql/playgroundInteractive GraphQL explorer
/gateway/initSDK gateway initialization
/metricsPrometheus metrics

Reverse Proxy (Nginx)

server {
    listen 443 ssl;
    server_name api.yourcompany.com;

    ssl_certificate     /etc/ssl/certs/yourcompany.crt;
    ssl_certificate_key /etc/ssl/private/yourcompany.key;

    client_max_body_size 20M;

    location / {
        proxy_pass         http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header   Upgrade $http_upgrade;
        proxy_set_header   Connection "upgrade";
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Proto $scheme;
        proxy_read_timeout 60s;
        proxy_send_timeout 60s;
    }
}

server {
    listen 80;
    server_name api.yourcompany.com;
    return 301 https://$host$request_uri;
}

Database Migrations

Migrations run automatically when the server starts. No manual intervention is needed. If you need to verify migration state, the server logs the current and target version at startup:

Current DB Version: 12, Latest Version: 12
No migrations needed.

License Validation

The service connects to ADMIN_ENDPOINT to validate the license on startup and periodically while running. If validation fails, the process exits. Ensure:

  • ADMIN_ENDPOINT is reachable from the container
  • LICENSE_KEY is valid and not expired
  • Outbound HTTPS traffic is allowed from the host

You can use https://admin.api.nativeblocks.io for the env variable.


Monitoring

Prometheus metrics are exposed at /metrics. Scrape config example:

scrape_configs:
  - job_name: nativeblocks-core-api
    static_configs:
      - targets: [ "api.yourcompany.com:8080" ]
    metrics_path: /metrics

Upgrading

# Pull the new image
docker pull nativeblocks/core-api:<new-version>

# Restart the container (migrations run automatically)
docker compose up -d --no-deps core-api

Migrations are applied forward-only. Always back up PostgreSQL before upgrading to a new major version.


Minimum Resource Recommendations

ComponentCPUMemory
core-api2 vCPU2 GB