# Database Hub

Production-ready **PostgreSQL**, **Redis**, **MongoDB** and **RabbitMQ** with
administration GUIs, all published through the Traefik proxy. Hostnames are
derived from `DOMAIN` in `.env` — the live HTML page renders this Markdown
guide and injects the current domain into every link.

## Administration UIs

| Service    | GUI           | URL                                             |
|------------|---------------|-------------------------------------------------|
| PostgreSQL | pgAdmin 4     | `https://pgadmin.<DOMAIN>/`                     |
| Redis      | RedisInsight  | `https://redisinsight.<DOMAIN>/`                |
| MongoDB    | mongo-express | `https://mongo-express.<DOMAIN>/`               |
| RabbitMQ   | Management UI | `https://rabbitmq.<DOMAIN>/` (built into broker)|
| Docs       | this page     | `https://db.<DOMAIN>/`                          |

Every UI has its own login; credentials are generated and stored in
`deployments/databases/.env`.

## How the stack is wired

- Each database runs on its **own dedicated external network**: `postgres-net`,
  `redis-net`, `mongodb-net`, `rabbitmq-net`.
- GUIs join their database's network **and** the shared external `proxy`
  network, so Traefik publishes them at `https://<name>.<DOMAIN>`.
- **No database port is exposed on the host** — databases are reachable only
  from containers attached to their dedicated network.
- Data persists in named volumes (`postgres_data`, `redis_data`,
  `mongodb_data`, `rabbitmq_data`).

## Internal endpoints

| Database | Network         | Host / port                      |
|----------|-----------------|----------------------------------|
| PostgreSQL | `postgres-net`   | `postgres:5432`                  |
| Redis      | `redis-net`      | `redis:6379`                     |
| MongoDB    | `mongodb-net`    | `mongodb:27017` (authSource admin)|
| RabbitMQ   | `rabbitmq-net`   | `rabbitmq:5672` · mgmt `:15672`  |

## Connecting from an app container

Attach your service to the required external network:

```yaml
services:
  myapp:
    networks:
      - postgres-net

networks:
  postgres-net:
    name: postgres-net
    external: true
```

Connection strings (values come from `.env`):

```text
postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@postgres:5432/${POSTGRES_DB}
redis://:${REDIS_PASSWORD}@redis:6379/0
mongodb://${MONGO_ROOT_USERNAME}:${MONGO_ROOT_PASSWORD}@mongodb:27017/?authSource=admin
amqp://${RABBITMQ_USER}:${RABBITMQ_PASSWORD}@rabbitmq:5672/
```

## Backups

Run from `deployments/databases` after sourcing `.env`:

```bash
set -a; source .env; set +a

# PostgreSQL
docker compose exec -T postgres pg_dump -U "$POSTGRES_USER" "$POSTGRES_DB" > backup-$(date +%F).sql

# Redis (fresh RDB snapshot in the redis_data volume)
docker compose exec redis redis-cli -a "$REDIS_PASSWORD" --no-auth-warning BGSAVE

# MongoDB
docker compose exec -T mongodb mongodump --username "$MONGO_ROOT_USERNAME" \
  --password "$MONGO_ROOT_PASSWORD" --authenticationDatabase admin --archive > backup-$(date +%F).archive

# RabbitMQ definitions (vhosts / exchanges / queues / users)
docker compose exec rabbitmq rabbitmqadmin export /tmp/defs.json \
  -u "$RABBITMQ_USER" -p "$RABBITMQ_PASSWORD" -H rabbitmq
docker cp rabbitmq:/tmp/defs.json ./defs-$(date +%F).json
```

## Credentials & security

- Passwords live only in `deployments/databases/.env` (ignored by git).
- Rotate by editing `.env` then `docker compose up -d`.
- GUIs are HTTPS + own login; add a Traefik `basicauth` middleware to restrict
  further.
- Point `db`, `pgadmin`, `redisinsight`, `mongo-express`, `rabbitmq`
  subdomains at this host (or use a wildcard `*.<DOMAIN>` record).
  Let's Encrypt certificates are issued automatically on first request.
