Skip to main content
Self-host the open-source Blnk Core in infrastructure your team controls. You are responsible for deployment, upgrades, configuration, and day-to-day operations across each environment you maintain—dev, staging, production, and beyond.

Deployment guide

There are two ways to self-host Blnk Core in your environment: via Docker or Kubernetes.
Before you start, make sure you have the following set up (required):
  1. Managed PostgreSQL instance
  2. Managed Redis instance
  3. Docker or k8s installed
  4. Linux server (Ubuntu 20.04 LTS or newer recommended)
1

Set up your configuration file

This is the configuration file that will be used to start the Blnk Core, it can be the blnk.json file or environment variables.For more options, go to Blnk Configuration.
{
  "project_name": "Blnk",
  "data_source": {
    "dns": "postgres://<user>:<password>@<host>:5432/blnk?sslmode=require"
  },
  "redis": {
    "dns": "redis://:<password>@<host>:6379"
  },
  "server": {
    "port": "5001"
  },
  "queue": {
    "monitoring_port": "5004"
  }
}
2

Create a 'docker-compose.yml' file

Add the following configuration to provision the server, worker, and supporting services if needed. You can use the default docker-compose.yml file in the Blnk repository.
For live deployments, we recommend connecting your managed Postgres and Redis databases. This means you can exclude the redis and postgres services from your docker-compose.yaml file.
docker-compose.yaml
version: "3.8"

services:
  server:
    image: ${BLNK_IMAGE:-jerryenebeli/blnk:0.14.5}
    container_name: server
    restart: on-failure
    entrypoint: ["/bin/sh", "-c"]
    command:
      - "blnk migrate up && blnk start"
    environment:
      TZ: ${TZ:-Etc/UTC}
    ports:
      - "5001:5001"
      - "80:80"
      - "443:443"
    volumes:
      - ./blnk.json:/blnk.json

  worker:
    image: ${BLNK_IMAGE:-jerryenebeli/blnk:0.14.5}
    container_name: worker
    restart: on-failure
    entrypoint: ["blnk", "workers"]
    ports:
      - "5004:5004"
    volumes:
      - ./blnk.json:/blnk.json
For PaaS deployments like Railway, Render, etc., you’ll need to deploy each service separately, with their respective start commands.
3

Start deployment

Run these commands in your terminal to start and validate your deployment:
# Start all services
docker compose up -d

# Verify deployment status
docker ps

# Monitor service logs
docker logs -f server worker
Blnk should be running and accessible at port 5001 and available for requests.

Back-office management

Once your Blnk Core is deployed in your own environment, you can connect it to a Blnk Cloud account to operate your ledger from a back-office dashboard. Transactions table

Connect Core to Blnk Cloud

Self-hosted Core connected to Cloud.

Monitoring

Use Blnk Cloud for monitoring

Setting up monitoring

We recommend connecting to Blnk Cloud to set up monitoring for your Core in less than 5 minutes. See Quick setup: Blnk Cloud. To manually export logs, traces, and metrics for your local deployment:
1

Enable observability in Core

Set "enable_observability": true in blnk.json, then restart server and worker after you finish the compose changes below.
2

Add Prometheus config

Create prometheus.yml beside your compose file:
prometheus.yml
global:
  scrape_interval: 15s

scrape_configs:
  - job_name: 'blnk-server'
    authorization:
      type: Bearer
      credentials: '<metrics-bearer-token>'
    static_configs:
      - targets: ['server:5001']
  - job_name: 'blnk-worker'
    authorization:
      type: Bearer
      credentials: '<metrics-bearer-token>'
    static_configs:
      - targets: ['worker:5004']
3

Add Jaeger and Prometheus services

Update your docker-compose.yaml to include Jaeger and Prometheus. This example extends the base compose with trace export on server and worker:
docker-compose.yaml
version: "3.8"

