WIP
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
# Hosting your web apps on mars
|
||||
|
||||
You can run web apps as containers and publish them on the home network at
|
||||
`http://mars.sol/<name>/`, without anyone changing mars's configuration.
|
||||
Everything below takes effect immediately — no restart, no redeploy.
|
||||
|
||||
This file is mounted read-only and is rewritten on every restart. Save what
|
||||
you need from it to your memory.
|
||||
|
||||
## How it fits together
|
||||
|
||||
- `podman` in your shell does not run containers next to you. It talks,
|
||||
through `$CONTAINER_HOST`, to a separate unprivileged account on mars
|
||||
(`luna-apps`). Containers there keep running when you restart, and come
|
||||
back after mars reboots if they were started with `--restart=always`.
|
||||
- Caddy on mars routes `http://mars.sol/<name>/` to the port you name in
|
||||
`/opt/data/sites/<name>.json`. A service on mars checks that file and
|
||||
writes the outcome to `/opt/data/sites-status.txt`.
|
||||
|
||||
## Publish an app
|
||||
|
||||
1. Put the source under `/opt/data/apps/<name>/` with a `Containerfile` (or
|
||||
`Dockerfile`), and build it. The directory is uploaded, so this works from
|
||||
where you are:
|
||||
|
||||
podman build -t localhost/<name> /opt/data/apps/<name>
|
||||
|
||||
2. Run it. Publish its port on `127.0.0.1` only, using a host port between
|
||||
@portMin@ and @portMax@ that no other app uses (`podman ps` shows the
|
||||
taken ones):
|
||||
|
||||
podman run -d --name <name> --restart=always \
|
||||
-p 127.0.0.1:20001:8080 localhost/<name>
|
||||
|
||||
3. Register it:
|
||||
|
||||
echo '{"port": 20001}' > /opt/data/sites/<name>.json
|
||||
|
||||
4. Check that it took, then fetch it:
|
||||
|
||||
cat /opt/data/sites-status.txt
|
||||
curl -si http://127.0.0.1/<name>/
|
||||
|
||||
It is now at `http://mars.sol/<name>/` for anyone on the home network.
|
||||
|
||||
## Rules the registry enforces
|
||||
|
||||
- `<name>` is lowercase letters, digits and `-`, starts with a letter or
|
||||
digit, at most 32 characters. The file is `/opt/data/sites/<name>.json`.
|
||||
- The file holds exactly one JSON object, and only `port` is read.
|
||||
- `port` is an integer from @portMin@ to @portMax@. Anything else is rejected
|
||||
(that includes everything else already running on mars).
|
||||
- A rejected entry never affects the others. `sites-status.txt` says why.
|
||||
- If `sites-status.txt` starts with `ERROR`, that is a fault on mars's side,
|
||||
not in your entry — tell darman.
|
||||
|
||||
## Writing apps that work under /<name>/
|
||||
|
||||
Caddy strips `/<name>` before the request reaches your app, so the app itself
|
||||
sees `/`, `/style.css`, `/api/items`. The browser, however, is at
|
||||
`http://mars.sol/<name>/`, so every link, asset URL and fetch() in the page must
|
||||
keep that prefix:
|
||||
|
||||
- Prefer relative URLs: `style.css`, `./api/items` — not `/style.css`.
|
||||
- Or set the framework's public base URL to `/<name>/` (e.g. Vite's `base`).
|
||||
Avoid settings that ALSO expect the prefix on incoming requests (Next.js
|
||||
`basePath`); the prefix has already been removed by then.
|
||||
- The original prefix arrives in the `X-Forwarded-Prefix` header.
|
||||
- `http://mars.sol/<name>` redirects to `http://mars.sol/<name>/`.
|
||||
|
||||
## Files and data
|
||||
|
||||
- `-v /opt/data/...:/somewhere` does not work: those paths exist only inside
|
||||
your container, and `luna-apps` cannot see your files. Copy code into the
|
||||
image in the `Containerfile`.
|
||||
- Keep an app's state in a named volume: `-v <name>-data:/data`.
|
||||
- Pulling public images works (`podman pull docker.io/library/nginx`).
|
||||
- Do not copy tokens or anything else from `/opt/data` into an app. The apps
|
||||
cannot read your files; keep it that way.
|
||||
|
||||
## Update, inspect, remove
|
||||
|
||||
- Update: rebuild, `podman rm -f <name>`, run it again on the same port. The
|
||||
JSON file stays as it is.
|
||||
- Inspect: `podman ps -a`, `podman logs <name>`, `cat /opt/data/sites-status.txt`.
|
||||
- Remove: `rm /opt/data/sites/<name>.json`, then `podman rm -f <name>`, and
|
||||
optionally `podman rmi localhost/<name>` and `podman volume rm <name>-data`.
|
||||
|
||||
## Limits
|
||||
|
||||
- Home network only: plain `http://`, not reachable from the internet, not on
|
||||
mgaction.town.
|
||||
- There is no login in front of these apps. Anyone on the home network can
|
||||
use them, so do not publish anything that would be a problem to expose there.
|
||||
Reference in New Issue
Block a user