logo
Docker Compose
Docker Compose

Docker Compose

Deploy Colanode quickly on your local machine or server using Docker Compose. This method is perfect for development, testing, small teams, or when you want to get started quickly without complex infrastructure.

Quick Start

1. Get the Docker Compose Configuration

# Option 1: Download directly
curl -o docker-compose.yaml https://raw.githubusercontent.com/colanode/colanode/main/hosting/docker/docker-compose.yaml

# Option 2: Clone the repository
git clone https://github.com/colanode/colanode.git
cd colanode/hosting/docker

2. Start the Services

# Start all services
docker compose up -d

# View logs
docker compose logs -f

# Check service status
docker compose ps

That’s it! The server runs with sensible defaults out of the box, using file system storage.

Custom Configuration

The server works without any configuration file. When you need to customize settings (branding, storage backend, email, etc.), create a config.json and mount it into the container.

Creating a Custom Config

# Download the example config as a starting point
curl -o config.json https://raw.githubusercontent.com/colanode/colanode/main/apps/server/config.example.json

Edit this file to set your values. Secrets should stay in environment variables and be referenced from JSON using the env://SECRET_NAME syntax.

Mounting the Config

Uncomment the config mount line in docker-compose.yaml and set the CONFIG environment variable:

services:
  server:
    environment:
      CONFIG: /config.json
    volumes:
      - ./config.json:/config.json:ro

Then restart the server:

docker compose up -d

Storage Configuration

The default Docker Compose setup uses file system storage. MinIO is available as an optional service for S3-compatible object storage. Storage is configured under storage.provider in your config.json.

Using the Default File System Storage

No configuration needed. The server uses file system storage by default with the server_storage volume mounted at /var/lib/colanode/storage.

Using MinIO S3 Storage

To enable MinIO, start the services with the S3 profile:

# Start with MinIO enabled
docker compose --profile s3 up -d

Create or update config.json:

{
  "storage": {
    "provider": {
      "type": "s3",
      "endpoint": "http://minio:9000",
      "bucket": "colanode",
      "region": "us-east-1",
      "forcePathStyle": true,
      "accessKey": "env://S3_ACCESS_KEY",
      "secretKey": "env://S3_SECRET_KEY"
    }
  }
}

Set the secrets in the server.environment block:

services:
  server:
    environment:
      S3_ACCESS_KEY: minioadmin
      S3_SECRET_KEY: your_minio_password

Using External S3 Storage

Update config.json to point to your provider (AWS S3, Cloudflare R2, Backblaze B2, etc.):

{
  "storage": {
    "provider": {
      "type": "s3",
      "endpoint": "https://s3.amazonaws.com",
      "bucket": "my-colanode-bucket",
      "region": "us-west-2",
      "forcePathStyle": false,
      "accessKey": "env://S3_ACCESS_KEY",
      "secretKey": "env://S3_SECRET_KEY"
    }
  }
}

Set S3_ACCESS_KEY and S3_SECRET_KEY in the compose env block. The MinIO service is optional and won’t start unless you use the --profile s3 flag.

Using Google Cloud Storage

Mount your GCP service account key and update config.json:

{
  "storage": {
    "provider": {
      "type": "gcs",
      "bucket": "my-colanode-bucket",
      "projectId": "my-project-123",
      "credentials": "file:///secrets/gcp-key.json"
    }
  }
}

Mount the key file in docker-compose.yaml:

services:
  server:
    volumes:
      - ./gcp-service-account.json:/secrets/gcp-key.json:ro

Using Azure Blob Storage

Configure Azure storage in config.json:

{
  "storage": {
    "provider": {
      "type": "azure",
      "account": "mystorageaccount",
      "containerName": "colanode",
      "accountKey": "env://AZURE_STORAGE_ACCOUNT_KEY"
    }
  }
}

Set AZURE_STORAGE_ACCOUNT_KEY as an environment variable in the compose file.

Access Colanode

Once all services are running:

Service Components

Colanode Server

  • Image: ghcr.io/colanode/server:latest
  • Port: 3000
  • Purpose: Main server handling client requests
  • Dependencies: PostgreSQL, Redis/Valkey, (MinIO optional)

Colanode Web App

  • Image: ghcr.io/colanode/web:latest
  • Port: 4000 (mapped to 80 internally)
  • Purpose: Web client interface
  • Access: Main entry point for users

Postgres with pgvector

  • Image: pgvector/pgvector:pg17
  • Port: 5432
  • Purpose: Primary database with vector search capabilities
  • Storage: Persistent volume postgres_data

Valkey Redis

  • Image: valkey/valkey:8.1
  • Port: 6379
  • Purpose: Message queuing and caching
  • Storage: Persistent volume valkey_data

