Skip to main content

02. Installation

Sure provides a great installation page on their website as can be found over here. However, I would like to drop the docker compose file straight away. Also note that I like to keep all the volumes inside the same folder instead of all in docker volumes. Hence, this has been changed compared to the original docker compose file. We will deploy this again nicely in Dockhand with compose and .env file that can be found below

compose.yml
x-db-env: &db_env
  POSTGRES_USER: ${POSTGRES_USER:-sure_user}
  POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-sure_password}
  POSTGRES_DB: ${POSTGRES_DB:-sure_production}

x-rails-env: &rails_env
  <<: *db_env
  SECRET_KEY_BASE: ${SECRET_KEY_BASE:-a7523c3d0ae56415046ad8abae168d71074a79534a7062258f8d1d51ac2f76d3c3bc86d86b6b0b307df30d9a6a90a2066a3fa9e67c5e6f374dbd7dd4e0778e13}
  SELF_HOSTED: "true"
  RAILS_FORCE_SSL: "false"
  RAILS_ASSUME_SSL: "false"
  DB_HOST: db
  DB_PORT: 5432
  REDIS_URL: redis://redis:6379/1
  # NOTE: enabling OpenAI will incur costs when you use AI-related features in the app (chat, rules).  Make sure you have set appropriate spend limits on your account before adding this.
#  OPENAI_ACCESS_TOKEN: ${OPENAI_ACCESS_TOKEN}

services:
  web:
    image: ghcr.io/we-promise/sure:stable
    volumes:
      - ./app-storage:/rails/storage
    ports:
      - ${PORT:-3000}:3000
      # To also publish on IPv6 (dual-stack), uncomment the line below AND
      # set BINDING=:: in the environment block. See docs/hosting/docker.md
      # "Binding to IPv6" for details.
      # - "[::]:${PORT:-3000}:3000"
    restart: unless-stopped
    environment:
      <<: *rails_env
      # BINDING: "::"  # Uncomment for IPv6 dual-stack inside the container
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    dns:
      - 8.8.8.8
      - 1.1.1.1
    networks:
      - sure_net

  worker:
    image: ghcr.io/we-promise/sure:stable
    command: bundle exec sidekiq
    volumes:
      - ./app-storage:/rails/storage
    restart: unless-stopped
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_healthy
    dns:
      - 8.8.8.8
      - 1.1.1.1
    environment:
      <<: *rails_env
    networks:
      - sure_net

  db:
    image: postgres:16
    restart: unless-stopped
    volumes:
      - ./postgres-data:/var/lib/postgresql/data
    environment:
      <<: *db_env
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready -U $$POSTGRES_USER -d $$POSTGRES_DB" ]
      interval: 5s
      timeout: 5s
      retries: 5
    networks:
      - sure_net

  backup:
    profiles:
      - backup
    image: prodrigestivill/postgres-backup-local
    restart: unless-stopped
    volumes:
      - ./backups:/backups # Change this path to your desired backup location on the host machine
    environment:
      - POSTGRES_HOST=db
      - POSTGRES_DB=${POSTGRES_DB:-sure_production}
      - POSTGRES_USER=${POSTGRES_USER:-sure_user}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-sure_password} # pipelock:ignore
      - SCHEDULE=@daily # Runs once a day at midnight
      - BACKUP_KEEP_DAYS=7 # Keeps the last 7 days of backups
      - BACKUP_KEEP_WEEKS=4 # Keeps 4 weekly backups
      - BACKUP_KEEP_MONTHS=6 # Keeps 6 monthly backups
    depends_on:
      - db
    networks:
      - sure_net

  redis:
    image: redis:latest
    restart: unless-stopped
    volumes:
      - ./redis-data:/data
    healthcheck:
      test: [ "CMD", "redis-cli", "ping" ]
      interval: 5s
      timeout: 5s
      retries: 5
    networks:
      - sure_net

networks:
  sure_net:
    driver: bridge

Then finally you can set your environment variables in the .env filefile, which basically are the email credentials

