114 lines
3.7 KiB
Markdown
114 lines
3.7 KiB
Markdown
<!-- README.md -->
|
|
|
|
# rs_maps — build and deploy
|
|
|
|
Single Rust binary + one rootless Postgres container. See `DESIGN.md` for the reasoning.
|
|
|
|
> **This code has not been compiled.** It was written without a Rust toolchain available,
|
|
> so treat the first `cargo build` as the real review. Expect to fix a handful of import
|
|
> paths and trait-bound details, not the structure.
|
|
|
|
## 1. Refresh dependency versions
|
|
|
|
`Cargo.toml` has plausible versions, but pin them properly:
|
|
|
|
```bash
|
|
cargo add axum -F multipart,macros
|
|
cargo add tokio -F full
|
|
cargo add sqlx --no-default-features -F runtime-tokio,tls-rustls,postgres,uuid,time,macros,migrate
|
|
cargo add tower-sessions
|
|
cargo add tower-sessions-sqlx-store -F postgres
|
|
cargo add lettre --no-default-features -F tokio1-rustls,smtp-transport,builder,pool
|
|
cargo add rust-embed -F debug-embed
|
|
cargo build
|
|
```
|
|
|
|
Two version-sensitive spots to check first if it doesn't compile:
|
|
|
|
- **`tower-sessions` / `tower-sessions-sqlx-store` must be a matching pair.** The store crate
|
|
tracks the main crate's version and they break in lockstep. Check the store's own README for
|
|
which `tower-sessions` it expects.
|
|
- **axum 0.8 changed path params from `:id` to `{id}`.** This code uses `{id}`. If you end up on
|
|
0.7 for some reason, they all need changing back.
|
|
|
|
## 2. Database
|
|
|
|
```bash
|
|
podman secret create mapserver-db-password - # type the password, then Ctrl-D
|
|
mkdir -p ~/.config/containers/systemd
|
|
cp deploy/postgres.container ~/.config/containers/systemd/
|
|
systemctl --user daemon-reload
|
|
systemctl --user start postgres
|
|
```
|
|
|
|
Migrations run automatically on startup — both `./migrations` and the session store's own.
|
|
|
|
## 3. Config
|
|
|
|
```bash
|
|
mkdir -p ~/.config/mapserver ~/gpx
|
|
cp .env.example ~/.config/mapserver/.env
|
|
chmod 600 ~/.config/mapserver/.env
|
|
$EDITOR ~/.config/mapserver/.env
|
|
```
|
|
|
|
Must change: `DATABASE_URL`, `REG_TOKEN`, `PUBLIC_URL`, `BASE_PATH`, `GPX_DIR`.
|
|
|
|
Leave `SMTP_HOST` empty for now — reset links get logged instead of emailed, and the whole flow
|
|
is testable without a provider.
|
|
|
|
## 4. Run
|
|
|
|
```bash
|
|
cargo build --release
|
|
mkdir -p ~/.local/bin && cp target/release/mapserver ~/.local/bin/
|
|
cp deploy/mapserver.service ~/.config/systemd/user/
|
|
systemctl --user daemon-reload
|
|
systemctl --user enable --now mapserver
|
|
loginctl enable-linger "$USER" # or nothing starts at boot
|
|
journalctl --user -u mapserver -f
|
|
```
|
|
|
|
## 5. nginx
|
|
|
|
Merge `deploy/nginx-snippet.conf` into your existing TLS server block, then
|
|
`nginx -t && systemctl reload nginx`.
|
|
|
|
## 6. First account
|
|
|
|
Visit `https://your-domain/maps/`, choose "Create an account", and enter the `REG_TOKEN` from
|
|
`.env`.
|
|
|
|
---
|
|
|
|
## Testing the reset flow with real mail
|
|
|
|
`mailpit` gives you a local SMTP server and a web inbox with no signup:
|
|
|
|
```
|
|
SMTP_HOST=127.0.0.1
|
|
SMTP_PORT=1025
|
|
SMTP_TLS=none
|
|
SMTP_USERNAME=
|
|
SMTP_PASSWORD=
|
|
```
|
|
|
|
When you move to a real provider: use an app-specific password (any account with 2FA will reject
|
|
the normal one over SMTP), check SMTP isn't disabled by default on the account, and make sure
|
|
`SMTP_FROM` is an address that account may send as.
|
|
|
|
## Things worth checking by hand after the first deploy
|
|
|
|
- `curl -i https://your-domain/maps/api/gpx/file/../../etc/passwd` → 400 or 404, never a file
|
|
- Live location works (needs HTTPS; it silently fails on plain HTTP)
|
|
- Session survives `systemctl --user restart mapserver`
|
|
- Upload a >2 MB GPX — catches both the axum and nginx body limits at once
|
|
- Upload the same filename twice — second one should come back as `name-1.gpx`
|
|
- Reboot the server, confirm both units come back (this is what `enable-linger` is for)
|
|
|
|
## Unit tests
|
|
|
|
cargo test
|
|
|
|
No database needed — every test is pure: base-path normalisation, bbox parsing,
|
|
GPX filename safety, and the rate-limiter window.
|