document media hosting in readme and usecases
This commit is contained in:
@@ -80,6 +80,9 @@ and verifies the site is live.
|
|||||||
installed. Uses the deploy SSH key from Bitwarden Secrets Manager -- no
|
installed. Uses the deploy SSH key from Bitwarden Secrets Manager -- no
|
||||||
personal server access needed. See USECASES.md for full details.
|
personal server access needed. See USECASES.md for full details.
|
||||||
|
|
||||||
|
`new-app.sh` also creates a Garage media bucket for the domain, allowing
|
||||||
|
media files to be served at `https://www.<domain>/media/`.
|
||||||
|
|
||||||
After the site is live, clone the app repo and customize it:
|
After the site is live, clone the app repo and customize it:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -119,6 +122,47 @@ docker exec garage /garage layout apply --version 1
|
|||||||
This only needs to be done once. If only hantim is reprovisioned, argento
|
This only needs to be done once. If only hantim is reprovisioned, argento
|
||||||
retains the layout and hantim reconnects automatically.
|
retains the layout and hantim reconnects automatically.
|
||||||
|
|
||||||
|
## Media hosting
|
||||||
|
|
||||||
|
Media files (images, videos) are stored in Garage and served via nginx at
|
||||||
|
`/media/` on each domain. This keeps large files out of git repos.
|
||||||
|
|
||||||
|
**Endpoints:**
|
||||||
|
- `s3.hantim.net` — S3 API for uploads (authenticated with `media-key`)
|
||||||
|
- `garage.hantim.net` — Admin API for bucket management
|
||||||
|
- `https://www.<domain>/media/<path>` — public file access
|
||||||
|
|
||||||
|
**Uploading media:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Configure AWS CLI (one-time)
|
||||||
|
aws configure # key ID, secret key from bws, region: garage
|
||||||
|
aws configure set default.endpoint_url https://s3.hantim.net
|
||||||
|
|
||||||
|
# Upload files
|
||||||
|
aws s3 cp photo.jpg s3://example.com/photo.jpg
|
||||||
|
aws s3 sync static/media/ s3://example.com/
|
||||||
|
```
|
||||||
|
|
||||||
|
**Local development:** Store media in `static/media/` (gitignored) so files
|
||||||
|
are accessible at `/media/` when serving locally.
|
||||||
|
|
||||||
|
**Creating buckets manually** (for existing domains without buckets):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Get admin token and media key ID from bws
|
||||||
|
# Create bucket
|
||||||
|
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
||||||
|
-d '{"globalAlias": "example.com"}' https://garage.hantim.net/v2/CreateBucket
|
||||||
|
# Note the bucket ID from the response, then:
|
||||||
|
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
||||||
|
-d '{"bucketId": "BUCKET_ID", "accessKeyId": "MEDIA_KEY_ID", "permissions": {"read": true, "write": true, "owner": false}}' \
|
||||||
|
https://garage.hantim.net/v2/AllowBucketKey
|
||||||
|
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
|
||||||
|
-d '{"websiteAccess": {"enabled": true, "indexDocument": "index.html"}}' \
|
||||||
|
"https://garage.hantim.net/v2/UpdateBucket?id=BUCKET_ID"
|
||||||
|
```
|
||||||
|
|
||||||
## Restoring from backup
|
## Restoring from backup
|
||||||
|
|
||||||
Run the same three commands as provisioning. `bootstrap.sh` is idempotent:
|
Run the same three commands as provisioning. `bootstrap.sh` is idempotent:
|
||||||
@@ -139,6 +183,9 @@ Bitwarden Secrets Manager (project: `hantim`, fetched via `bws` CLI on the serve
|
|||||||
| `hantim-vultr-api-key` | Vultr API key for DNS management | `new-app.sh` |
|
| `hantim-vultr-api-key` | Vultr API key for DNS management | `new-app.sh` |
|
||||||
| `hantim-garage-rpc-secret` | Garage cluster RPC secret | `deploy.sh` |
|
| `hantim-garage-rpc-secret` | Garage cluster RPC secret | `deploy.sh` |
|
||||||
| `hantim-garage-argento-node-id` | Argento's Garage node ID + address | `deploy.sh` |
|
| `hantim-garage-argento-node-id` | Argento's Garage node ID + address | `deploy.sh` |
|
||||||
|
| `hantim-garage-admin-token` | Garage admin API token | `deploy.sh`, `new-app.sh` |
|
||||||
|
| `hantim-garage-media-key-id` | S3 access key ID for media uploads | `new-app.sh`, `aws` CLI |
|
||||||
|
| `hantim-garage-media-secret-key` | S3 secret key for media uploads | `aws` CLI |
|
||||||
|
|
||||||
Machine accounts: `hantim-server` (token at `/etc/bws-token`), `hantim-ci` (reserved).
|
Machine accounts: `hantim-server` (token at `/etc/bws-token`), `hantim-ci` (reserved).
|
||||||
|
|
||||||
|
|||||||
+31
-3
@@ -62,9 +62,10 @@ From your dev machine (single command):
|
|||||||
- `.gitea/workflows/deploy-example.com.yml`
|
- `.gitea/workflows/deploy-example.com.yml`
|
||||||
- `docker/nginx/conf.d/example.com.conf` (HTTP->HTTPS, bare->www, proxy)
|
- `docker/nginx/conf.d/example.com.conf` (HTTP->HTTPS, bare->www, proxy)
|
||||||
7. SSHes to server as deploy user, issues SSL cert via webroot (zero downtime)
|
7. SSHes to server as deploy user, issues SSL cert via webroot (zero downtime)
|
||||||
8. Commits and pushes hantim-server (triggers deploy)
|
8. Creates Garage media bucket via admin API (create, allow media-key, enable website)
|
||||||
9. Triggers initial build of the app repo via Gitea API
|
9. Commits and pushes hantim-server (triggers deploy)
|
||||||
10. Polls `https://www.example.com` until it responds (up to 3 minutes)
|
10. Triggers initial build of the app repo via Gitea API
|
||||||
|
11. Polls `https://www.example.com` until it responds (up to 3 minutes)
|
||||||
|
|
||||||
After the site is live, clone the app repo and customize:
|
After the site is live, clone the app repo and customize:
|
||||||
|
|
||||||
@@ -148,3 +149,30 @@ triggers automatically.
|
|||||||
- Existing certs are skipped
|
- Existing certs are skipped
|
||||||
- Brief nginx downtime (seconds) while certbot checks run
|
- Brief nginx downtime (seconds) while certbot checks run
|
||||||
- Services are restarted
|
- Services are restarted
|
||||||
|
|
||||||
|
## 8. Upload media files
|
||||||
|
|
||||||
|
Media files (images, videos) are stored in Garage and served at `/media/`
|
||||||
|
on each domain.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# One-time setup
|
||||||
|
aws configure # key ID + secret from bws, region: garage
|
||||||
|
aws configure set default.endpoint_url https://s3.hantim.net
|
||||||
|
|
||||||
|
# Upload a single file
|
||||||
|
aws s3 cp photo.jpg s3://example.com/photo.jpg
|
||||||
|
|
||||||
|
# Sync a directory
|
||||||
|
aws s3 sync static/media/ s3://example.com/
|
||||||
|
```
|
||||||
|
|
||||||
|
**What happens:**
|
||||||
|
1. File is uploaded to the Garage S3 API via `s3.hantim.net`
|
||||||
|
2. Garage replicates the file to both nodes (hantim + argento)
|
||||||
|
3. File is accessible at `https://www.example.com/media/photo.jpg`
|
||||||
|
|
||||||
|
**Local development:** Store media in `static/media/` (gitignored). The app's
|
||||||
|
nginx serves these locally, matching the `/media/` path used in production.
|
||||||
|
|
||||||
|
**Reference in HTML:** Use absolute paths like `/media/photo.jpg`.
|
||||||
|
|||||||
Reference in New Issue
Block a user