Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/wikioasis/salt/llms.txt

Use this file to discover all available pages before exploring further.

The nginx state installs and configures Nginx as the web server on all mw* and apps* servers. Rather than maintaining individual per-wiki vhost files, WikiOasis uses a two-part template system: a shared mediawiki-common.conf snippet that contains all location blocks, FastCGI configuration, and security headers, and a mediawiki-vhosts.conf that iterates over nginx:server_blocks to emit one server {} block per set of hostnames. A third template, custom-domains.conf, handles wikis that have been mapped to external domain names, serving ACME challenge tokens alongside the normal MediaWiki config.

What gets installed and configured

Package

Installs the nginx package via apt and removes the default sites-enabled/default vhost.

Snippets directory

Creates /etc/nginx/snippets/ and places mediawiki-common.conf there for inclusion by all server blocks.

MediaWiki vhosts

Writes /etc/nginx/conf.d/mediawiki-vhosts.conf from server_blocks pillar entries.

Custom domains

Writes /etc/nginx/conf.d/custom_domains.conf from nginx:custom_domains pillar entries. Removes legacy custom_domains and custom_domains_include.conf paths.
Nginx is managed as a service with reload: True, meaning configuration changes trigger a graceful reload rather than a full restart.

Pillar keys

KeyDefaultDescription
nginx:doc_root/srv/mediawikiDocument root passed to the mediawiki-common.conf snippet
nginx:csp_header(empty)Full Content-Security-Policy header value
nginx:permission_policy_header(empty)Permissions-Policy header value
nginx:server_blocks[]List of server block definitions for mediawiki-vhosts.conf
nginx:custom_domains{}Map of wiki slug → custom domain configuration
php:version8.3PHP version; used to derive the FPM socket path
php:fpm:listen(derived)FPM listen address; defaults to unix:/run/php/php<version>-fpm.sock

mediawiki-common.conf snippet

The snippet at /etc/nginx/snippets/mediawiki-common.conf is included by every MediaWiki server block. It sets the document root, configures all MediaWiki URL patterns, and emits security headers.
{%- set nginx = salt['pillar.get']('nginx', {}) %}
{%- set csp = nginx.get('csp_header', '') %}
{%- set doc_root = nginx.get('doc_root', '/srv/mediawiki') %}
{%- set php_version = salt['pillar.get']('php:version', '8.4') %}
{%- set fpm_listen = salt['pillar.get']('php:fpm:listen', '') or ('unix:/run/php/php' ~ php_version ~ '-fpm.sock') %}

root {{ doc_root }};
index index.php index.html index.htm;
client_max_body_size 128M;

add_header Referrer-Policy strict-origin-when-cross-origin;
add_header X-Permitted-Cross-Domain-Policies "none";
add_header Cross-Origin-Opener-Policy "same-origin";
add_header Access-Control-Allow-Origin $cors_origin always;

{% if csp %}
add_header Content-Security-Policy "{{ csp }}" always;
{% endif %}
Key location patterns defined in the snippet:
PatternBehaviour
= /robots.txtTries static file, falls back to /w/config/robots.php
= /sitemap.xmlRewrites to /w/sitemap.php
~ ^/images/(.*)$Returns 301 to static.wikioasis.org/$1
/Tries static file, falls back to /w/index.php
/wiki/Rewrites to /w/index.php?title=...
~ /w/.*\.php$FastCGI to PHP-FPM with MW_ENV production
~ ^/w/rest\.phpREST API — FastCGI to PHP-FPM
~ ^/w/(includes|vendor|...)Deny all (protects internals)

mediawiki-vhosts.conf

Generated from nginx:server_blocks pillar. Each entry in the list becomes one server {} block that includes the shared mediawiki-common.conf snippet:
{% for block in nginx.get('server_blocks', []) %}
server {
{%- for addr in block.get('listen', ['80', '[::]:80']) %}
    listen {{ addr }};
{%- endfor %}
    server_name {{ block.server_name }};
    include snippets/mediawiki-common.conf;
}
{% endfor %}

Production server_blocks pillar

nginx:
  doc_root: /srv/mediawiki
  server_blocks:
    - listen:
        - "80"
        - "[::]:80"
      server_name: ".wikioasis.org .skywiki.org .betaoasis.xyz"

CSP header

The nginx:csp_header pillar value is a multi-directive Content Security Policy string. Because the policy is long and spans many origins, it is defined in pillar as a YAML block scalar:
nginx:
  csp_header: >-
    default-src 'self' https://*.betaoasis.xyz https://*.wikioasis.org;
    script-src 'self' blob: 'unsafe-inline' 'unsafe-eval'
      https://*.betaoasis.xyz https://*.wikioasis.org
      https://*.newrelic.com https://*.wikimedia.org
      https://*.sentry-cdn.com https://*.cloudflareinsights.com
      https://hcaptcha.com https://*.hcaptcha.com
      https://*.googletagmanager.com;
    ...
    report-uri https://wikioasis.report-uri.com/r/d/csp/reportOnly;
The CSP is currently emitted in Report-Only mode (report-uri only) via an external reporting endpoint. Violations are sent to wikioasis.report-uri.com for review before enforcement is tightened.

Custom domains

Wikis that use external domain names (e.g. www.drawing.wiki mapped to drawingwiki) are declared under nginx:custom_domains. Each entry produces a dedicated server {} block that includes mediawiki-common.conf and also serves an ACME challenge token at /.well-known/acme-challenge/<location>.
{% for wikiname, domain in custom_domains.items() %}
server {
    listen {{ domain.get('listen', 80) }};
    server_name {{ domain.server_name }};

    set $custom_domain_sitemap "{{ domain.get('database_name', wikiname) }}";
    include snippets/mediawiki-common.conf;

    location = /.well-known/acme-challenge/{{ domain.location }} {
        return 200 "{{ domain['return'] }}";
    }
}
{% endfor %}

Custom domain pillar structure

KeyDescription
server_nameThe external domain (e.g. www.drawing.wiki)
listenPort to listen on (default: 80)
locationThe ACME challenge token path component
returnThe full ACME challenge response body
database_nameThe wiki’s internal database name for sitemap routing

Example entry

nginx:
  custom_domains:
    drawingwiki:
      server_name: 'www.drawing.wiki'
      listen: 80
      location: '0mxcwTJibfwKVSeAYeUb2O5T1WSgC5DnrHdjqOYM98d6LIpjlSj0NIsLkE7qL_Qi'
      return: '0mxcwTJibfwKVSeAYeUb2O5T1WSgC5DnrHdjqOYM98d6LIpjlSj0NIsLkE7qL_Qi.r54qAqCZSs4xyyeamMffaxyR1FWYVb5OvwUh8EcrhpI'
      database_name: 'drawingwiki'

Applying the state

salt 'mw*' state.apply nginx
After applying, Nginx performs a graceful reload. To verify the configuration is valid before applying:
salt 'mw*' cmd.run 'nginx -t'

Build docs developers (and LLMs) love