Running apps
Databases
Run Postgres, MySQL and Redis for your apps, each on a volume of its own, linked with a connection URL.
Create and link a database#
Jokku runs Postgres, MySQL and Redis for your apps, each from its official image:
Linking sets DATABASE_URL on the app (REDIS_URL for Redis) and restarts it, so it connects right away. The database is reachable only from your apps, at postgres-shopdb.internal, on any server in the cluster, until you expose it.
Each gets a 10 GB volume. Choose otherwise when you create it:
Work with it#
Reach it from outside#
To connect from your laptop, a BI tool or another host, expose the database at a domain:
Point the domain at your servers, or at your edges, and open the port in their firewalls. Jokku's proxy takes the connections, on every server that takes web traffic and on every edge, and sends them to the database over the cluster's encrypted network.
A domain Let's Encrypt can reach gets a certificate from it, so clients can check it (sslmode=verify-full sslrootcert=system). Any other name gets one the proxy makes itself, which sslmode=require accepts without checking.
--allow takes addresses and ranges, comma-separated (--allow 203.0.113.7,198.51.100.0/24), and the proxy turns away everyone else. Without it, any address can connect, and only the database's password and TLS protect it: Jokku generates long random passwords, but an allow list is better. Run expose again to change the domain, port or list. --port picks another port for Postgres or Redis too.
Only on your network#
To reach a database from your own network but not from the internet, add --lan:
Your servers take the connections, and your edges don't: they don't listen on the port, and they can't reach the database. Unless you give an --allow list of your own, only private addresses are let in (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, Tailscale's 100.64.0.0/10, and IPv6's fc00::/7). Point the name at one of your servers, as the sslip.io name above does, or use a name from your own DNS. The certificate is one the proxy makes itself, since Let's Encrypt can't reach your network: sslmode=require accepts it without checking.
See inside it#
The Databases view of jokku top (key 8) shows each database's connections against its limit, its queries a second, how long they take, and how often reads come from memory, over the last minute, hour and day, with who's connected, its users and its slowest queries. db:<engine>:info shows the same:
Every ten seconds, your control server runs the database's own client (psql, mysql or redis-cli) in its microVM and leaves its own queries out of what it counts. It keeps the history in memory, so the hour and day start over when it restarts. The times are how long queries took inside the database, without the trip from your app.
pg_stat_statements has to be loaded when Postgres starts. A new database loads it. On a database created before v0.8.12, Jokku turns it on the first time it looks, and it starts at the database's next restart: jokku db:postgres:restart shopdb. Until then, the average is per transaction.
Users#
Your apps connect as the database's own user. Add others for a reporting tool, a teammate or a second app:
users:add makes a password and prints the user's URL, and its URL from outside when the database is exposed. A user reads and writes the data, or only reads with --read-only, but can't change the schema, so migrations stay with the database's own user.
Postgres (14 and newer) and MySQL have users. Redis has one password, the one in its URL.
Export and import#
Over SSH, leave out -t so the dump passes through untouched: ssh jokku@your-server db:postgres:export shopdb > shopdb.dump.
Backups#
With a backup destination, a database is backed up every 15 minutes from the moment it's created, and if its server dies it comes back on another one from its latest backup.
Under the hood#
A database is an app named after its engine, such as postgres-shopdb, deployed from a compose file with one service and a data volume. So jokku top, storage:report and resource:limit work on it too. It isn't listed by apps:list, and pushes to it are refused.