added rootless docker setup
This commit is contained in:
@@ -145,6 +145,83 @@ docker compose down -v # stop and wipe all data — careful!
|
||||
docker compose up --build -d # rebuild after pulling code changes
|
||||
```
|
||||
|
||||
### Optional: hardened deployment — isolated user + rootless Docker
|
||||
|
||||
Anyone who can run `docker` commands effectively has root on the host (container volume mounts can reach the whole filesystem) — being in the `docker` group is root-equivalent. For a production server, it's worth confining this stack to a dedicated, unprivileged system user running its own **rootless Docker** daemon, instead of using a system-wide install or adding the user to the `docker` group.
|
||||
|
||||
Rootless Docker runs as a completely independent daemon — separate socket (`/run/user/<uid>/docker.sock`) and storage (`~/.local/share/docker` vs. `/var/lib/docker`) — so it coexists fine with an existing system-wide Docker install on the same host. Just make sure `DOCKER_HOST`/`PATH` point at the rootless daemon when operating on this stack, and that the ports you publish in step 4 below aren't already in use elsewhere.
|
||||
|
||||
**1. Create the user and enable lingering** (so its services keep running without an active login session):
|
||||
|
||||
```sh
|
||||
sudo adduser --disabled-password --gecos "" rss-svc
|
||||
sudo loginctl enable-linger rss-svc
|
||||
```
|
||||
|
||||
**2. Install rootless Docker for that user:**
|
||||
|
||||
```sh
|
||||
sudo apt install -y uidmap dbus-user-session
|
||||
sudo machinectl shell rss-svc@
|
||||
curl -fsSL https://get.docker.com/rootless | sh
|
||||
```
|
||||
|
||||
Add to `~/.bashrc` (as `rss-svc`):
|
||||
|
||||
```sh
|
||||
export PATH=/home/rss-svc/bin:$PATH
|
||||
export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock
|
||||
```
|
||||
|
||||
Enable the daemon as a persistent user service, then re-login (or `exec $SHELL`) so the exports above take effect:
|
||||
|
||||
```sh
|
||||
systemctl --user enable docker
|
||||
systemctl --user start docker
|
||||
```
|
||||
|
||||
**3. Deploy the stack as `rss-svc`:**
|
||||
|
||||
```sh
|
||||
git clone <your-repo-url> ~/rss-reader
|
||||
cd ~/rss-reader
|
||||
cp .env.example .env
|
||||
chmod 600 .env
|
||||
```
|
||||
|
||||
Fill in `.env` with strong, unique secrets — `openssl rand -hex 32` is a convenient way to generate `JWT_SECRET`/`POSTGRES_PASSWORD`.
|
||||
|
||||
**4. Bind published ports to localhost only.** The only thing that needs to reach this stack from outside is the reverse proxy below, and it runs on the same host. Edit `docker-compose.yml`:
|
||||
|
||||
```yaml
|
||||
postgres:
|
||||
ports:
|
||||
- "127.0.0.1:5432:5432"
|
||||
backend:
|
||||
ports:
|
||||
- "127.0.0.1:8001:8001"
|
||||
frontend:
|
||||
ports:
|
||||
- "127.0.0.1:8080:80"
|
||||
```
|
||||
|
||||
**5. Bring it up:**
|
||||
|
||||
```sh
|
||||
docker compose up --build -d
|
||||
```
|
||||
|
||||
**6. Firewall** (run as your normal sudo-capable user — not `rss-svc`):
|
||||
|
||||
```sh
|
||||
sudo ufw allow OpenSSH
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
With this in place: only SSH and HTTPS are reachable from the network, the reverse proxy is the sole entry point into the app, the whole stack runs in its own user/container/network namespaces with no elevated privileges, and secrets live in a `chmod 600` `.env` owned by an account that can't do anything else on the system.
|
||||
|
||||
### Optional: Apache reverse proxy (TLS termination)
|
||||
|
||||
If you want to expose the app under a domain with HTTPS, put Apache in front of the `frontend` container (which keeps listening on `localhost:8080`) and let Apache handle TLS. Enable the required modules first:
|
||||
|
||||
Reference in New Issue
Block a user