services:
  server:
    image: ${BLNK_IMAGE:-jerryenebeli/blnk:0.14.5}
    container_name: server
    restart: on-failure
    entrypoint: ["/bin/sh", "-c"]
    command:
      - "blnk migrate up && blnk start"
    environment:
      TZ: ${TZ:-Etc/UTC}
      OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: http://jaeger:4318/v1/traces
    ports:
      - "5001:5001"
      - "80:80"
      - "443:443"
    depends_on:
      - jaeger
    volumes:
      - ./blnk.json:/blnk.json

  worker:
    image: ${BLNK_IMAGE:-jerryenebeli/blnk:0.14.5}
    container_name: worker
    restart: on-failure
    entrypoint: ["blnk", "workers"]
    environment:
      OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: http://jaeger:4318/v1/traces
    ports:
      - "5004:5004"
    depends_on:
      - jaeger
    volumes:
      - ./blnk.json:/blnk.json

  jaeger:
    image: jaegertracing/all-in-one:latest
    container_name: jaeger
    ports:
      - "16686:16686"
      - "4318:4318"
    environment:
      - COLLECTOR_OTLP_ENABLED=true
    healthcheck:
      test: ["CMD", "wget", "--spider", "http://localhost:16686"]
      interval: 10s
      timeout: 5s
      retries: 3

  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    profiles:
      - monitoring
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
    depends_on:
      - server
      - worker
4

Start or restart the stack

Run docker compose --profile monitoring up -d to start Core, Jaeger, and Prometheus together.Open Jaeger at http://localhost:16686 and Prometheus at http://localhost:9090 to confirm data is flowing.To learn more, see Monitoring in Blnk.

Troubleshooting

Use this guide to troubleshoot your deployment when Blnk fails to start or you experience errors in your deployment.
Common symptoms: Connection refused or timeout errors in server logs; messages referencing data_source or BLNK_DATA_SOURCE_DNS.
1

Verify your connection string

Confirm BLNK_DATA_SOURCE_DNS (or data_source.dns in blnk.json) includes the correct host, port, database name, user, and password.Set sslmode to match your provider; most managed Postgres instances require sslmode=require.
Many hosted Postgres providers expose two URLs: a direct connection and a pooled connection.If Blnk keeps timing out or disconnecting under load, confirm you are using the direct connection string for BLNK_DATA_SOURCE_DNS.
See Database settings.
2

Check network access

Allow inbound traffic from your Blnk host to PostgreSQL. Review security groups, firewall rules, and private networking (VPC peering, subnet routing) between the container host and your database.
If Postgres is only reachable on a private network, running psql from your laptop may succeed or fail independently of the container. Test from the same network context as the Blnk server.
3

Test the connection

From a host on the same network as Blnk, run:
psql "$BLNK_DATA_SOURCE_DNS" -c "SELECT 1"
A successful response confirms credentials and reachability.
Common symptoms: The server container exits immediately; logs show errors from blnk migrate up.The Docker Compose example runs migrations before starting the API (blnk migrate up && blnk start). Migration failures prevent the server from listening on port 5001.
1

Confirm database permissions

The database user must be able to create and alter tables in the target database. Read-only or restricted roles cause migration failures.
Grant the application user CREATE and ALTER privileges on the blnk database (or your chosen database name).
2

Inspect migration logs

Read the server container output:
docker logs server
Look for the first migration error—later messages often repeat the same root cause.
3

Run migrations manually

Re-run migrations in the foreground to capture the full error:
docker compose run --rm server blnk migrate up
Common symptoms: The API accepts requests but transactions remain QUEUED; the worker container restarts or logs Redis connection errors.Workers depend on Redis for queueing and coordination. The server and worker must share the same Redis and queue configuration.
1

Verify Redis connectivity

Confirm BLNK_REDIS_DNS (or redis.dns in blnk.json) points at your managed Redis instance. Include the password in the URL when required:
redis://:<password>@<host>:6379
For TLS-enabled Redis, use rediss:// and review Redis configuration.
2

Confirm the worker is running

Both server and worker services must be up:
docker ps
docker logs -f worker
On Kubernetes, check worker pod status and logs alongside the server deployment.
3

Check queue health

If you configured BLNK_QUEUE_MONITORING_PORT (default 5004), open the monitoring dashboard or probe the endpoint:
curl -s http://localhost:5004/monitoring
See Queue monitoring for dashboard details and metrics.
Common symptoms: docker ps shows a restarting server or worker container; requests to port 5001 time out.
1

Review container status

List all containers, including stopped ones:
docker ps -a
docker logs -f server worker
Restart loops usually point to configuration, migration, or dependency errors in the logs.
2

Confirm port exposure

Verify port 5001 is published in docker-compose.yaml and allowed through your host firewall and cloud security groups.
curl http://localhost:5001/health (or your health endpoint) should respond when the server is healthy.
3

Validate configuration is loaded

When using blnk.json, confirm the file is mounted into both server and worker containers. When using environment variables, set them on both services—mismatched config between server and worker causes subtle queue issues.See Blnk configuration.
For PaaS deployments (Railway, Render, Fly.io), run the server and worker as separate services with identical configuration and the correct start commands for each.