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