Velld LogoVelld

Database Configuration

Connect and configure PostgreSQL, MySQL, and MongoDB

Database Configuration

Learn how to connect Velld to your databases and configure them for optimal backups.


Supported Databases

PostgreSQL

Connection Settings

Name: My PostgreSQL DB
Type: PostgreSQL
Host: host.docker.internal  # or your server IP
Port: 5432                  # default PostgreSQL port
Database: myapp_production
Username: postgres
Password: your_password
SSL Mode: disable          # or require, verify-ca, verify-full

Docker Setup

Make sure you're using the PostgreSQL Dockerfile:

# apps/api/Dockerfile.postgres
RUN apk add --no-cache \
    sqlite-libs \
    postgresql-client

Connection String Format

Velld supports standard PostgreSQL connection strings:

postgresql://username:password@host:port/database?sslmode=disable

Backup Command

Velld uses pg_dump under the hood:

pg_dump -h host -p port -U username -d database -F c -f backup.dump

Options:

  • -F c: Custom format (compressed, allows selective restore)
  • -F p: Plain SQL format (human-readable)
  • -F t: Tar format

Common Issues

Connection refused:

  • Ensure PostgreSQL is accepting connections from Docker
  • Update postgresql.conf: listen_addresses = '*'
  • Update pg_hba.conf to allow connections from Docker network

Permission denied:

  • User needs appropriate privileges:
    GRANT CONNECT ON DATABASE myapp_production TO backup_user;
    GRANT SELECT ON ALL TABLES IN SCHEMA public TO backup_user;

SSL errors:

  • For local development, use sslmode=disable
  • For production, use sslmode=require or higher
  • Provide SSL certificates if using verify-ca or verify-full

Best Practices

  1. Create a dedicated backup user:

    CREATE USER backup_user WITH PASSWORD 'secure_password';
    GRANT CONNECT ON DATABASE myapp_production TO backup_user;
    GRANT SELECT ON ALL TABLES IN SCHEMA public TO backup_user;
    GRANT SELECT ON ALL SEQUENCES IN SCHEMA public TO backup_user;
    ALTER DEFAULT PRIVILEGES IN SCHEMA public 
      GRANT SELECT ON TABLES TO backup_user;
  2. Use read-only replicas for large databases to avoid impacting production

  3. Test restores regularly:

    pg_restore -h localhost -U postgres -d test_db backup.dump
  4. Monitor backup size - large databases may need custom retention policies

MySQL / MariaDB

Connection Settings

Name: My MySQL DB
Type: MySQL
Host: host.docker.internal  # or your server IP
Port: 3306                  # default MySQL port
Database: myapp_production
Username: root
Password: your_password

Docker Setup

Make sure you're using the MySQL Dockerfile:

# apps/api/Dockerfile.mysql
RUN apk add --no-cache \
    sqlite-libs \
    mysql-client

Connection String Format

mysql://username:password@host:port/database

Backup Command

Velld uses mysqldump:

mysqldump -h host -P port -u username -p database > backup.sql

Options:

  • --single-transaction: For InnoDB tables (no locks)
  • --routines: Include stored procedures and functions
  • --triggers: Include triggers
  • --events: Include scheduled events

Common Issues

Access denied:

  • Ensure user has sufficient privileges:
    GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER 
      ON myapp_production.* TO 'backup_user'@'%';
    FLUSH PRIVILEGES;

Max packet size errors:

  • Increase max_allowed_packet in my.cnf:
    [mysqldump]
    max_allowed_packet=512M

Connection from Docker:

  • Update bind-address in my.cnf:
    bind-address = 0.0.0.0

Best Practices

  1. Create a dedicated backup user:

    CREATE USER 'backup_user'@'%' IDENTIFIED BY 'secure_password';
    GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER 
      ON myapp_production.* TO 'backup_user'@'%';
    FLUSH PRIVILEGES;
  2. Use --single-transaction for consistent backups without locks:

    mysqldump --single-transaction --routines --triggers myapp_production
  3. Exclude large tables if needed:

    mysqldump myapp_production --ignore-table=myapp_production.logs
  4. Test restores:

    mysql -u root -p test_db < backup.sql

MongoDB

Connection Settings

