Cadenas de conexión
sh0 no conecta las bases de datos a tus aplicaciones por ti. Lees la información de conexión, creas una base y un usuario para la aplicación y defines DATABASE_URL tú mismo. Esta página muestra cada paso con los comandos tal como se ejecutan.
DATABASE_URL, REDIS_URL ni ninguna otra variable a tus aplicaciones, sea cual sea su proyecto. Una aplicación que espera DATABASE_URL no recibe nada hasta que la defines.Encontrar la información de conexión
En el panel, abre Bases y luego el servidor: Información de conexión muestra el Host interno, el puerto, la contraseña de administrador y una URL de conexión para copiar.
Desde la CLI, sh0 db connection-info recibe el ID del servidor que se muestra al crearlo (o con sh0 db list):
$ sh0 db create --name my-pg --engine postgres
Database server 'my-pg' created (id: e8afafa4-2ff1-4088-8276-fccb839734a8, engine: postgres 16)
$ sh0 db connection-info e8afafa4-2ff1-4088-8276-fccb839734a8
Connection Info:
Host: my-pg.internal
Port: 32962
Username: postgres
Password: <password>
Internal: postgresql://postgres:<password>@my-pg.internal:5432/
External: postgresql://postgres:<password>@localhost:32962/Usa la URL Internal desde tus aplicaciones. La URL External apunta a un puerto vinculado a 127.0.0.1 en el servidor: solo responde desde el propio servidor (ver «Conectarte desde tu equipo»).
Una base y un usuario por aplicación
Un servidor arranca sin ninguna base y solo con la cuenta de administrador. Da a cada aplicación su propia base y su propio usuario en lugar de la contraseña de administrador. En el panel: Crear base de datos, Crear usuario y luego Otorgar acceso. Desde la CLI:
$ sh0 db create-database e8afafa4-2ff1-4088-8276-fccb839734a8 --name appdb
Database 'appdb' created (id: 503a447c-f9f5-44b8-87cf-22c0905f075c).
$ sh0 db create-user e8afafa4-2ff1-4088-8276-fccb839734a8 --username appuser --password '<password>'
User 'appuser' created (id: 86de6179-7e97-463a-93d8-dfd89b1da6e2).
$ sh0 db grant e8afafa4-2ff1-4088-8276-fccb839734a8 \
--user 86de6179-7e97-463a-93d8-dfd89b1da6e2 \
--database 503a447c-f9f5-44b8-87cf-22c0905f075c --privileges all
Access granted.- Reglas de contraseña -- al menos una mayúscula y un símbolo, entre otras; una contraseña que no cumple alguna se rechaza indicando la regla incumplida. El botón Generar del panel crea una válida; guárdala, no se volverá a mostrar.
- Privilegios --
alloreadonly. Cualquier otro valor se rechaza.
Definir DATABASE_URL en la aplicación
Construye la URL con el host interno, el puerto del motor, el usuario y la base, y guárdala como variable de entorno de la aplicación. Las variables se aplican al desplegar, así que vuelve a desplegar:
$ sh0 env my-api set "DATABASE_URL=postgresql://appuser:<password>@my-pg.internal:5432/appdb"
[ok] Set DATABASE_URL for 'my-api'
$ sh0 deploy my-api
[*] Deploying my-api...
Deployment ID: 64492c39-dad0-409f-ad6d-29b71f79bab3
Status: queuedLa forma de la URL según el motor (sustituye los nombres por los tuyos; el puerto interno es el puerto por defecto del motor, no el que aparece en Port):
- PostgreSQL --
postgresql://appuser:<password>@my-pg.internal:5432/appdb - MySQL y MariaDB --
mysql://appuser:<password>@my-mysql.internal:3306/appdb - Redis --
redis://:<password>@my-redis.internal:6379
@, :, /, #…) deben codificarse con porcentajes en una URL. Las tareas programadas no reciben estas variables -- ver Tareas programadas.Red interna
Las aplicaciones y los servidores de bases comparten la red Docker de sh0. Una aplicación llega a un servidor por <nombre-del-servidor>.internal en el puerto del motor -- medido desde un contenedor de aplicación: una conexión TCP a my-pg.internal:5432 se abre, y appuser inicia sesión en appdb con la URL anterior.
Conectarte desde tu equipo
Para llegar a una base desde tu equipo (pgAdmin, TablePlus, DBeaver, psql) hay dos vías. Prefiere la primera.
Túnel SSH (recomendado)
El puerto que aparece en Port (aquí 32962) está vinculado a 127.0.0.1 en el servidor. Redirígelo por SSH: nada queda expuesto a internet y el acceso es el de tu clave SSH.
ssh -N -L 5432:127.0.0.1:32962 root@your-server
# in another terminal
psql "postgresql://appuser:<password>@127.0.0.1:5432/appdb"Acceso externo
Habilitar acceso externo en el servidor abre un puerto público a través del proxy de sh0. Lo que impone el código de la versión publicada:
- IPs permitidas obligatorias -- direcciones o rangos CIDR;
0.0.0.0/0y::/0se rechazan. - TLS obligatorio por defecto.
- Caducidad -- 1 h, 6 h, 24 h, 7 días, 30 días o permanente.
- Puerto -- el primero libre en el rango 10000-10999; tu cortafuegos debe dejarlo pasar.
Pooling de conexiones
Cada base tiene un límite de conexiones (100 por defecto en PostgreSQL). Dimensiona tus pools para que el conjunto de réplicas quede por debajo.
- Usa el pool integrado de tu framework -- la mayoría de los ORM y controladores tienen uno.
- Reparte el límite entre réplicas -- con 3 réplicas de una aplicación y un límite de 100, unas 30 conexiones por réplica, menos lo que usen otras aplicaciones.
- Configura tiempos de inactividad para que las conexiones ociosas liberen su sitio.
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
});Ejemplos para frameworks comunes
Cada ejemplo de abajo lee la variable DATABASE_URL que definiste en la aplicación.
production:
url: <%= ENV['DATABASE_URL'] %>import dj_database_url
DATABASES = {"default": dj_database_url.config(conn_max_age=600)}let pool = PgPoolOptions::new()
.max_connections(20)
.connect(&std::env::var("DATABASE_URL")?)
.await?;pool, err := pgxpool.New(ctx, os.Getenv("DATABASE_URL"))