Connection Strings
Connect your applications to databases with auto-injected environment variables. sh0 handles internal networking so your app can reach its database by hostname.
Finding Connection Strings
Every database created in sh0 has its connection details available in the dashboard. Navigate to the database detail page and click the Connection tab to see all connection information.
The connection tab displays:
- Full connection URL -- Ready to copy and paste into your app configuration.
- Individual fields -- Host, port, username, password, and database name as separate values.
- Connection command -- A CLI command to connect directly (e.g.,
psql,mysql).
For example, a PostgreSQL database connection string looks like:
postgresql://myuser:secretpass@mydb:5432/myappAuto-Injected Environment Variables
When you create a database in a stack, sh0 automatically injects connection environment variables into all application services within the same stack. Your app can read these variables at runtime without any manual configuration.
Variable Naming Convention
Auto-injected variables follow a consistent naming pattern based on the database name and engine:
DATABASE_URL=postgresql://sh0:generated_pass@mydb:5432/sh0
MYDB_HOST=mydb
MYDB_PORT=5432
MYDB_USER=sh0
MYDB_PASSWORD=generated_pass
MYDB_DATABASE=sh0DATABASE_URL=mysql://sh0:generated_pass@maindb:3306/sh0
MAINDB_HOST=maindb
MAINDB_PORT=3306
MAINDB_USER=sh0
MAINDB_PASSWORD=generated_pass
MAINDB_DATABASE=sh0REDIS_URL=redis://:generated_pass@cache:6379
CACHE_HOST=cache
CACHE_PORT=6379
CACHE_PASSWORD=generated_passMONGO_URL=mongodb://sh0:generated_pass@docs:27017/sh0
DOCS_HOST=docs
DOCS_PORT=27017
DOCS_USER=sh0
DOCS_PASSWORD=generated_pass
DOCS_DATABASE=sh0DATABASE_URL (or REDIS_URL / MONGO_URL) as a convenience. If you have multiple databases of the same engine, use the name-prefixed variables to avoid conflicts.Connecting from the Same Stack
Services within the same stack share a Docker network. This means your app can connect to the database using the database container's name as the hostname. No IP addresses, no port mapping -- just the container name.
// The DATABASE_URL is auto-injected by sh0
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
});# settings.py
import dj_database_url
DATABASES = {
'default': dj_database_url.config(
default=os.environ['DATABASE_URL']
)
}External Access
By default, databases are only accessible from within the stack network. To connect from your local machine (for example, using a GUI tool like pgAdmin, TablePlus, or DBeaver), you need to enable external access.
- Open the database settings.
- Toggle Public Access to enable it.
- sh0 maps the container port to a random high port on the host (e.g.,
54321). - Connect using
your-server-ip:54321with your database credentials.
Connection Pooling
Most databases have a limit on the number of concurrent connections. Connection pooling helps you stay within these limits while serving many requests.
Best practices for connection pooling in sh0:
- Use your framework's built-in pool -- Most ORMs and database drivers support connection pooling. Configure the pool size based on your database limits.
- Match pool size to available connections -- PostgreSQL defaults to 100 max connections. If you have 3 app replicas, set each pool to ~30 connections.
- Set connection timeouts -- Configure idle connection timeouts to prevent stale connections from consuming slots.
- Monitor connection count -- Use the database metrics dashboard to track active connections over time.
const pool = new Pool({
connectionString: process.env.DATABASE_URL,
max: 20, // Maximum connections in the pool
idleTimeoutMillis: 30000, // Close idle connections after 30s
connectionTimeoutMillis: 5000, // Fail if connection takes > 5s
});Common Framework Examples
Here are connection examples for popular frameworks. All of them use the DATABASE_URL environment variable that sh0 injects automatically.
production:
url: <%= ENV['DATABASE_URL'] %>DB_CONNECTION=pgsql
DB_HOST=${{ MYDB_HOST }}
DB_PORT=${{ MYDB_PORT }}
DB_DATABASE=${{ MYDB_DATABASE }}
DB_USERNAME=${{ MYDB_USER }}
DB_PASSWORD=${{ MYDB_PASSWORD }}let pool = PgPoolOptions::new()
.max_connections(20)
.connect(&std::env::var("DATABASE_URL")?)
.await?;pool, err := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))DATABASE_URL. If yours does, you do not need to configure anything -- just deploy to sh0 and it works out of the box.