MinIO S3 Storage (Optional)

  • Image: minio/minio:RELEASE.2025-04-08T15-41-24Z
  • Ports: 9000 (API), 9001 (Console)
  • Purpose: S3-compatible file storage
  • Storage: Persistent volume minio_data
  • Profile: Only starts with --profile s3 flag

Configuration & Secrets

The server works with defaults, but you can customize any setting via config.json.

  1. Edit config.json for non-sensitive values. Update branding, storage provider, SMTP host, etc. directly in the file.

  2. Reference secrets via env://SECRET_NAME. Example:

    {
      "email": {
        "enabled": true,
        "from": {
          "email": "noreply@example.com",
          "name": "Colanode"
        },
        "provider": {
          "type": "smtp",
          "host": "smtp.example.com",
          "port": 587,
          "auth": {
            "user": "env://SMTP_USER",
            "password": "env://SMTP_PASSWORD"
          }
        }
      }
    }
  3. Provide those env vars in docker-compose.yaml. The server already declares the required ones (POSTGRES_URL, REDIS_URL). Add any additional secrets you referenced in the JSON.

Environment variables do not override JSON values unless explicitly referenced. See the configuration reference for the full schema.

Ports Configuration

Change exposed ports by modifying the ports section:

services:
  server:
    ports:
      - "8080:3000" # Change server port to 8080
  web:
    ports:
      - "8081:80" # Change web port to 8081

Volume Persistence

Data is stored in Docker volumes:

# List volumes
docker volume ls

# Backup a volume
docker run --rm -v colanode_postgres_data:/data -v $(pwd):/backup alpine tar czf /backup/postgres-backup.tar.gz -C /data .

# View volume details
docker volume inspect colanode_postgres_data

Using a Reverse Proxy

For production deployments, use a reverse proxy like Nginx or Traefik:

# docker-compose.prod.yaml
version: "3.8"
services:
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/ssl/certs
    depends_on:
      - web
      - server
    networks:
      - colanode_network

  web:
    networks:
      - colanode_network

  server:
    environment:
      SERVER_PATH_PREFIX: "api"
    networks:
      - colanode_network

networks:
  colanode_network:
    external: false

Important: When exposing Colanode behind a path such as /api, the web client needs the server to report the same prefix. Set SERVER_PATH_PREFIX on the server container and make sure your reverse proxy forwards /api/* without stripping it. If the prefix is missing, the client falls back to the root path and the server will appear unavailable.

Example Nginx configuration:

# nginx.conf
events {}

http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }

    upstream colanode_web {
        server web:80;
    }

    upstream colanode_server {
        server server:3000;
    }

    server {
        listen 80;
        listen 443 ssl;
        server_name colanode.yourcompany.com;

        ssl_certificate /etc/ssl/certs/cert.pem;
        ssl_certificate_key /etc/ssl/certs/key.pem;

        location / {
            proxy_pass http://colanode_web;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }

        location /api/ {
            proxy_pass http://colanode_server;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $connection_upgrade;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

Starting and Stopping

# Start services
docker compose up -d

# Stop services
docker compose down

# Restart a specific service
docker compose restart server

# Pull latest images
docker compose pull

Monitoring and Logs

# View all logs
docker compose logs -f

# View specific service logs
docker compose logs -f server
docker compose logs -f postgres

# Monitor resource usage
docker stats

# Check service health
docker compose ps

Database Management

# Access PostgreSQL directly
docker compose exec postgres psql -U colanode_user -d colanode_db

# Create database backup
docker compose exec postgres pg_dump -U colanode_user colanode_db > backup.sql

# Restore from backup
docker compose exec -T postgres psql -U colanode_user colanode_db < backup.sql

Troubleshooting

Services Not Starting
# Check logs for errors
docker compose logs

# Verify all images are pulled
docker compose pull

# Check available disk space
df -h

# Check port conflicts
netstat -tlnp | grep :3000

Database Connection Issues

# Check PostgreSQL logs
docker compose logs postgres

# Verify database is ready
docker compose exec postgres pg_isready -U colanode_user

# Test connection manually
docker compose exec postgres psql -U colanode_user -d colanode_db -c "SELECT version();"

File Storage Issues

# Check MinIO logs
docker compose logs minio

# Access MinIO console
# Visit http://localhost:9001
# Login: minioadmin / your_minio_password

# Verify buckets exist
docker compose exec minio mc ls local/

Upgrading

# Pull latest images
docker compose pull

# Restart with new images
docker compose up -d

# Check logs for any migration messages
docker compose logs server

Version-Specific Updates

# Use specific version
# Edit docker-compose.yaml
server:
  image: ghcr.io/colanode/server:v0.3.0

web:
  image: ghcr.io/colanode/web:v0.3.0