Learning paths / Deploy on ComputeSphere / Data: databases and storage

Connecting to a database

Reading · 6 min · Module 5, lesson 3 of 536 min left in this module

Module 5 · Data: databases and storageLesson 3 of 5

Goal: Connect a service to a database: a SphereDB database in its environment, or one from a provider through a secret.

Key idea

Your service reaches a database through a connection string. A SphereDB database in the same environment hands every service its string as DATABASE_URL, privately. A database from another provider needs the string stored as a secret, and TLS over the internet.

SphereDB: a database in your environment

SphereDB is ComputeSphere's managed PostgreSQL (versions 16 to 18). It runs in the environment you create it in, and ComputeSphere handles its backups (nightly, restorable to any moment in the last 7 days) and, if you turn on high availability (1 vCPU or more), a standby in another zone.

It comes with every plan, in US East and EU (Sweden). In the console, open the New menu in the top bar and choose SphereDB, then pick an instance type, a version and a storage size. The Free type gives each account one small database (500 MB, fixed size) to learn on. From a terminal:

csph db create shop --environment <environment-id> --instance-type "Standard 1"

When it's ready, every service in the environment gets its connection string as DATABASE_URL, and running services restart to pick it up. If another database already gives the environment DATABASE_URL, nothing is injected: you choose which services get it. The string goes through a connection pooler, stays inside the environment, and uses TLS. csph db connection-string shop prints it if a tool needs it.

A database from a provider

A hosted database elsewhere, such as managed PostgreSQL or MySQL from your cloud, gives you a connection string. The provider handles backups, upgrades and failover.

postgres://app_user:[email protected]:5432/shop?sslmode=require

It holds a username and password, a host and port, a database name, and options such as TLS. The password makes the whole string a secret.

Store it as a secret

A secret is a variable whose value ComputeSphere stores but never shows again. Your app reads it as an ordinary environment variable, for example DATABASE_URL.

  1. Open the service, then Settings, then the Environment variables card.
  2. Switch to the Secrets tab and add DATABASE_URL with the connection string.
  3. Save, and choose Save & redeploy so the running service picks it up.

Staging and production should never share a database. Each environment has its own secrets, so point each one's DATABASE_URL at its own database and the same image runs safely in both.

From the terminal, and for several services
csph services secrets set DATABASE_URL="$DATABASE_URL" --service <service-id>

Keep the value in a shell variable (read -s DATABASE_URL; export DATABASE_URL) so it never appears in the command or your shell history. set saves the whole set of secrets at once, so it needs every existing secret key too; --replace keeps only the ones you list and drops the rest. The console is safer while you're learning.

If several services use the same database, set it once on the environment with csph environments secrets set. Every service inherits it, and a service can override it.

Make sure the network allows it

Your services reach the internet directly, so a database with a public address and TLS works out of the box. Check three things:

  • TLS on. Use the provider's option (sslmode=require or similar); the connection crosses the internet.
  • Public endpoint. Services can't reach private addresses such as 10.x.x.x, so use the database's public endpoint.
  • No IP allowlist. Your services don't have a fixed outbound address to allow. Rely on TLS and a strong, database-only password.

Connections add up

A connection pool is a set of open database connections your app reuses instead of opening one per request. Each spherelet keeps its own pool, so five spherelets with a pool of 10 each is 50 connections. Small database plans often allow fewer, so size the pool with your spherelet count in mind. SphereDB's DATABASE_URL already goes through a pooler, which helps; a provider's database may not.

Reaching your other services privately

Services in one environment can reach each other without the internet if the environment has Private network on. Each answers on d- plus the eight characters from its public URL, then its port: http://d-3f9c2a71:8080 for d-hello-web-3f9c2a71.computesphere.app. Other environments can't reach it this way.

Turn it on when you create the environment: csph environments create --name <name> --region <region> --project <project-id> --private-network=true. Switching it on later doesn't yet take effect, so decide up front.

Check yourself

You added DATABASE_URL as a secret and chose Save only instead of Save & redeploy. The app still can't find the database. Why?
Your database only accepts connections on 10.0.4.12. What do you change?