Name: My MongoDB
Type: MongoDB
Host: host.docker.internal  # or your server IP
Port: 27017                 # default MongoDB port
Database: myapp_production
Username: admin
Password: your_password
Auth Database: admin        # usually 'admin'

Docker Setup

Make sure you're using the MongoDB Dockerfile:

# apps/api/Dockerfile.mongo
RUN apk add --no-cache \
    sqlite-libs \
    mongodb-tools

Connection String Format

mongodb://username:password@host:port/database?authSource=admin

For MongoDB Atlas or replica sets:

mongodb+srv://username:password@cluster.mongodb.net/database

Backup Command

Velld uses mongodump:

mongodump --host=host --port=port \
          --username=user --password=pass \
          --db=database --archive=backup.archive --gzip

Options:

  • --archive: Single archive file
  • --gzip: Compress the archive
  • --oplog: Include oplog for point-in-time recovery

Common Issues

Authentication failed:

  • Ensure user has correct roles:
    use admin
    db.createUser({
      user: "backup_user",
      pwd: "secure_password",
      roles: [
        { role: "backup", db: "admin" },
        { role: "read", db: "myapp_production" }
      ]
    })

Connection timeout:

  • Check MongoDB is listening on all interfaces:
    # mongod.conf
    net:
      bindIp: 0.0.0.0

SSL/TLS errors:

  • Use connection string with SSL options:
    mongodb://user:pass@host:port/db?ssl=true&authSource=admin

Best Practices

  1. Create a dedicated backup user:

    use admin
    db.createUser({
      user: "backup_user",
      pwd: "secure_password",
      roles: [
        { role: "backup", db: "admin" },
        { role: "read", db: "myapp_production" }
      ]
    })
  2. Use --oplog for replica sets to ensure consistency:

    mongodump --oplog --archive=backup.archive --gzip
  3. Backup specific collections if needed:

    mongodump --db=myapp --collection=users
  4. Test restores:

    mongorestore --archive=backup.archive --gzip \
                 --nsFrom='myapp_production.*' \
                 --nsTo='test_db.*'
  5. For large databases, consider backing up during off-peak hours


Connecting to Databases on Host Machine

When your database is running on your host machine (not in Docker), use these special hostnames:

macOS / Windows (Docker Desktop)

host.docker.internal

Linux

172.17.0.1

Or add this to your docker-compose.yml:

services:
  api:
    extra_hosts:
      - "host.docker.internal:host-gateway"

SSH Tunnel Support

Velld supports SSH tunnels for secure database connections, especially useful when:

  • Your database is behind a firewall
  • You need to connect through a bastion/jump host
  • You want an extra layer of security
  • Your database doesn't allow direct external connections

Enabling SSH Tunnel

When adding a connection, expand the SSH Tunnel section and enable it. You'll need:

  1. SSH Host: The SSH server address (e.g., bastion.example.com)
  2. SSH Port: Usually 22
  3. SSH Username: Your SSH username
  4. Authentication Method: Choose between password or private key

Authentication Methods

Password Authentication

The simplest method—just provide your SSH password:

SSH Host: bastion.example.com
SSH Port: 22
SSH Username: deploy
SSH Password: your_ssh_password

Less secure than key-based auth. Use only if you trust the network and have strong passwords.

Private Key Authentication

More secure—uses your SSH private key:

SSH Host: bastion.example.com
SSH Port: 22
SSH Username: deploy
SSH Private Key: |
  -----BEGIN RSA PRIVATE KEY-----
  MIIEpAIBAAKCAQEA...
  -----END RSA PRIVATE KEY-----

How to get your private key:

# Display your private key
cat ~/.ssh/id_rsa

# Or generate a new one
ssh-keygen -t rsa -b 4096 -C "velld-backup"

Then copy the entire key (including -----BEGIN and -----END lines) into Velld.

Make sure your public key is added to the SSH server's ~/.ssh/authorized_keys.

Configuration Example

Here's a complete example connecting to a PostgreSQL database through an SSH tunnel:

# Database settings
Name: Production DB (via SSH)
Type: PostgreSQL
Host: localhost              # or 127.0.0.1 (database host from SSH server perspective)
Port: 5432
Database: myapp_production
Username: postgres
Password: db_password
SSL Mode: disable

