<https://docs.linkeddatahub.com/reference/configuration/#content>
        a       <https://w3id.org/atomgraph/linkeddatahub#XHTML>;
        <http://www.w3.org/1999/02/22-rdf-syntax-ns#value>
                "<div xmlns=\"http://www.w3.org/1999/xhtml\">\n    <p class=\"ldh-body-lg\">Environment variables, secrets and RDF configuration files</p>\n    <p>This page covers the RDF configuration files, Compose overrides, and the environment variables and secrets of each service\n        (defined in the <samp>environment</samp> sections of <samp>docker-compose.yml</samp>).</p>\n    <div>\n        <h2 id=\"system-base-uri\">System base URI</h2>\n        <p>The system base URI is the URI at which the LinkedDataHub service is accessible.</p>\n        <p>A common case is changing the system base URI from the default <samp>https://localhost:4443/</samp> to your own.\n            Take <samp>https://ec2-54-235-229-141.compute-1.amazonaws.com/</samp> as an example. Split the URI into components and set them in the <samp>.env</samp> file:</p>\n        <pre>PROTOCOL=https\nHTTP_PORT=80\nHTTPS_PORT=443\nHOST=ec2-54-235-229-141.compute-1.amazonaws.com</pre>\n        <p>A dataspace serves its documents from the root of its origin, so the base URI is always the origin followed by <samp>/</samp> — there is no\n            sub-path component to configure. Serving several dataspaces from one instance is a matter of giving each its own subdomain, as described under\n            <a href=\"../dataspace/\">Dataspaces</a>.</p>\n        <div class=\"ac-alert va-informative\" role=\"status\">\n            <span class=\"ac-alert-ic\"><span aria-hidden=\"true\" class=\"msi outline\">info</span></span>\n            <div class=\"ac-alert-body\">\n                <p class=\"ac-alert-text\">The <a href=\"../dataspace/#admin\">administration dataspace</a> of each dataspace is served on the <code>admin.</code> subdomain\n                    of its end-user host (e.g. <samp>admin.ec2-54-235-229-141.compute-1.amazonaws.com</samp>). The subdomain must resolve in DNS and be covered by the\n                    server's TLS certificate, otherwise the admin dataspace will not be reachable.</p>\n            </div>\n        </div>\n        <p><a href=\"../../user-guide/manage-dataspaces/\">Dataspace URIs</a> need to be relative to the system base URI in order to be reachable — after the change, the\n            origins in <samp>config/dataspaces.trig</samp> have to follow. For the Northwind Traders dataspace, deploying from local development to the demo\n            host means:</p>\n        <pre># before\n&lt;urn:linkeddatahub:apps/northwind-traders/end-user&gt; a lds:Dataspace ;\n    lds:origin &lt;https://northwind-traders.demo.localhost:4443&gt; ;\n    lds:ontology &lt;https://northwind-traders.demo.localhost:4443/ns#&gt; .\n\n# after\n&lt;urn:linkeddatahub:apps/northwind-traders/end-user&gt; a lds:Dataspace ;\n    lds:origin &lt;https://northwind-traders.demo.linkeddatahub.com&gt; ;\n    lds:ontology &lt;https://northwind-traders.demo.linkeddatahub.com/ns#&gt; .</pre>\n        <p>Restart the services (<samp>make down</samp>, then <samp>make up</samp>) for the changes to take effect. Note that changing the base URI does not\n            rewrite URIs already stored in the dataset — documents minted under the old base URI keep it.</p>\n    </div>\n    <div>\n        <h2 id=\"config-files\">Configuration files</h2>\n        <p>LinkedDataHub uses two main RDF configuration files that define dataspaces and services:</p>\n        <dl>\n            <dt><samp>config/dataspaces.trig</samp></dt>\n            <dd>Contains public metadata for each dataspace, including:</dd>\n            <dd>\n                <ul>\n                    <li>Base URIs and origins</li>\n                    <li>Dataspace titles and descriptions</li>\n                    <li>Associated ontologies</li>\n                    <li>Custom stylesheets</li>\n                </ul>\n            </dd>\n            <dd>This file contains public-facing metadata and can be safely shared.</dd>\n            <dt><samp>config/system.trig</samp></dt>\n            <dd>Contains internal deployment wiring, including:</dd>\n            <dd>\n                <ul>\n                    <li>Dataspace-to-service bindings (admin and end-user roles)</li>\n                    <li>SPARQL endpoint URLs</li>\n                    <li>Graph Store Protocol endpoints</li>\n                </ul>\n            </dd>\n            <dd>This file contains internal configuration and is not intended for public sharing, but does not contain credentials.</dd>\n            <dt><samp>secrets/credentials.trig</samp></dt>\n            <dd>Optional file containing service authentication credentials, including:</dd>\n            <dd>\n                <ul>\n                    <li>Bearer tokens (<code>a:authToken</code>)</li>\n                    <li>HTTP Basic auth credentials (<code>a:authUser</code>, <code>a:authPwd</code>)</li>\n                </ul>\n            </dd>\n            <dd>This file is gitignored and must not be committed to version control. See the <samp>credentials</samp> secret entry below for configuration details.</dd>\n        </dl>\n        <p>All files are in TriG format and are mounted into the LinkedDataHub container at startup. The separation allows you to version control\n        dataspace metadata and service wiring while keeping credentials out of version control entirely. The\n        <a href=\"../dataspace/#configuring-dataspaces\">dataspace reference</a> shows the Northwind Traders dataspace as a worked example across both\n        <samp>config/</samp> files.</p>\n    </div>\n    <div>\n        <h2 id=\"compose-override\">Compose overrides</h2>\n        <p>Environment-specific configuration goes into <samp>docker-compose.override.yml</samp>, which Docker Compose merges over\n            <samp>docker-compose.yml</samp> automatically. Mounting a stylesheet under development, for example:</p>\n        <pre>services:\n  linkeddatahub:\n    volumes:\n      - ./files/northwind.xsl:/usr/local/tomcat/webapps/ROOT/static/com/atomgraph/linkeddatahub/northwind/xsl/layout.xsl:ro</pre>\n    </div>\n    <div>\n        <h2 id=\"compose-variables\">Compose-level variables</h2>\n        <p>The variables in the <samp>.env</samp> file are interpolated by Docker Compose into <samp>docker-compose.yml</samp>. They define the\n            <a href=\"#system-base-uri\">system base URI</a> and the host port mappings:</p>\n        <dl>\n            <dt><samp>PROTOCOL</samp></dt>\n            <dd>URI scheme of the system base URI (<samp>http</samp> or <samp>https</samp>)</dd>\n            <dt><samp>HOST</samp></dt>\n            <dd>Hostname of the system base URI</dd>\n            <dt><samp>HTTP_PORT</samp></dt>\n            <dd>Host port mapped to the container's port <samp>8080</samp>, which redirects HTTP to HTTPS</dd>\n            <dt><samp>HTTPS_PORT</samp></dt>\n            <dd>Host HTTPS port, mapped to the container's port <samp>8443</samp></dd>\n        </dl>\n    </div>\n    <div>\n        <h2 id=\"service-configuration\">Service configuration</h2>\n        <p>SPARQL service endpoints are configured in <samp>config/system.trig</samp>. See <a href=\"../triplestores/#service-configuration\">service configuration</a> in the triplestores reference for the RDF properties and examples, and the <a href=\"../dataspace/#services\">dataspace reference</a> for the conceptual overview.</p>\n    </div>\n    <div>\n        <h2 id=\"linkeddatahub\"><samp>linkeddatahub</samp> service</h2>\n        <div>\n            <h3 id=\"secrets\">Secrets</h3>\n            <dl>\n                <dt><samp>owner_cert_password</samp></dt>\n                <dd>Password of the owner's WebID certificate</dd>\n                <dt><samp>secretary_cert_password</samp></dt>\n                <dd>Password of the secretary's WebID certificate</dd>\n                <dt><samp>client_truststore_password</samp></dt>\n                <dd>Password of the client truststore</dd>\n                <dt><samp>google_client_id</samp></dt>\n                <dd><a href=\"https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid\">OAuth client ID</a></dd>\n                <dd><a href=\"../../get-started/get-an-account/\">Login with Google</a> authentication is enabled when this value is provided</dd>\n                <dt><samp>google_client_secret</samp></dt>\n                <dd><a href=\"https://developers.google.com/identity/gsi/web/guides/get-google-api-clientid\">OAuth client secret</a></dd>\n                <dt><samp>orcid_client_id</samp></dt>\n                <dd><a href=\"https://info.orcid.org/documentation/integration-guide/registering-a-public-api-client/\">ORCID OpenID Connect client ID</a></dd>\n                <dd><a href=\"../../get-started/get-an-account/\">Login with ORCID</a> authentication is enabled when this value is provided</dd>\n                <dt><samp>orcid_client_secret</samp></dt>\n                <dd><a href=\"https://info.orcid.org/documentation/integration-guide/registering-a-public-api-client/\">ORCID OpenID Connect client secret</a></dd>\n                <dt><samp>credentials</samp></dt>\n                <dd>RDF dataset file (<samp>./secrets/credentials.trig</samp>) containing service authentication credentials (optional)</dd>\n                <dd>Supports HTTP Basic authentication (<code>a:authUser</code>, <code>a:authPwd</code>) and Bearer token authentication (<code>a:authToken</code>)</dd>\n                <dd>See <a href=\"../triplestores/#authentication\">authentication</a> in the triplestores reference for RDF examples</dd>\n            </dl>\n        </div>\n        <div>\n            <h3 id=\"webid-auth\">WebID authentication</h3>\n            <dl>\n                <dt><samp>ENABLE_WEBID_SIGNUP</samp></dt>\n                <dd><samp>false</samp> to disable. Enabled by default.</dd>\n                <dd>\n                    <div class=\"ac-alert va-warning\" role=\"status\">\n                        <span class=\"ac-alert-ic\"><span aria-hidden=\"true\" class=\"msi outline\">warning</span></span>\n                        <div class=\"ac-alert-body\">\n                            <p class=\"ac-alert-text\">Currently this will only hide the signup button in the UI, without disabling the endpoint.</p>\n                        </div>\n                    </div>\n                </dd>\n                <dt><samp>WEBID_CACHE_EXPIRATION</samp></dt>\n                <dd>Expiration time (in seconds) of cached WebID profiles, bounding how long a revoked WebID stays authenticated. Defaults to <samp>86400</samp>.</dd>\n                <dt><samp>JWKS_CACHE_EXPIRATION</samp></dt>\n                <dd>Expiration time (in seconds) of cached JWKS keys used for OpenID Connect token verification. Defaults to <samp>86400</samp>.</dd>\n            </dl>\n        </div>\n        <div>\n            <h3 id=\"email-server\">Email server</h3>\n            <dl>\n                <dt><samp>MAIL_SMTP_HOST</samp></dt>\n                <dd>Hostname of the email server</dd>\n                <dt><samp>MAIL_SMTP_PORT</samp></dt>\n                <dd>Port number of the email server</dd>\n                <dt><samp>MAIL_USER</samp></dt>\n                <dd>Username</dd>\n                <dt><samp>MAIL_PASSWORD</samp></dt>\n                <dd>Password (if required)</dd>\n            </dl>\n        </div>\n        <div>\n            <h3 id=\"linked-data\">Linked Data</h3>\n            <p><samp>ENABLE_LINKED_DATA_PROXY</samp> takes <samp>false</samp> to disable the <a href=\"../http-api/#ld-proxy\">Linked Data proxy</a>, which is enabled by default.</p>\n        </div>\n        <div>\n            <h3 id=\"http\">HTTP(S)</h3>\n            <dl>\n                <dt><samp>SELF_SIGNED_CERT</samp></dt>\n                <dd>Set to <samp>false</samp> if you are not using the self-signed <em>server</em> certificate (e.g. using a LetsEncrypt certificate instead). Not to be confused with the WebID client certificate.\n                    Defaults to <samp>true</samp>.</dd>\n                <dt><samp>MAX_CONTENT_LENGTH</samp></dt>\n                <dd>Maximum allowed request body size (<samp>nginx</samp> has a separate setting for this). Defaults to <samp>2097152</samp>.</dd>\n            </dl>\n        </div>\n        <div>\n            <h3 id=\"debug\">Debug</h3>\n            <dl>\n                <dt><samp>JPDA_ADDRESS</samp></dt>\n                <dd>The address through which the Java debugger can connect, for example <samp>*:8000</samp>. Note that the port has to be mapped to the host in order for the debugger to work, e.g. <samp>8000:8000</samp>.</dd>\n                <dt><samp>CATALINA_OPTS</samp></dt>\n                <dd>Tomcat's Java options</dd>\n            </dl>\n        </div>\n        <div>\n            <h3 id=\"proxy\">Proxy</h3>\n            <dl>\n                <dt><samp>LDHC_FRONTEND_PROXY</samp></dt>\n                <dd>Frontend proxy URL for HTTP requests (optional)</dd>\n                <dd>Configures a proxy server for the HTTP client infrastructure layer when making frontend requests</dd>\n                <dt><samp>LDHC_BACKEND_PROXY</samp></dt>\n                <dd>Backend proxy URL for SPARQL service access (optional)</dd>\n                <dd>Configures a proxy server for accessing SPARQL services and backend endpoints</dd>\n            </dl>\n        </div>\n        <div>\n            <h3 id=\"http-client\">HTTP client timeouts</h3>\n            <p>Timeouts and connection lifetimes for LinkedDataHub's pooled HTTP clients, used for the <a href=\"../http-api/#ld-proxy\">Linked Data proxy</a> and for accessing SPARQL services. All values are in milliseconds and are passed as <samp>CATALINA_OPTS</samp> system properties.</p>\n            <dl>\n                <dt><samp>CLIENT_SOCKET_TIMEOUT</samp></dt>\n                <dd>Socket (read) timeout — how long to wait for data on an established connection. Defaults to <samp>120000</samp>.</dd>\n                <dt><samp>CLIENT_CONNECT_TIMEOUT</samp></dt>\n                <dd>Connection timeout — how long to wait to establish a connection. Defaults to <samp>10000</samp>.</dd>\n                <dt><samp>CLIENT_CONNECTION_TIME_TO_LIVE</samp></dt>\n                <dd>Maximum lifetime of a pooled connection before it is closed. Defaults to <samp>300000</samp>.</dd>\n                <dt><samp>CLIENT_VALIDATE_AFTER_INACTIVITY</samp></dt>\n                <dd>Idle time after which a pooled connection is validated before reuse. Defaults to <samp>10000</samp>.</dd>\n            </dl>\n        </div>\n    </div>\n    <div>\n        <h2 id=\"varnish\">Varnish services</h2>\n        <p>The backend ports of the <samp>varnish-frontend</samp>, <samp>varnish-admin</samp> and <samp>varnish-end-user</samp> caching services can be\n            customized when running LinkedDataHub behind additional proxies or in non-standard Docker networking configurations:</p>\n        <dl>\n            <dt><samp>VARNISH_FRONTEND_BACKEND_PORT</samp></dt>\n            <dd>Port for frontend Varnish backend. Defaults to <samp>7070</samp>.</dd>\n            <dt><samp>VARNISH_ADMIN_BACKEND_PORT</samp></dt>\n            <dd>Port for admin Varnish backend. Defaults to <samp>3030</samp>.</dd>\n            <dt><samp>VARNISH_END_USER_BACKEND_PORT</samp></dt>\n            <dd>Port for end-user Varnish backend. Defaults to <samp>3030</samp>.</dd>\n        </dl>\n    </div>\n    <div>\n        <h2 id=\"fuseki\"><samp>fuseki</samp> service</h2>\n        <p>A single <a href=\"https://jena.apache.org/documentation/fuseki2/\" target=\"_blank\">Apache Jena Fuseki</a> server holds a TDB2 dataset for every dataspace role — an <samp>end-user</samp> and an <samp>admin</samp> dataset per dataspace — declared in <samp>config/fuseki/config.ttl</samp> and persisted under the <samp>fuseki/</samp> folder, one sub-folder per dataset. <samp>JAVA_OPTIONS</samp> carries the Java options of the Fuseki process, and is what sizes its heap.</p>\n        <p>Datasets are named after the dataspace origin with the deployment host dropped and the role appended — <samp>northwind-traders.demo.end-user</samp>, <samp>northwind-traders.demo.admin</samp> — so the names hold across development and production; the root dataspace's are plain <samp>end-user</samp> and <samp>admin</samp>. See the <a href=\"../dataspace/#services\">dataspace reference</a> for the service declarations that bind a dataspace to its datasets.</p>\n    </div>\n    <div>\n        <h2 id=\"egress\"><samp>egress</samp> service</h2>\n        <p>A forward proxy (Squid) that the outbound SPARQL <code>SERVICE</code> and <code>LOAD</code> requests of both Fuseki and the platform pass through. It permits public destinations and refuses loopback, private and link-local ones, resolving each where it connects so redirect hops and DNS answers are checked too. Federation with public endpoints keeps working, while a <code>SERVICE</code> clause cannot reach another dataset, the cache or the platform.</p>\n        <p>Fuseki is pointed at it through its <samp>JAVA_TOOL_OPTIONS</samp>; the platform's own in-process queries (imports and PATCH updates) are routed through it when <samp>EGRESS_PROXY</samp> is set to its <samp>host:port</samp>. Without a proxy and without <samp>ALLOW_INTERNAL_URLS</samp>, the platform disables <code>SERVICE</code> in those queries rather than leaving it open.</p>\n    </div>\n    <div>\n        <h2 id=\"sef-compiler\"><samp>sef-compiler</samp> service</h2>\n        <p>Compiles each dataspace's client-side stylesheet together with the stylesheets of its <a href=\"../administration/packages/\">imported packages</a> into a SEF that the browser runs, so a package's rendering reaches the client as well as the server. The platform composes the wrapper and submits it; the compiled SEF is written to the <samp>sef</samp> bind mount (<samp>/var/www/linkeddatahub/sef</samp>, served under <samp>/static/xsl/sef/</samp>) and its URL travels to the page as a <code>Link</code> header. The service is built from the same Dockerfile as the platform, so its copy of the stylesheets is the deployed one.</p>\n        <p><samp>SEF_ROOT</samp> and <samp>SEF_COMPILER</samp> reach the platform through <samp>CATALINA_OPTS</samp> and are optional: without them packages compose server-side only, and the client runs the stock stylesheet. A deployment with its own compose file adds the service, the platform's <samp>depends_on</samp> on it and the bind mount.</p>\n        <p><samp>CLIENT_STYLESHEET</samp> names the client stylesheet the SEF is composed from and defaults to the platform's <samp>client.xsl</samp>. A deployment whose page bootstraps its own client stylesheet sets it to that stylesheet's webapp path - it must import the platform's <samp>client.xsl</samp> directly, by an href that resolves from that path - and its layout prefers <code>ldh:client-stylesheet()</code> over its own SEF; otherwise the site's rules vanish from a package dataspace on the first client-side navigation, while a reload brings them back.</p>\n    </div>\n    <div>\n        <h2 id=\"nginx\"><samp>nginx</samp> service</h2>\n        <dl>\n            <dt><samp>SERVER_CERT_FILE</samp></dt>\n            <dd>Location of the server's SSL certificate. Defaults to <samp>/etc/nginx/ssl/server.crt</samp>.</dd>\n            <dt><samp>SERVER_KEY_FILE</samp></dt>\n            <dd>Location of the server's SSL certificate's key. Defaults to <samp>/etc/nginx/ssl/server.key</samp>.</dd>\n            <dt><samp>SSL_VERIFY_CLIENT</samp></dt>\n            <dd><samp>optional_no_ca</samp> to enable TLS client certificate authentication on the <a href=\"#compose-variables\"><samp>$HTTPS_PORT</samp></a> port; <samp>off</samp> to disable it, which also disables LinkedDataHub's <a href=\"../../get-started/get-an-account/\">WebID-TLS authentication method</a>.</dd>\n            <dd>Disabling can be used to avoid the certificate prompt in the browser in end-user facing dataspaces. The client certificate authentication is still available on port 5443.</dd>\n            <dt><samp>MAX_BODY_SIZE</samp></dt>\n            <dd>Maximum allowed request body size (<samp>linkeddatahub</samp> has a separate setting for this). Defaults to <samp>2097152</samp>.</dd>\n        </dl>\n        <p>By default nginx is configured to guard against DoS by limiting the rate of requests per second, which can be necessary on a public instance. The limiting can be disabled in <samp>platform/nginx.conf.template</samp>\n            by commenting out all lines starting with <samp>limit_req</samp> using <samp>#</samp>.</p>\n        <div>\n            <h3 id=\"server-certs\">Server certificates</h3>\n            <p>The certificates generated by the <samp>server-cert-gen.sh</samp> script are self-signed and therefore are shown as\n                <samp>not secure</samp> in web browsers. On a local machine this should not be a problem; on public/production servers use\n                <a href=\"https://letsencrypt.org/\" target=\"_blank\">LetsEncrypt</a> certificates instead. They can be mounted into nginx as follows:</p>\n            <pre>services:\n  nginx:\n    environment:\n      - SERVER_CERT_FILE=/etc/letsencrypt/live/kgdev.net/fullchain.pem\n      - SERVER_KEY_FILE=/etc/letsencrypt/live/kgdev.net/privkey.pem\n    volumes:\n      - /etc/letsencrypt:/etc/letsencrypt</pre>\n            <p><a href=\"#http\"><samp>SELF_SIGNED_CERT</samp></a> should be set to <samp>false</samp> in this case.</p>\n        </div>\n    </div>\n</div>"^^<http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral> .

<https://docs.linkeddatahub.com/reference/configuration/>
        a       <https://w3id.org/atomgraph/linkeddatahub/document-hierarchy#Item>;
        <http://www.w3.org/1999/02/22-rdf-syntax-ns#_1>
                <https://docs.linkeddatahub.com/reference/configuration/#content>;
        <http://purl.org/dc/terms/created>
                "2026-09-29T09:52:20.507Z"^^<http://www.w3.org/2001/XMLSchema#dateTime>;
        <http://purl.org/dc/terms/creator>
                <https://admin.linkeddatahub.com/acl/agents/5ba81960-d511-4a3b-8b9a-cb5bb278dd95/#this>;
        <http://purl.org/dc/terms/description>
                "Environment variables, secrets and RDF configuration files";
        <http://purl.org/dc/terms/title>
                "Configuration";
        <http://rdfs.org/sioc/ns#has_container>
                <https://docs.linkeddatahub.com/reference/>;
        <http://www.w3.org/ns/auth/acl#owner>
                <https://admin.linkeddatahub.com/acl/agents/5ba81960-d511-4a3b-8b9a-cb5bb278dd95/#this> .
