SETUP.md

v1.5.6
skunky-art/SETUP.md rendered · source · history · blame · raw

128 lines · 6702 bytes · executable

  1# Config
  2
  3SkunkyArt reads `config.json` from the working directory, or the file named
  4with `-c`. The default file is optional: without it the built-in defaults
  5below apply. A file named with `-c` must exist.
  6
  7* `listen` — IP and port to listen on, `ip:port`. Default `127.0.0.1:3003`.
  8* `uri` — Instance URI. Example: `"uri":"/art/"` -> https://skunky.example.com/art/.
  9  Default `/`.
 10* `cache` — On-disk cache for proxied media, avatars and emotes. On by
 11  default. A proxying instance with no cache re-fetches every image from
 12  wixmp on every view, which is the pattern that gets an egress IP blocked.
 13  * `enabled` — boolean, default true.
 14  * `path` — Cache directory, default `cache`. It must be writable by the
 15    user SkunkyArt runs as, and SkunkyArt refuses to start if it is not. The
 16    container image runs as uid 10000, so a bind-mounted cache needs
 17    `sudo chown -R 10000:10000 <dir>` on the host.
 18  * `memcache` — Also keep served media in RAM, on top of the on-disk cache.
 19    Entries are scored by how often they are requested and dropped once they
 20    go a round unused. The cache is bounded only by that scoring, so leave it
 21    off unless you have RAM to spare for your traffic. Default false.
 22  * `lifetime` — How long a cached file is kept, in the time units below.
 23    Default `1w`.
 24  * `max-size` — Cache size cap in megabytes, default 200. When the cache
 25    grows past it, the oldest files are removed until it fits.
 26  * `update-interval` — Seconds between rotation passes, default 1. Each
 27    pass reads the whole cache directory, so raise it on a large cache.
 28* `api-cache` — In-memory cache of DeviantArt API responses. Every page,
 29  feed poll and API call that asks DeviantArt the same question within the
 30  TTL is answered from memory, and concurrent requests for one thing make
 31  one upstream call. On by default; DeviantArt bans egress IPs that ask too
 32  often, so leave it on unless you are debugging.
 33  * `enabled` — boolean, default true.
 34  * `max-size` — Megabytes of response bodies to hold, default 64. Least
 35    recently used entries are dropped past this.
 36  * `ttl` — How long a response is reused, in the time units below. Default
 37    `5i`.
 38  * `stale` — How long past `ttl` a response is kept to be served when
 39    DeviantArt fails or blocks the instance, so a short ban does not take
 40    the daily deviations, popular searches and feeds down. Default `1h`;
 41    `0i` keeps nothing past `ttl`. After a block the instance also leaves
 42    DeviantArt alone for a minute instead of retrying every request.
 43* `rate-limit` — Per-client budget for page, feed and API requests, so one
 44  crawler cannot spend the whole upstream budget. Media, avatars and static
 45  files are not counted. Over budget answers 429 with `Retry-After`.
 46  Behind a reverse proxy the client is taken from the rightmost
 47  `X-Forwarded-For` entry, but only when the connection itself comes from a
 48  loopback or private address; a direct client's header is ignored.
 49  * `per-minute` — Sustained requests per minute per client, default 60.
 50    `0` turns the limit off.
 51  * `burst` — How many requests a client can make at once before the rate
 52    applies, default 20.
 53* `upstream` — How fast the instance itself talks to DeviantArt, whichever
 54  client asked. DeviantArt bans an address that asks too often, so an
 55  instance that gets banned should slow this down before anything else.
 56  * `min-interval-ms` — Minimum gap between two requests to DeviantArt, in
 57    milliseconds. Default 400.
 58  * `max-concurrent` — Requests to DeviantArt in flight at once. Default 2.
 59* `static-path` — Directory of templates, styles and catalogues, read into
 60  memory at startup. Default `static`. Ignored by a binary built with the
 61  `embed` tag.
 62* `download-proxy` — Outbound proxy used when fetching media from DeviantArt's
 63  CDN. Leave empty (`""`) unless you actually run a proxy: if this points at
 64  something that isn't listening, every image 502s while pages still render,
 65  because only media fetches go through it. Inside a container `127.0.0.1` is
 66  the container itself, so a host-side proxy must be addressed by service name
 67  or host IP, not loopback.
 68* `user-agent` — The User-Agent SkunkyArt sends to DeviantArt.
 69* `proxy` — Serve media through this instance instead of linking straight to
 70  DeviantArt's CDN. Required by `cache`; when off, clients fetch images from
 71  wixmp directly. Default true.
 72* `nsfw` — Show mature content. Default false.
 73* `hide-ai` — Omit AI-generated deviations (those flagged `[🤖]`) from all
 74  listings: search, daily deviations, galleries and favourites. Default false.
 75* `theme` — Palette for the interface. `auto` (default) serves the dark theme
 76  and lets a visitor whose system asks for light get the light one, through
 77  `prefers-color-scheme` — no cookie, no query string, no JavaScript. `dark` or
 78  `light` pins one for everybody. An unrecognised value stops startup rather
 79  than quietly falling back.
 80* `language` — Interface language. `auto` (default) reads the browser's own
 81  `Accept-Language` header, which it sends on every request anyway, so nothing
 82  extra is stored or asked for. A language code (`en`, `es`) pins one for
 83  everybody. An unknown code falls back to English rather than refusing to
 84  start, since a missing catalogue is a worse reason to be down than to be in
 85  the wrong language.
 86
 87  Catalogues live in `static/lang/*.json`, keyed by the strings the templates
 88  ask for. `en.json` is the reference and is always complete; a catalogue that
 89  is missing a key shows the English for that one string, so a partial
 90  translation is useful immediately. To add a language, copy `en.json`,
 91  translate it, and name it after the code.
 92
 93# Time units
 94
 95A number followed by one of:
 96
 97* `i` — minutes
 98* `h` — hours
 99* `d` — days
100* `w` — weeks
101* `m` — months (30 days)
102* `y` — years (360 days)
103
104# robots.txt
105
106`/robots.txt` is served automatically. It disallows search, the API, user
107and group pages, media and paginated URLs, and asks for a 10 second crawl
108delay; the index, daily deviations and posts stay crawlable.
109
110# Setting up reverse proxy
111
112Pretty much business as usual, except for the [`X-Forwarded-Proto`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto) header setting.
113
114Nginx example configuration:
115```apache
116server {
117    listen 443 ssl;
118    server_name skunky.example.com;
119
120    # In case of subdomain, use / instead of ((BASE_URL))
121    location ((BASE_URL)) {
122        proxy_set_header X-Forwarded-Proto $scheme;
123        proxy_set_header Host $host;
124        proxy_http_version 1.1;
125        proxy_pass http://((IP)):((PORT));
126    }
127}
128```