> ## Documentation Index
> Fetch the complete documentation index at: https://sure-917046f5-docs-backup-restore-clarity.mintlify.site/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

1. Follow the [official Docker installation guide](https://docs.docker.com/engine/install/)
2. Start the Docker service on your machine
3. Verify the installation:

```bash theme={null}
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:

```bash theme={null}
mkdir -p ~/docker-apps/sure
cd ~/docker-apps/sure
```

### Download the Docker Compose file

Download the sample compose file from the Sure repository:

```bash theme={null}
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:

```txt theme={null}
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):

```txt theme={null}
SMTP_OPENSSL_VERIFY_MODE=none
```

**Use custom CA certificate**:

```txt theme={null}
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:

```bash theme={null}
touch .env
```

### Generate a secret key

Generate a secret key using one of these methods:

**With OpenSSL:**

```bash theme={null}
openssl rand -hex 64
```

**Without OpenSSL:**

```bash theme={null}
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:

```txt theme={null}
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](/providers/market-data) for details on each provider.

```txt theme={null}
# 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"
```

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

## Running the application

### Start the application

Start the app to verify everything is working:

```bash theme={null}
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:

```bash theme={null}
docker compose up -d
```

Verify it's running:

```bash theme={null}
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:

```yml theme={null}
image: ghcr.io/we-promise/sure:latest
```

### Recommended images

* `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](https://github.com/we-promise/sure/pkgs/container/sure).

### Update to the latest version

Your app does not automatically update. To update:

```bash theme={null}
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:

```yml theme={null}
image: ghcr.io/we-promise/sure:stable
```

Then restart the app:

```bash theme={null}
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.

<Warning>
  The backup service only creates PostgreSQL backups. It does not back up local files stored in Sure's `storage` directory.
  If your deployment uses local file storage, back up that directory separately. If you use external object storage such as S3 or R2, make sure that storage is protected with its own backup and retention policy.
</Warning>

### What to back up

For a complete recovery plan, make sure you know which of these apply to your deployment:

* **PostgreSQL database**: accounts, transactions, settings, users, and metadata
* **Local file storage**: uploaded files stored on disk by the app
* **External object storage**: uploaded files stored in S3, R2, or another object store
* **Environment and deployment config**: your `.env`, `compose.yml`, secrets, and any reverse proxy or DNS setup needed to bring the app back online

### Enabling backups

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

```bash theme={null}
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:

```yml theme={null}
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)

### Restore from a PostgreSQL backup

Use this process when you have a SQL dump created by the backup service or with `pg_dump`.

> \[!NOTE]
> If you customized the PostgreSQL username, password, or database name in your `.env` or `compose.yml`, replace `sure_user` and `sure_production` in the commands below.

1. Stop the application containers so they do not write to the database during the restore:

```bash theme={null}
docker compose stop web worker
```

2. Start or keep the database container running:

```bash theme={null}
docker compose up -d db
```

3. Locate the backup file in your backup directory, for example `/opt/sure-data/backups`.

4. Restore the SQL backup into PostgreSQL:

```bash theme={null}
docker compose exec -T db psql -U sure_user -d sure_production < /path/to/backup.sql
```

5. Restart the app:

```bash theme={null}
docker compose up -d web worker
```

### Restore local uploaded files

If your Sure instance stores uploaded files on the local filesystem, restoring the database alone is not enough. You must also restore the app's storage directory from the matching file backup.

The exact host path depends on how you mapped volumes in `compose.yml`. Restore the same directory that Sure uses for local storage, then restart the app containers.

If you are using external object storage instead of local disk, restore those files using that provider's backup or versioning workflow instead.

### Verify the restore

After restoring, check the following:

* You can sign in successfully
* Your accounts and transactions appear as expected
* Uploaded files open correctly, if you use uploads
* The web and worker containers start cleanly without repeated errors

### Verifying backups

Check that backups are running correctly:

```bash theme={null}
# 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:

```txt theme={null}
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`:

```yml theme={null}
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:

```bash theme={null}
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:

```txt theme={null}
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:

```txt theme={null}
SMTP_ENABLE_STARTTLS_AUTO=false
SMTP_TLS_VERIFY=false
```

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

**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:

```txt theme={null}
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

<Warning>
  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.
</Warning>

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.

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

Reset the database:

```bash theme={null}
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:

```bash theme={null}
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:

* Read the [contributing guide](https://github.com/we-promise/sure/wiki/How-to-Contribute-Effectively-to-Sure)
* Ask in the [Discord](https://discord.gg/36ZGBsxYEK)
* Open an [issue](https://github.com/we-promise/sure/issues/new/choose)
