# Working with a database

A database is private: only its project's services reach it, at `postgres:5432` and the like. For yourself there are two ways in, a prompt in its own container and your own machine, through the project's private network or a public port.

## A prompt in it

From your terminal, with the [command line](/docs/cli):

```bash
alf shell shop/postgres --live -- psql -U app app
```

For MySQL, `alf shell shop/mysql --live -- sh -c 'mysql -u app -p"$MYSQL_PASSWORD" app'`; for Redis, `alf shell shop/redis --live -- sh -c 'redis-cli -a "$REDIS_PASSWORD"'`; for MongoDB, `alf shell shop/mongodb --live -- sh -c 'mongosh -u app -p "$MONGO_PASSWORD" --authenticationDatabase app app'`. The **Connect** tab has the line with your names filled in. It runs in the database's own container (`--live`), where the client and the password are.

In the dashboard instead: the database's **Terminal** tab, with *Its own running container* ticked, and `psql -U app app` there.

## From your own machine

With [network access](/docs/network-access), the database opens on your machine without being put on the internet: a GUI client, `psql`, or a migration you run locally talks to it as if it were on `localhost`.

```bash
alf connect shop postgres
```

opens it on `localhost:5432` (or a free port, if that one's taken) until you press Ctrl-C, so `psql postgres://app:…@localhost:5432/app` reaches the project's database. The password is a secret, so the dashboard doesn't show it, but the database's own container has it: `alf exec shop/postgres --live 'echo $POSTGRES_PASSWORD'` (`$MYSQL_PASSWORD` for MySQL, `$REDIS_PASSWORD` for Redis, `$MONGO_PASSWORD` for MongoDB), or `echo` it in its terminal. With `--all`, every service of the project is at its own name instead: `psql -h postgres.shop.internal -U app`.

For something that can't run the command line (a hosted BI tool, a server elsewhere), give the database a [public TCP port](/docs/tcp-ports) under **Networking**, open only to the addresses you list. Anyone who can reach the port still needs the password.

## A copy of its data

```bash
alf db dump                    # into postgres-2026-10-20-1430.sql, here
alf db restore seed.sql        # a .sql file into it
```

`dump` runs `pg_dump` (or `mysqldump`) in the database's own container and writes what it prints to a file on your machine, so nothing needs installing. The file loads into a database of your own: `psql -d myapp_dev -f postgres-….sql`, or `mysql myapp_dev < mysql-….sql`. It's made with `--clean`, so loading it replaces the tables it has.

`restore` feeds a `.sql` file to the database's own client (`psql`, `mysql`) the same way, and stops at the first error. It says what it's about to do and asks first, then takes a [snapshot](/docs/backups) of the database, so what it changes can be undone (`--no-snapshot` doesn't). Both work for Postgres and MySQL (and MariaDB); Redis keeps no SQL, and its snapshots are its copies.

For MongoDB they use `mongodump` and `mongorestore`, and the file is a MongoDB archive (`mongodb-….archive`) rather than SQL: `mongorestore --archive=mongodb-….archive` loads it into a MongoDB of your own, and `alf db restore` replaces each collection the archive has.
