diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 3b71f9b39..1d7e11f8d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -110,6 +110,8 @@ When adding a new page, you need to include it in the [`mkdocs.yml`](mkdocs.yml)
If you don't use Conda, you can read the `docs/environment.yml` to see which dependencies are required and `pip install` them manually. It's advisable to do this in a virtual environment, which you can create with something like `python3 -m venv /path-to/store-the-venv`. You can then call `/path-to/store-the-venv/bin/pip`, `/path-to/store-the-venv/bin/mkdocs` etc.
+In order to upgrade dependencies, use `conda update --update-all` in the activated environment. You can then update the `environment.yml` with `conda env export --from-history -f ./docs/environment.yml`, though you'll need to fix the `channels`. Beware that `conda env export` will also drop the `pip` dependencies, so make sure to add those back.
+
## Development
### Golang forking quirks
diff --git a/docs/advanced/caching/api.md b/docs/advanced/caching/api.md
index 89df55a09..f8ec789ce 100644
--- a/docs/advanced/caching/api.md
+++ b/docs/advanced/caching/api.md
@@ -19,68 +19,68 @@ Many implementations will regularly request the public key for a user in order t
## Configuration snippets
-### nginx
+=== "nginx"
-For nginx, you'll need to start by configuring a cache zone. The cache zone must be created in the `http` section, not within `server` or `location`.
+ For nginx, you'll need to start by configuring a cache zone. The cache zone must be created in the `http` section, not within `server` or `location`.
-```nginx
-http {
- ...
- proxy_cache_path /var/cache/nginx keys_zone=gotosocial_ap_public_responses:10m inactive=1w;
-}
-```
+ ```nginx
+ http {
+ ...
+ proxy_cache_path /var/cache/nginx keys_zone=gotosocial_ap_public_responses:10m inactive=1w;
+ }
+ ```
-This configures a cache of 10MB whose entries will be kept up to one week if they're not accessed.
+ This configures a cache of 10MB whose entries will be kept up to one week if they're not accessed.
-The zone is named `gotosocial_ap_public_responses` but you can name it whatever you want. 10MB is a lot of cache keys; you can probably use a smaller value on small instances.
+ The zone is named `gotosocial_ap_public_responses` but you can name it whatever you want. 10MB is a lot of cache keys; you can probably use a smaller value on small instances.
-Second, we need to update our GoToSocial nginx configuration to actually use the cache for the endpoints we want to cache.
+ Second, we need to update our GoToSocial nginx configuration to actually use the cache for the endpoints we want to cache.
-```nginx
-server {
- server_name social.example.org;
-
- location ~ /.well-known/(webfinger|host-meta)$ {
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header X-Forwarded-Proto $scheme;
+ ```nginx
+ server {
+ server_name social.example.org;
+
+ location ~ /.well-known/(webfinger|host-meta)$ {
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_set_header X-Forwarded-Proto $scheme;
- proxy_cache gotosocial_ap_public_responses;
- proxy_cache_background_update on;
- proxy_cache_key $scheme://$host$uri$is_args$query_string;
- proxy_cache_valid 200 10m;
- proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
- proxy_cache_lock on;
- add_header X-Cache-Status $upstream_cache_status;
+ proxy_cache gotosocial_ap_public_responses;
+ proxy_cache_background_update on;
+ proxy_cache_key $scheme://$host$uri$is_args$query_string;
+ proxy_cache_valid 200 10m;
+ proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
+ proxy_cache_lock on;
+ add_header X-Cache-Status $upstream_cache_status;
- proxy_pass http://localhost:8080;
- }
+ proxy_pass http://localhost:8080;
+ }
- location ~ ^\/users\/(?:[a-z0-9_\.]+)\/main-key$ {
- proxy_set_header Host $host;
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header X-Forwarded-Proto $scheme;
+ location ~ ^\/users\/(?:[a-z0-9_\.]+)\/main-key$ {
+ proxy_set_header Host $host;
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_set_header X-Forwarded-Proto $scheme;
- proxy_cache gotosocial_ap_public_responses;
- proxy_cache_background_update on;
- proxy_cache_key $scheme://$host$uri;
- proxy_cache_valid 200 604800s;
- proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
- proxy_cache_lock on;
- add_header X-Cache-Status $upstream_cache_status;
+ proxy_cache gotosocial_ap_public_responses;
+ proxy_cache_background_update on;
+ proxy_cache_key $scheme://$host$uri;
+ proxy_cache_valid 200 604800s;
+ proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504 http_429;
+ proxy_cache_lock on;
+ add_header X-Cache-Status $upstream_cache_status;
- proxy_pass http://localhost:8080;
- }
-```
+ proxy_pass http://localhost:8080;
+ }
+ ```
-The `proxy_pass` and `proxy_set_header` are mostly the same, but the `proxy_cache*` entries warrant some explanation:
+ The `proxy_pass` and `proxy_set_header` are mostly the same, but the `proxy_cache*` entries warrant some explanation:
-- `proxy_cache gotosocial_ap_public_responses` tells nginx to use the `gotosocial_ap_public_responses` cache zone we previously created. If you named it something else, you should change this value
-- `proxy_cache_background_update on` means nginx will try and refresh a cached resource that's about to expire in the background, to ensure it has a current copy on disk
-- `proxy_cache_key` is configured in such a way that it takes the query string into account for caching. So a request for `.well-known/webfinger?acct=user1@example.org` and `.well-known/webfinger?acct=user2@example.org` are not seen as the same.
-- `proxy_cache_valid 200 10m;` means we only cache 200 responses from GTS and for 10 minutes. You can add additional lines of these, like `proxy_cache_valid 404 1m;` to cache 404 responses for 1 minute
-- `proxy_cache_use_stale` tells nginx it's allowed to use a stale cache entry (so older than 10 minutes) in certain cases
-- `proxy_cache_lock on` means that if a resource is not cached and there's multiple concurrent requests for them, the queries will be queued up so that only one request goes through and the rest is then answered from cache
-- `add_header X-Cache-Status $upstream_cache_status` will add an `X-Cache-Status` header to the response so you can check if things are getting cached. You can remove this.
+ - `proxy_cache gotosocial_ap_public_responses` tells nginx to use the `gotosocial_ap_public_responses` cache zone we previously created. If you named it something else, you should change this value
+ - `proxy_cache_background_update on` means nginx will try and refresh a cached resource that's about to expire in the background, to ensure it has a current copy on disk
+ - `proxy_cache_key` is configured in such a way that it takes the query string into account for caching. So a request for `.well-known/webfinger?acct=user1@example.org` and `.well-known/webfinger?acct=user2@example.org` are not seen as the same.
+ - `proxy_cache_valid 200 10m;` means we only cache 200 responses from GTS and for 10 minutes. You can add additional lines of these, like `proxy_cache_valid 404 1m;` to cache 404 responses for 1 minute
+ - `proxy_cache_use_stale` tells nginx it's allowed to use a stale cache entry (so older than 10 minutes) in certain cases
+ - `proxy_cache_lock on` means that if a resource is not cached and there's multiple concurrent requests for them, the queries will be queued up so that only one request goes through and the rest is then answered from cache
+ - `add_header X-Cache-Status $upstream_cache_status` will add an `X-Cache-Status` header to the response so you can check if things are getting cached. You can remove this.
-The provided configuration will serve a stale response in case there's an error proxying to GoToSocial, if our connection to GoToSocial times out, if GoToSocial returns a `5xx` status code or if GoToSocial returns 429 (Too Many Requests). The `updating` value says that we're allowed to serve a stale entry if nginx is currently in the process of refreshing its cache. Because we configured `inactive=1w` in the `proxy_cache_path` directive, nginx may serve a response up to one week old if the conditions in `proxy_cache_use_stale` are met.
+ The provided configuration will serve a stale response in case there's an error proxying to GoToSocial, if our connection to GoToSocial times out, if GoToSocial returns a `5xx` status code or if GoToSocial returns 429 (Too Many Requests). The `updating` value says that we're allowed to serve a stale entry if nginx is currently in the process of refreshing its cache. Because we configured `inactive=1w` in the `proxy_cache_path` directive, nginx may serve a response up to one week old if the conditions in `proxy_cache_use_stale` are met.
diff --git a/docs/advanced/caching/assets-media.md b/docs/advanced/caching/assets-media.md
index 4ba8e4ae9..e2b67f831 100644
--- a/docs/advanced/caching/assets-media.md
+++ b/docs/advanced/caching/assets-media.md
@@ -20,20 +20,18 @@ The filesystem location of `/assets` is defined by the [`web-asset-base-dir`](..
## Configuration
-### Apache 2.4
+=== "apache2"
-This is intended to behave identical to the nginx section below.
+ The `Cache-Control` header is manually set to merge the values
+ from the configuration and the `expires` directive to avoid
+ breakage from having two header lines. `Header set` defaults
+ to ` onsuccess`, so it is also not added to error responses.
-The `Cache-Control` header is manually set to merge the values
-from the configuration and the `expires` directive to avoid
-breakage from having two header lines. `Header set` defaults
-to ` onsuccess`, so it is also not added to error responses.
+ Assuming your GtS installation is rooted in `/opt/GtS` with a
+ `storage` subdirectory, and the webserver has been given access,
+ add the following section to the vhost:
-Assuming your GtS installation is rooted in `/opt/GtS` with a
-`storage` subdirectory, and the webserver has been given access,
-add the following section to the vhost:
-
-```
+ ```apacheconf
Options None
AllowOverride None
@@ -54,11 +52,11 @@ add the following section to the vhost:
RewriteCond "/opt/GtS/storage/$1" -f
RewriteRule "^/fileserver/(.*)$" "/opt/GtS/storage/$1" [L]
-```
+ ```
-The trick here is that, in an Apache 2-based reverse proxy setup…
+ The trick here is that, in an Apache 2-based reverse proxy setup…
-```
+ ```apacheconf
RewriteEngine On
RewriteCond %{HTTP:Upgrade} websocket [NC]
@@ -73,71 +71,71 @@ The trick here is that, in an Apache 2-based reverse proxy setup…
ProxyPass http://127.0.0.1:8980/
ProxyPassReverse http://127.0.0.1:8980/
-```
+ ```
-… everything is proxied by default, the `RewriteRule` bypasses
-the proxy (by specifying a filesystem path to redirect to) for
-specific URL præficēs and the `RewriteCond` ensures to only
-disable the `/fileserver/` proxy if the file is, indeed, present.
+ … everything is proxied by default, the `RewriteRule` bypasses
+ the proxy (by specifying a filesystem path to redirect to) for
+ specific URL præficēs and the `RewriteCond` ensures to only
+ disable the `/fileserver/` proxy if the file is, indeed, present.
-Also run the following commands (assuming a Debian-like setup)
-to enable the modules used:
+ Also run the following commands (assuming a Debian-like setup)
+ to enable the modules used:
-```
-$ sudo a2enmod expires
-$ sudo a2enmod headers
-$ sudo a2enmod rewrite
-```
+ ```
+ $ sudo a2enmod expires
+ $ sudo a2enmod headers
+ $ sudo a2enmod rewrite
+ ```
-Then (after a configtest), restart Apache.
+ Then (after a configtest), restart Apache.
-### nginx
+=== "nginx"
-Here's an example of the three location blocks you'll need to add to your existing configuration in nginx:
+ Here's an example of the three location blocks you'll need to add to your existing configuration in nginx:
-```nginx
-server {
- server_name social.example.org;
+ ```nginx
+ server {
+ server_name social.example.org;
- location /assets/ {
- alias web-asset-base-dir/;
- autoindex off;
- expires 5m;
- add_header Cache-Control "public";
- }
+ location /assets/ {
+ alias web-asset-base-dir/;
+ autoindex off;
+ expires 5m;
+ add_header Cache-Control "public";
+ }
- location @fileserver {
- proxy_pass http://localhost:8080;
- proxy_set_header Host $host;
- proxy_set_header Upgrade $http_upgrade;
- proxy_set_header Connection "upgrade";
- proxy_set_header X-Forwarded-For $remote_addr;
- proxy_set_header X-Forwarded-Proto $scheme;
- }
+ location @fileserver {
+ proxy_pass http://localhost:8080;
+ proxy_set_header Host $host;
+ proxy_set_header Upgrade $http_upgrade;
+ proxy_set_header Connection "upgrade";
+ proxy_set_header X-Forwarded-For $remote_addr;
+ proxy_set_header X-Forwarded-Proto $scheme;
+ }
- location /fileserver/ {
- alias storage-local-base-path/;
- autoindex off;
- expires 1w;
- add_header Cache-Control "private, immutable";
- try_files $uri @fileserver;
- }
-}
-```
+ location /fileserver/ {
+ alias storage-local-base-path/;
+ autoindex off;
+ expires 1w;
+ add_header Cache-Control "private, immutable";
+ try_files $uri @fileserver;
+ }
+ }
+ ```
-The `/fileserver` location is a bit special. When we fail to fetch the media from disk, we want to proxy the request on to GoToSocial so it can try and fetch it. The `try_files` directive can't take a `proxy_pass` itself so instead we created the named `@fileserver` location that we pass in last to `try_files`.
+ The `/fileserver` location is a bit special. When we fail to fetch the media from disk, we want to proxy the request on to GoToSocial so it can try and fetch it. The `try_files` directive can't take a `proxy_pass` itself so instead we created the named `@fileserver` location that we pass in last to `try_files`.
-!!! bug "Trailing slashes"
- The trailing slashes in the `location` directives and the `alias` are significant, do not remove those.
+ !!! bug "Trailing slashes"
+ The trailing slashes in the `location` directives and the `alias` are significant, do not remove those.
-The `expires` directive adds the necessary headers to inform the client how long it may cache the resource:
+ The `expires` directive adds the necessary headers to inform the client how long it may cache the resource:
-* For assets, which may change on each release, 5 minutes is used in this example
-* For attachments, which should never change once they're created, we currently use one week
+ * For assets, which may change on each release, 5 minutes is used in this example
+ * For attachments, which should never change once they're created, we currently use one week
-For other options, see the nginx documentation on the [`expires` directive](https://nginx.org/en/docs/http/ngx_http_headers_module.html#expires).
+ For other options, see the nginx documentation on the [`expires` directive](https://nginx.org/en/docs/http/ngx_http_headers_module.html#expires).
-Nginx does not add cache headers to 4xx or 5xx response codes so a failure to fetch an asset won't get cached by clients. The `autoindex off` directive tells nginx to not serve a directory listing. This should be the default but it doesn't hurt to be explicit. The added `add_header` lines set additional options for the `Cache-Control` header:
+ Nginx does not add cache headers to 4xx or 5xx response codes so a failure to fetch an asset won't get cached by clients. The `autoindex off` directive tells nginx to not serve a directory listing. This should be the default but it doesn't hurt to be explicit. The added `add_header` lines set additional options for the `Cache-Control` header:
-* `public` is used to indicate that anyone may cache this resource
-* `immutable` is used to indicate this resource will never change while it is fresh (it's before the end of the expires) allowing clients to forgo conditional requests to revalidate the resource during that timespan.
+ * `public` is used to indicate that anyone may cache this resource
+ * `immutable` is used to indicate this resource will never change while it is fresh (it's before the end of the expires) allowing clients to forgo conditional requests to revalidate the resource during that timespan.
diff --git a/docs/environment.yml b/docs/environment.yml
index b7ba5fe14..9aace2d4e 100644
--- a/docs/environment.yml
+++ b/docs/environment.yml
@@ -3,12 +3,12 @@ channels:
- conda-forge
- nodefaults
dependencies:
- - python=3.11.3=h2755cc3_0_cpython
- - pip=23.1.2=pyhd8ed1ab_0
- - mkdocs=1.4.3=pyhd8ed1ab_0
- - mkdocs-material=9.1.9=pyhd8ed1ab_0
- - mkdocs-material-extensions=1.1.1=pyhd8ed1ab_0
- - pillow=9.5.0=py311h573f0d3_0
- - cairosvg=2.6.0=pyhd8ed1ab_0
+ - cairosvg==2.7.1
+ - mkdocs-material-extensions==1.3.1
+ - mkdocs-material==9.5.8
+ - mkdocs==1.5.3
+ - pillow==10.0.0
+ - pip==23.3.1
+ - python==3.11.3=h2755cc3_0_cpython
- pip:
- - mkdocs-swagger-ui-tag==0.6.1
+ - mkdocs-swagger-ui-tag==0.6.8
diff --git a/docs/getting_started/reverse_proxy/apache-httpd.md b/docs/getting_started/reverse_proxy/apache-httpd.md
index 29af32734..e30d98615 100644
--- a/docs/getting_started/reverse_proxy/apache-httpd.md
+++ b/docs/getting_started/reverse_proxy/apache-httpd.md
@@ -64,55 +64,55 @@ In the above `sudoedit` command, replace `example.com` with the hostname of your
The file you're about to create should look a bit like this:
-```apache
-MDomain example.com auto
-MDCertificateAgreement accepted
+=== "2.4.47+"
+ ```apache
+ MDomain example.com auto
+ MDCertificateAgreement accepted
-
- ServerName example.com
-
+
+ ServerName example.com
+
-
- ServerName example.com
+
+ ServerName example.com
- RewriteEngine On
- RewriteCond %{HTTP:Upgrade} websocket [NC]
- RewriteCond %{HTTP:Connection} upgrade [NC]
- # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
- RewriteRule ^/?(.*) "ws://127.0.0.1:8080/$1" [P,L]
+ SSLEngine On
+ ProxyPreserveHost On
+ # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
+ ProxyPass / http://127.0.0.1:8080/ upgrade=websocket
+ ProxyPassReverse / http://127.0.0.1:8080/
- SSLEngine On
- ProxyPreserveHost On
- # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
- ProxyPass / http://127.0.0.1:8080/
- ProxyPassReverse / http://127.0.0.1:8080/
+ RequestHeader set "X-Forwarded-Proto" expr=https
+
+ ```
- RequestHeader set "X-Forwarded-Proto" expr=https
-
-```
+=== "older versions"
+ ```apache
+ MDomain example.com auto
+ MDCertificateAgreement accepted
-or, if you have [Apache httpd 2.4.47+](https://httpd.apache.org/docs/2.4/mod/mod_proxy.html#protoupgrade), you can get rid of both `mod_rewrite` and `mod_proxy_wstunnel` and simplify the whole config to:
+
+ ServerName example.com
+
-```apache
-MDomain example.com auto
-MDCertificateAgreement accepted
+
+ ServerName example.com
-
- ServerName example.com
-
+ RewriteEngine On
+ RewriteCond %{HTTP:Upgrade} websocket [NC]
+ RewriteCond %{HTTP:Connection} upgrade [NC]
+ # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
+ RewriteRule ^/?(.*) "ws://127.0.0.1:8080/$1" [P,L]
-
- ServerName example.com
+ SSLEngine On
+ ProxyPreserveHost On
+ # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
+ ProxyPass / http://127.0.0.1:8080/
+ ProxyPassReverse / http://127.0.0.1:8080/
- SSLEngine On
- ProxyPreserveHost On
- # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
- ProxyPass / http://127.0.0.1:8080/ upgrade=websocket
- ProxyPassReverse / http://127.0.0.1:8080/
-
- RequestHeader set "X-Forwarded-Proto" expr=https
-
-```
+ RequestHeader set "X-Forwarded-Proto" expr=https
+
+ ```
Again, replace occurrences of `example.com` in the above config file with the hostname of your GtS server. If your domain name is `gotosocial.example.com`, then `gotosocial.example.com` would be the correct value.
@@ -182,23 +182,36 @@ In the above `sudoedit` command, replace `example.com` with the hostname of your
The file you're about to create should look initially for both 80 (required) and 443 ports (optional) a bit like this:
-```apache
-
- ServerName example.com
+=== "2.4.47+"
+ ```apache
+
+ ServerName example.com
- RewriteEngine On
- RewriteCond %{HTTP:Upgrade} websocket [NC]
- RewriteCond %{HTTP:Connection} upgrade [NC]
- # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
- RewriteRule ^/?(.*) "ws://127.0.0.1:8080/$1" [P,L]
+ ProxyPreserveHost On
+ # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
+ ProxyPass / http://127.0.0.1:8080/ upgrade=websocket
+ ProxyPassReverse / http://127.0.0.1:8080/
+
+ ```
- ProxyPreserveHost On
- # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
- ProxyPass / http://127.0.0.1:8080/
- ProxyPassReverse / http://127.0.0.1:8080/
+=== "older versions"
+ ```apache
+
+ ServerName example.com
-
-```
+ RewriteEngine On
+ RewriteCond %{HTTP:Upgrade} websocket [NC]
+ RewriteCond %{HTTP:Connection} upgrade [NC]
+ # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
+ RewriteRule ^/?(.*) "ws://127.0.0.1:8080/$1" [P,L]
+
+ ProxyPreserveHost On
+ # set to 127.0.0.1 instead of localhost to work around https://stackoverflow.com/a/52550758
+ ProxyPass / http://127.0.0.1:8080/
+ ProxyPassReverse / http://127.0.0.1:8080/
+
+
+ ```
Again, replace occurrences of `example.com` in the above config file with the hostname of your GtS server. If your domain name is `gotosocial.example.com`, then `gotosocial.example.com` would be the correct value.
diff --git a/mkdocs.yml b/mkdocs.yml
index deb9a4c6e..d9b87b818 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -25,9 +25,9 @@ plugins:
lang: en
- social:
cards: true
- cards_color:
- fill: "#fd6a00"
- text: "#fafaff"
+ cards_layout_options:
+ background_color: "#fd6a00"
+ color: "#fafaff"
- swagger-ui-tag:
supportedSubmitMethods: []
syntaxHighlightTheme: obsidian
@@ -37,13 +37,23 @@ extra_css:
markdown_extensions:
- admonition
+ - pymdownx.details
- pymdownx.highlight:
anchor_linenums: true
line_spans: __span
+ linenums_style: pymdownx-inline
pygments_lang_class: true
+ linenums: true
- pymdownx.inlinehilite
- pymdownx.snippets
- pymdownx.superfences
+ - pymdownx.smartsymbols
+ - pymdownx.caret
+ - pymdownx.keys
+ - pymdownx.mark
+ - pymdownx.tilde
+ - pymdownx.tabbed:
+ alternate_style: true
nav:
- "Home": "index.md"