# SSH tunnel settings
SSH Enabled: 
SSH Host: bastion.example.com
SSH Port: 22
SSH Username: deploy
SSH Authentication: Private Key
SSH Private Key: [paste your private key]

Important: The Host field should be the database hostname as seen from the SSH server, not from your local machine. Common values:

  • localhost or 127.0.0.1 if the database is on the same server as SSH
  • The internal IP or hostname if they're on separate servers

How It Works

  1. Velld connects to your SSH server
  2. Creates a secure tunnel to the database server
  3. Routes database traffic through the tunnel
  4. Database sees the connection coming from the SSH server
[Velld] --SSH--> [SSH Server] ---> [Database]
         (encrypted)        (internal network)

Common Scenarios

Database on Same Server as SSH

Host: localhost  # Database is on the SSH server itself
Port: 5432
SSH Host: myserver.com

Database on Different Internal Server

Host: 10.0.1.50  # Database's internal IP
Port: 5432
SSH Host: bastion.mycompany.com  # Jump host

AWS RDS Through Bastion

Host: mydb.abc123.us-east-1.rds.amazonaws.com
Port: 5432
SSH Host: ec2-bastion.example.com

Troubleshooting SSH Tunnels

SSH connection failed:

  • Verify SSH credentials work manually:
    ssh deploy@bastion.example.com
  • Check firewall allows SSH (port 22)
  • Ensure your SSH user has access

SSH connected but database connection failed:

  • The Host field should be from SSH server's perspective, not yours
  • Try localhost if database is on SSH server
  • Verify database allows connections from SSH server's IP

Private key rejected:

  • Make sure you copied the entire key (including header/footer)
  • Key should be in OpenSSH format (PEM)
  • Verify public key is in ~/.ssh/authorized_keys on SSH server
  • Check file permissions: chmod 600 ~/.ssh/authorized_keys

Permission denied (publickey):

  • Your public key isn't authorized on the SSH server
  • Add your public key to ~/.ssh/authorized_keys:
    # On SSH server
    echo "ssh-rsa AAAAB3..." >> ~/.ssh/authorized_keys
    chmod 600 ~/.ssh/authorized_keys

Remote Database Connections

Over the Internet

If your database is on a remote server:

  1. Ensure the database accepts remote connections
  2. Open firewall ports (5432, 3306, or 27017)
  3. Use SSL/TLS for security
  4. Consider using SSH tunnel (see section above)

Connection Testing

Before saving a connection, always click Test Connection. This verifies:

  • ✅ Network connectivity
  • ✅ Credentials are correct
  • ✅ User has necessary permissions
  • ✅ Database exists and is accessible

If the test fails, check the error message—it will tell you exactly what's wrong!


Security Best Practices

1. Use Dedicated Backup Users

Never use root or admin accounts for backups. Create read-only users with minimal privileges.

2. Rotate Passwords Regularly

Change database passwords periodically and update them in Velld.

3. Enable SSL/TLS

Always use encrypted connections for remote databases:

  • PostgreSQL: sslmode=require
  • MySQL: --ssl-mode=REQUIRED
  • MongoDB: ssl=true

4. Restrict Network Access

Use firewall rules to only allow connections from your Velld server:

# PostgreSQL
host    all    backup_user    172.17.0.0/16    md5

# MySQL
CREATE USER 'backup_user'@'172.17.0.%' IDENTIFIED BY 'password';

5. Encrypt Backup Files

Velld encrypts connection credentials, but you can also:

  • Encrypt backup files at rest
  • Use encrypted volumes for backup storage
  • Enable encryption in your storage backend

Troubleshooting

Check Database Client is Installed

# Enter the API container
docker exec -it velld-api-1 sh

# Check for database clients
which pg_dump        # PostgreSQL
which mysqldump      # MySQL
which mongodump      # MongoDB

If a client is missing, you're using the wrong Dockerfile. See Installation for database-specific Dockerfiles.

Test Connection Manually

# PostgreSQL
pg_dump --host=host.docker.internal --port=5432 --username=postgres --version

# MySQL
mysqldump --host=host.docker.internal --port=3306 --user=root --version

# MongoDB
mongodump --host=host.docker.internal --port=27017 --version

View Backup Logs

docker compose logs api | grep backup

Next Steps