.env
POSTGRES_USER=usernamedifficult
POSTGRES_PASSWORD=0394jgoipjeroigjoisdjgkljyourcode
POSTGRES_DB=sure_production
SECRET_KEY_BASE=a7523c3d0ae56415046ad8abae168d71074a79534a7062258f8d1d51ac2f76d3c3bc86d86b6b0b307df30d9a6a90a2066a3fa9e67c5e6f374dbd7dd4e0778e13
PORT=3000
SMTP_ADDRESS=smtp.example.com
SMTP_PORT=587
SMTP_DOMAIN=example.com
SMTP_USERNAME=your-username
SMTP_PASSWORD=your-password
SMTP_AUTHENTICATION=plain
SMTP_ENABLE_STARTTLS_AUTO=true

Note! Make sure that sure has the right writing permissions of 700750 for the sure"sure" folder you are hosting everything in. Otherwise it cannot create a directory for your account.

Documentation Index

Fetch the complete documentation index at: https://docs.sure.am/llms.txt Use this file to discover all available pages before exploring further.

Self-hosting with Docker

Deploy Sure on your own infrastructure using Docker Compose

This guide shows you how to set up, update, and maintain a self-hosted Sure application with Docker Compose.

Prerequisites

    Docker Engine installed and running Basic familiarity with the command line

    Installation

    Install Docker

      Follow the official Docker installation guide Start the Docker service on your machine Verify the installation:
      docker run hello-world
      

      If Docker is set up correctly, this command will succeed.

      Create your application directory

      Create a directory where your app will run:

      mkdir -p ~/docker-apps/sure
      cd ~/docker-apps/sure
      

      Download the Docker Compose file

      Download the sample compose file from the Sure repository:

      curl -o compose.yml https://raw.githubusercontent.com/we-promise/sure/main/compose.example.yml
      

      This creates a compose.yml file in your current directory with the default configuration.

      Configuration

      By default, the compose.example.yml file runs without any configuration. For production deployments or if you're running outside of a local network, follow these steps to add security.

      Email configuration

      To enable email notifications and password resets, configure SMTP settings in your .env file:

      SMTP_ADDRESS=smtp.example.com
      SMTP_PORT=587
      SMTP_DOMAIN=example.com
      SMTP_USERNAME=your-username
      SMTP_PASSWORD=your-password
      SMTP_AUTHENTICATION=plain
      SMTP_ENABLE_STARTTLS_AUTO=true

      SSL/TLS options

      For SMTP servers with custom SSL certificates or self-signed certificates:

      Skip TLS verification (not recommended for production):

      SMTP_OPENSSL_VERIFY_MODE=none
      

      Use custom CA certificate:

      SSL_CA_FILE=/path/to/ca-certificate.pem
      

      The SSL_CA_FILE option allows you to specify a custom CA certificate file for SSL verification when connecting to SMTP servers with self-signed or internal certificates.

      Create an environment file

      Create a .env file where Docker will read environment variables:

      touch .env
      

      Generate a secret key

      Generate a secret key using one of these methods:

      With OpenSSL:

      openssl rand -hex 64
      

      Without OpenSSL:

      head -c 64 /dev/urandom | od -An -tx1 | tr -d ' \n' && echo
      

      Save the generated key for the next step.

      Configure environment variables

      Open the .env file in your text editor and add:

      SECRET_KEY_BASE="your-generated-secret-key-here"
      POSTGRES_PASSWORD="your-database-password-here"
      

      Replace the placeholder values with your generated secret key and a secure database password.

      Market data provider variables

      Sure supports multiple securities pricing providers. You can configure them through environment variables or in the UI under Settings > Self-Hosting. See market data providers for details on each provider.

      # Comma-separated list of securities providers (e.g. yahoo_finance,tiingo,mfapi)
      SECURITIES_PROVIDERS="yahoo_finance"
      
      # Exchange rate provider (default: twelve_data)
      EXCHANGE_RATE_PROVIDER="twelve_data"
      
      # API keys (only needed for providers that require them)
      TWELVE_DATA_API_KEY="your-key-here"
      TIINGO_API_KEY="your-key-here"
      EODHD_API_KEY="your-key-here"
      ALPHA_VANTAGE_API_KEY="your-key-here"
      

      Setting `SECURITIES_PROVIDERS` as an environment variable takes precedence over the UI setting. Leave it unset to manage providers from the UI only.

      Running the application

      Start the application

      Start the app to verify everything is working:

      docker compose up
      

      This pulls the official Docker image and starts the app. You'll see logs in your terminal.

      Open your browser and navigate to http://localhost:3000. You should see the Sure login screen.

      Create your account

      On first run, register a new account:

      1. Click "Create your account" on the login page
      2. Enter your email
      3. Enter a password

      Run in the background

      To run Sure in the background:

      1. Stop the current process with Ctrl+C
      2. Start in detached mode:
      docker compose up -d
      

      Verify it's running:

      docker compose ls
      

      Your app is now accessible at http://localhost:3000.

      Updating

      The Docker image in your compose.yml file controls which version of Sure you're running:

      image: ghcr.io/we-promise/sure:latest
      
      • ghcr.io/we-promise/sure:latest - Latest alpha release
      • ghcr.io/we-promise/sure:stable - Latest stable release

      You can also pin to a specific version from the packages page.

      Update to the latest version

      Your app does not automatically update. To update:

      cd ~/docker-apps/sure
      docker compose pull
      docker compose build
      docker compose up --no-deps -d web worker
      

      Change update channel

      To switch between update channels, edit the compose.yml file:

      image: ghcr.io/we-promise/sure:stable
      

      Then restart the app:

      docker compose pull
      docker compose build
      docker compose up --no-deps -d web worker
      

      Backup service

      The Docker Compose configuration includes an optional backup service that automatically backs up your PostgreSQL database.

      Enabling backups

      The backup service uses Docker Compose profiles and is disabled by default. To enable it:

      docker compose --profile backup up -d
      

      Configure backup settings

      The backup service uses the following default settings:

      • Schedule: Daily at midnight
      • Retention: 7 daily backups, 4 weekly backups, 6 monthly backups
      • Location: /opt/sure-data/backups on your host machine

      To customize these settings, edit the backup service in your compose.yml file:

      backup:
        profiles:
          - backup
        image: prodrigestivill/postgres-backup-local
        restart: unless-stopped
        volumes:
          - /your/custom/path:/backups  # Change this to your desired location
        environment:
          - POSTGRES_HOST=db
          - POSTGRES_DB=${POSTGRES_DB:-sure_production}
          - POSTGRES_USER=${POSTGRES_USER:-sure_user}
          - POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-sure_password}
          - SCHEDULE=@daily              # Change schedule (e.g., @hourly, @weekly)
          - BACKUP_KEEP_DAYS=7           # Number of daily backups to keep
          - BACKUP_KEEP_WEEKS=4          # Number of weekly backups to keep
          - BACKUP_KEEP_MONTHS=6         # Number of monthly backups to keep
      

      Backup schedule options

      You can use cron syntax or these shortcuts:

      • @hourly - Every hour
      • @daily - Once per day at midnight
      • @weekly - Once per week
      • @monthly - Once per month
      • Custom cron: 0 2 * * * (2 AM daily)

      Restoring from backup

      To restore your database from a backup:

      1. Stop the application:
      docker compose down
      
      1. Locate your backup file in the backup directory (e.g., /opt/sure-data/backups)

      2. Restore the backup:

      docker compose up -d db
      docker compose exec -T db psql -U sure_user -d sure_production < /path/to/backup.sql
      
      1. Restart the application:
      docker compose up -d
      

      Verifying backups

      Check that backups are running correctly:

      # View backup service logs
      docker compose logs backup
      
      # List backup files
      ls -lh /opt/sure-data/backups
      

      SSL certificate configuration

      For self-hosted environments using self-signed certificates or custom certificate authorities, Sure provides SSL configuration options.

      Environment variables

      Add these variables to your .env file:

      SSL_CA_FILE=/path/to/ca-bundle.pem
      SSL_VERIFY=true
      

      SSL_CA_FILE: Path to a custom CA certificate bundle (PEM format). Use this when:

      • Your environment uses self-signed certificates
      • You need to trust a custom certificate authority
      • Corporate proxies inject their own certificates

      SSL_VERIFY: Controls SSL certificate verification (default: true)

      • Set to false to disable SSL verification (not recommended for production)
      • Only disable verification in development or testing environments

      If you're using a custom CA bundle, mount it into your containers in compose.yml:

      services:
        web:
          volumes:
            - /path/to/your/ca-bundle.pem:/path/to/your/ca-bundle.pem:ro
        worker:
          volumes:
            - /path/to/your/ca-bundle.pem:/path/to/your/ca-bundle.pem:ro
      

      Restart the application after updating your configuration:

      docker compose restart web worker
      

      Optional: SSL/TLS Configuration

      Sure supports additional SSL/TLS configuration options for secure email delivery and API connections.

      Custom CA Certificate

      If you're using a custom Certificate Authority (CA) or self-signed certificates, you can specify a CA file:

      SSL_CA_FILE="/path/to/your/ca-certificate.pem"
      

      This is useful when:

      • Running Sure in a corporate environment with internal CAs
      • Using self-signed certificates for development
      • Connecting to services with custom certificate chains

      Skip TLS Verification for Email

      For development or testing environments, you can disable TLS verification for the email mailer:

      SMTP_ENABLE_STARTTLS_AUTO=false
      SMTP_TLS_VERIFY=false
      

      Only disable TLS verification in development or trusted environments. In production, always use proper TLS verification to ensure secure email delivery.

      When to use this:

      • Development environments with self-signed certificates
      • Testing email functionality locally
      • Internal mail servers with custom certificates

      Production recommendations:

      • Always use valid SSL/TLS certificates in production
      • Use the SSL_CA_FILE option instead of disabling verification
      • Ensure your SMTP server supports STARTTLS

      Mailer SSL configuration

      For SMTP connections, additional SSL options are available:

      SMTP_ENABLE_STARTTLS_AUTO=true
      SMTP_OPENSSL_VERIFY_MODE=none
      

      SMTP_ENABLE_STARTTLS_AUTO: Enable STARTTLS for SMTP connections (default: true)

      SMTP_OPENSSL_VERIFY_MODE: SSL verification mode for SMTP

      • none: Skip SSL verification
      • peer: Verify the server certificate (default)

      Security considerations

      Disabling SSL verification (`SSL_VERIFY=false` or `SMTP_OPENSSL_VERIFY_MODE=none`) exposes your application to man-in-the-middle attacks. Only use these settings in trusted networks or development environments.

      For production deployments:

      • Use properly signed certificates from a trusted CA
      • Keep SSL_VERIFY=true
      • Use SMTP_OPENSSL_VERIFY_MODE=peer
      • If you must use self-signed certificates, provide a CA bundle via SSL_CA_FILE

      Troubleshooting

      Database connection errors

      If you encounter ActiveRecord::DatabaseConnectionError on first startup, Docker may have initialized the Postgres database with a different default role from a previous attempt.

      The following commands will delete all existing data in your Sure database. Only proceed if you're comfortable losing this data.

      Reset the database:

      docker compose down
      docker volume rm sure_postgres-data
      docker compose up
      docker compose exec db psql -U sure_user -d sure_development -c "SELECT 1;"
      

      The last command verifies the issue is fixed.

      Slow CSV imports

      If CSV imports are processing rows slower than expected, check your worker logs for errors:

      docker compose logs worker
      

      Look for connection timeouts or Redis communication failures. The sure-worker container requires Redis to process CSV imports.

      Getting help

      If you find bugs or have feature requests: