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 file, which basically arefor the postgres and email credentialsdetails. Just make sure you create again a nice secret key with the command
openssl rand -hex 64
and then paste it into the .env file for the SECRET_KEY_BASE
.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 750 for the "sure" folder you are hosting everything in. Otherwise it cannot create a directory for your account.
MostEmaillikely configuration
you Towill enableget emailan notificationserror for because of sure not being able to write to the sure folder. In that case as noted above go into your folder and passwordchange resets,the configurepermissions SMTPand settingsrestart inthe sure stack.
Then you will be able to reach your sure .envfile:
SMTP_ADDRESS=smtp.example.comat SMTP_PORT=587DOCKERVMIP:Port SMTP_DOMAIN=example.comand SMTP_USERNAME=your-usernamecreate SMTP_PASSWORD=your-passworda SMTP_AUTHENTICATION=plainuser SMTP_ENABLE_STARTTLS_AUTO=trueaccount. SSL/TLSNow, options
For SMTP serversas with customany SSLapplication certificatesyou should give it a domain name public or self-signednot. certificates:If you don't know how to do this check the Reverse Proxy section.
SkipPerfect! TLSNow 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 foron the next step.
Configurewe environmentwill variables
discuss Opensome thebasic .env file in your text editorsettings 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:
Run in the background
To run Sure in the background:
Ctrl+Cdocker 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
Recommended images
ghcr.io/we-promise/sure:latestghcr.io/we-promise/sure:stableYou 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:
/opt/sure-data/backupsTo 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@daily@weekly@monthly0 2 * * *Restoring from backup
To restore your database from a backup:
docker compose down
Locate your backup file in the backup directory (e.g., /opt/sure-data/backups)
Restore the backup:
docker compose up -d db
docker compose exec -T db psql -U sure_user -d sure_production < /path/to/backup.sql
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:
SSL_VERIFY: Controls SSL certificate verification (default: true)
falseIf 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,things you can specify a CA file:
SSL_CA_FILE="/path/to/your/ca-certificate.pem"
This is useful when:
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:
Production recommendations:
SSL_CA_FILEMailer 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
nonepeerSecurity 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:
SSL_VERIFY=trueSMTP_OPENSSL_VERIFY_MODE=peerSSL_CA_FILETroubleshooting
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,just 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: