Five documentation fixes that do not depend on anything upstream. **PostgreSQL version in the docker guide** (closes #224) The compose example pinned `postgres:14`, the oldest version Gitea still tests against, and PostgreSQL does not upgrade its data directory on its own, so every new deployment that copies the example is one major upgrade behind from day one. The example now uses `postgres:18`, with a note about why the major version is pinned and a pointer to the supported range. **SELinux** (closes #211) `setcap 'cap_net_bind_service=+ep'` is what the docs suggest for binding to a port below 1024, but it is denied under SELinux depending on the label of the binary, and it is lost on every upgrade because the capability lives in an extended attribute of the file. A new page describes granting the capability through the systemd unit instead (`AmbientCapabilities`, plus `PrivateUsers=false` when the sandboxing gets in the way), the `semanage fcontext` / `restorecon` labels for the binary and the data directory, and how to read the denials with `ausearch` and `audit2allow`. It is linked from the binary and source installation pages and from the `gitea web` notes. **OAuth2 and OpenID Connect** (closes #106) The authentication page documented LDAP, PAM, SMTP, FreeIPA, SPNEGO and the reverse proxy, but not that Gitea can log users in against an external OAuth2 or OpenID Connect provider, which made it look like the only OAuth2 support is Gitea acting as the provider. The new section covers the fields of the authentication source, the callback URL to register at the provider, the group and claim mappings, and the `[oauth2_client]` settings, and separates it from the older OpenID 2.0 sign-in. **IIS reverse proxy** (closes #39) Application Request Routing rewrites the host of the `Location` header back to the internal one while "Reverse rewrite host in response headers" is on, which sends the browser to `127.0.0.1:3000` after a sign-in. The IIS section now says to turn it off and where the setting lives. **ACME in containers** (closes #292) `ACME_DIRECTORY` defaults to the relative path `https`, which is resolved against the working directory of the process. In the official image that is `/app/gitea`, outside the `/data` volume, so a recreated container asks the CA for a new certificate and runs into the Let's Encrypt limit of 5 certificates per week for the same domains. The HTTPS page now warns about it and shows an absolute path inside the volume; the cheat sheet entry points at the warning. The default itself is being changed in https://github.com/go-gitea/gitea/pull/35851, the note stays useful for every released version. Only `docs/` is touched, the released versions keep their content. <!-- cloudflare-preview --> Preview: https://pr-513.docs-gitea-com.pages.dev Reviewed-on: https://gitea.com/gitea/docs/pulls/513 Reviewed-by: bircni <[email protected]> Co-authored-by: Lunny Xiao <[email protected]>
18 KiB
date, slug, sidebar_position, aliases
| date | slug | sidebar_position | aliases | |
|---|---|---|---|---|
| 2018-05-22T11:00:00+00:00 | reverse-proxies | 16 |
|
Reverse Proxies
General configuration
- Set
[server] ROOT_URL = https://git.example.com/in yourapp.inifile. - Make the reverse-proxy pass
https://git.example.com/footohttp://gitea:3000/foo. - Make sure the reverse-proxy does not decode the URI. The request
https://git.example.com/a%2Fbshould be passed ashttp://gitea:3000/a%2Fb. - Make sure
HostandX-Forwarded-Protoheaders are correctly passed to Gitea to make Gitea see the real URL being visited. - Make sure your webserver has a certificate, including all intermediate and RootCA certificates, for
git cloneandgit pullto work. - Gitea uses a WebSocket connection at
/-/wsfor real-time updates like the notification counter. Make sure the reverse-proxy talks HTTP/1.1 and forwards theUpgradeandConnectionheaders, see the examples below. Without it, Gitea falls back to periodic polling.
Use a sub-path
Usually it's not recommended to put Gitea in a sub-path, it's not widely used and may have some issues in rare cases.
To make Gitea work with a sub-path (eg: https://common.example.com/gitea/),
there are some extra requirements besides the general configuration above:
- Use
[server] ROOT_URL = https://common.example.com/gitea/in yourapp.inifile. - Make the reverse-proxy pass
https://common.example.com/gitea/footohttp://gitea:3000/foo. - The container registry requires a fixed sub-path
/v2at the root level which must be configured:- Make the reverse-proxy pass
https://common.example.com/v2tohttp://gitea:3000/v2. - Make sure the URI and headers are also correctly passed (see the general configuration above).
- Make the reverse-proxy pass
Nginx
If you want Nginx to serve your Gitea instance, add the following server section to the http section of nginx.conf.
Make sure client_max_body_size is large enough, otherwise there would be "413 Request Entity Too Large" error when uploading large files.
server {
...
location / {
client_max_body_size 512M;
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Nginx with a sub-path
In case you already have a site, and you want Gitea to share the domain name,
you can setup Nginx to serve Gitea under a sub-path by adding the following server section
into the http section of nginx.conf:
server {
...
location ~ ^/(gitea|v2)($|/) {
client_max_body_size 512M;
# make nginx use unescaped URI, keep "%2F" as-is, remove the "/gitea" sub-path prefix, pass "/v2" as-is.
rewrite ^ $request_uri;
rewrite ^/(gitea($|/))?(.*) /$3 break;
proxy_pass http://127.0.0.1:3000$uri;
proxy_http_version 1.1;
# other common HTTP headers, see the "Nginx" config section above
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
Then you MUST set something like [server] ROOT_URL = http://git.example.com/gitea/ correctly in your configuration.
Nginx and serve static resources directly
We can tune the performance in splitting requests into categories static and dynamic.
CSS files, JavaScript files, images and web fonts are static content. The front page, a repository view or issue list is dynamic content.
Nginx can serve static resources directly and proxy only the dynamic requests to Gitea. Nginx is optimized for serving static content, while the proxying of large responses might be the opposite of that (see https://serverfault.com/q/587386).
Download a snapshot of the Gitea source repository to /path/to/gitea/.
After this, run make frontend in the repository directory to generate the static resources. We are only interested in the public/ directory for this task, so you can delete the rest.
(You will need to have Node with npm and make installed to generate the static resources)
Depending on the scale of your user base, you might want to split the traffic to two distinct servers, or use a cdn for the static files.
Single node and single domain
Set [server] STATIC_URL_PREFIX = /_/static in your configuration.
server {
listen 80;
server_name git.example.com;
location /_/static/assets/ {
alias /path/to/gitea/public/;
}
location / {
# other directives, see the "Nginx" config section above
proxy_pass http://localhost:3000;
}
}
Two nodes and two domains
Set [server] STATIC_URL_PREFIX = http://cdn.example.com/gitea in your configuration.
# application server running Gitea
server {
listen 80;
server_name git.example.com;
location / {
# other directives, see the "Nginx" config section above
proxy_pass http://localhost:3000;
}
}
# static content delivery server
server {
listen 80;
server_name cdn.example.com;
location /gitea/ {
alias /path/to/gitea/public/;
}
location / {
return 404;
}
}
Nginx Proxy Manager
If you are using Nginx Proxy Manager to serve your Gitea instance it differs slighly from the raw Nginx.
It is adding some directives for a custom location by default, so you have to skip these from the above mentioned Nginx config. Otherwise Nginx will produce 400 bad request error due to duplicated directives (proxy_set_header Host $host is the particularly problematic one).
So while creating the / Custom location, just add the following line to it's configuration:
client_max_body_size 512M;
Enable Websockets Support on the proxy host, Nginx Proxy Manager then adds the WebSocket directives itself. Adding proxy_http_version on top of that makes Nginx refuse to start.
Apache HTTPD
If you want Apache HTTPD to serve your Gitea instance, you can add the following to your Apache HTTPD configuration (usually located at /etc/apache2/httpd.conf in Ubuntu):
<VirtualHost *:80>
...
ProxyPreserveHost On
ProxyRequests off
AllowEncodedSlashes NoDecode
ProxyPass / http://localhost:3000/ nocanon upgrade=websocket
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
:::note
The following Apache HTTPD mods must be enabled: proxy, proxy_http.
upgrade=websocket requires Apache HTTPD 2.4.48 or later. On older versions you MUST remove it, otherwise Apache HTTPD will not start.
:::
If you wish to use Let's Encrypt with webroot validation, add the line ProxyPass /.well-known ! before ProxyPass to disable proxying these requests to Gitea.
Apache HTTPD with a sub-path
In case you already have a site, and you want Gitea to share the domain name, you can setup Apache HTTPD to serve Gitea under a sub-path by adding the following to you Apache HTTPD configuration (usually located at /etc/apache2/httpd.conf in Ubuntu):
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
AllowEncodedSlashes NoDecode
# Note: no trailing slash after either /git or port
ProxyPass /git http://localhost:3000 nocanon upgrade=websocket
ProxyPreserveHost On
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
Then you MUST set something like [server] ROOT_URL = http://git.example.com/git/ correctly in your configuration.
:::note
The following Apache HTTPD mods must be enabled: proxy, proxy_http. upgrade=websocket requires Apache HTTPD 2.4.48 or later, remove it on older versions.
:::
Apache HTTPD and serve static resources directly
We can tune the performance in splitting requests into categories static and dynamic.
CSS files, JavaScript files, images and web fonts are static content. The front page, a repository view or issue list is dynamic content.
Apache HTTPD can serve static resources directly and proxy only the dynamic requests to Gitea.
Download a snapshot of the Gitea source repository to /path/to/gitea/.
After this, run make frontend in the repository directory to generate the static resources. We are only interested in the public/ directory for this task, so you can delete the rest.
(You will need to have Node with npm and make installed to generate the static resources)
Depending on the scale of your user base, you might want to split the traffic to two distinct servers, or use a cdn for the static files.
Single node and single domain
Set [server] STATIC_URL_PREFIX = /_/static in your configuration.
<VirtualHost *:80>
...
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass /_/static/ !
Alias /_/static/ /path/to/gitea/public/
<Directory /path/to/gitea/public/>
Options FollowSymlinks
AllowOverride None
Require all granted
</Directory>
AllowEncodedSlashes NoDecode
# Note: no trailing slash after either /git or port
ProxyPass / http://localhost:3000/ nocanon upgrade=websocket
ProxyPreserveHost On
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
</VirtualHost>
:::note
The following Apache HTTPD mods must be enabled: proxy, proxy_http. upgrade=websocket requires Apache HTTPD 2.4.48 or later, remove it on older versions.
:::
Caddy
If you want Caddy to serve your Gitea instance, you can add the following server block to your Caddyfile:
git.example.com {
reverse_proxy localhost:3000
}
Caddy with a sub-path
In case you already have a site, and you want Gitea to share the domain name, you can setup Caddy to serve Gitea under a sub-path by adding the following to your server block in your Caddyfile:
git.example.com {
route /git/* {
uri strip_prefix /git
reverse_proxy localhost:3000
}
}
Then set [server] ROOT_URL = http://git.example.com/git/ in your configuration.
IIS
If you wish to run Gitea with IIS. You will need to setup IIS with URL Rewrite as reverse proxy.
- Setup an empty website in IIS, named let's say,
Gitea Proxy. - Follow the first two steps in Microsoft's Technical Community Guide to Setup IIS with URL Rewrite. That is:
- Install Application Request Routing (ARR for short) either by using the Microsoft Web Platform Installer 5.1 (WebPI) or downloading the extension from IIS.net
- Once the module is installed in IIS, you will see a new Icon in the IIS Administration Console called URL Rewrite.
- Install the
WebSocket ProtocolWindows feature, otherwise ARR cannot proxy Gitea's WebSocket endpoint. - Open the IIS Manager Console and click on the
Gitea ProxyWebsite from the tree view on the left. Select and double click the URL Rewrite Icon from the middle pane to load the URL Rewrite interface. - Choose the
Add Ruleaction from the right pane of the management console and select theReverse Proxy Rulefrom theInbound and Outbound Rulescategory. - In the Inbound Rules section, set the server name to be the host that Gitea is running on with its port. e.g. if you are running Gitea on the localhost with port 3000, the following should work:
127.0.0.1:3000 - Enable SSL Offloading
- In the Outbound Rules, ensure
Rewrite the domain names of the links in HTTP responseis set and set theFrom:field as above and theTo:to your external hostname, say:git.example.com - Turn
Reverse rewrite host in response headersoff, in theServer Proxy Settingsof Application Request Routing (select the server node in the IIS Manager, openApplication Request Routing Cache, thenServer Proxy Settingsin the right pane). While it is on, ARR rewrites the host of theLocationheader back to the internal one, so the redirects Gitea sends after a sign-in or a form submission send the browser to127.0.0.1:3000instead ofgit.example.com. - Now edit the
web.configfor your website to match the following: (changing127.0.0.1:3000andgit.example.comas appropriate)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<httpRuntime requestPathInvalidCharacters="" />
</system.web>
<system.webServer>
<security>
<requestFiltering>
<hiddenSegments>
<clear />
</hiddenSegments>
<denyUrlSequences>
<clear />
</denyUrlSequences>
<fileExtensions allowUnlisted="true">
<clear />
</fileExtensions>
</requestFiltering>
</security>
<rewrite>
<rules useOriginalURLEncoding="false">
<rule name="ReverseProxyInboundRule1" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite" url="http://127.0.0.1:3000{UNENCODED_URL}" />
<serverVariables>
<set name="HTTP_X_ORIGINAL_ACCEPT_ENCODING" value="HTTP_ACCEPT_ENCODING" />
<set name="HTTP_ACCEPT_ENCODING" value="" />
</serverVariables>
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule1" preCondition="ResponseIsHtml1">
<!-- set the pattern correctly here - if you only want to accept http or https -->
<!-- change the pattern and the action value as appropriate -->
<match filterByTags="A, Form, Img" pattern="^http(s)?://127.0.0.1:3000/(.*)" />
<action type="Rewrite" value="http{R:1}://git.example.com/{R:2}" />
</rule>
<rule name="RestoreAcceptEncoding" preCondition="NeedsRestoringAcceptEncoding">
<match serverVariable="HTTP_ACCEPT_ENCODING" pattern="^(.*)" />
<action type="Rewrite" value="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml1">
<add input="{RESPONSE_CONTENT_TYPE}" pattern="^text/html" />
</preCondition>
<preCondition name="NeedsRestoringAcceptEncoding">
<add input="{HTTP_X_ORIGINAL_ACCEPT_ENCODING}" pattern=".+" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
<urlCompression doDynamicCompression="true" />
<handlers>
<clear />
<add name="StaticFile" path="*" verb="*" modules="StaticFileModule,DefaultDocumentModule,DirectoryListingModule" resourceType="Either" requireAccess="Read" />
</handlers>
<!-- Map all extensions to the same MIME type, so all files can be
downloaded. -->
<staticContent>
<clear />
<mimeMap fileExtension="*" mimeType="application/octet-stream" />
</staticContent>
</system.webServer>
</configuration>
HAProxy
If you want HAProxy to serve your Gitea instance, you can add the following to your HAProxy configuration
add an acl in the frontend section to redirect calls to gitea.example.com to the correct backend
frontend http-in
...
acl acl_gitea hdr(host) -i gitea.example.com
use_backend gitea if acl_gitea
...
add the previously defined backend section
backend gitea
server localhost:3000 check
If you redirect the http content to https, the configuration work the same way, just remember that the connection between HAProxy and Gitea will be done via http so you do not have to enable https in Gitea's configuration.
HAProxy with a sub-path
In case you already have a site, and you want Gitea to share the domain name, you can setup HAProxy to serve Gitea under a sub-path by adding the following to you HAProxy configuration:
frontend http-in
...
acl acl_gitea path_beg /gitea
use_backend gitea if acl_gitea
...
With that configuration http://example.com/gitea/ will redirect to your Gitea instance.
then for the backend section
backend gitea
http-request replace-path /gitea\/?(.*) \/\1
server localhost:3000 check
The added http-request will automatically add a trailing slash if needed and internally remove /gitea from the path to allow it to work correctly with Gitea by setting properly http://example.com/gitea as the root.
Then you MUST set something like [server] ROOT_URL = http://example.com/gitea/ correctly in your configuration.
Traefik
If you want traefik to serve your Gitea instance, you can add the following label section to your docker-compose.yaml (Assuming the provider is docker).
gitea:
image: docker.io/gitea/gitea
...
labels:
- "traefik.enable=true"
- "traefik.http.routers.gitea.rule=Host(`example.com`)"
- "traefik.http.services.gitea-websecure.loadbalancer.server.port=3000"
This config assumes that you are handling HTTPS on the traefik side and using HTTP between Gitea and traefik.
Traefik with a sub-path
In case you already have a site, and you want Gitea to share the domain name, you can setup Traefik to serve Gitea under a sub-path by adding the following to your docker-compose.yaml (Assuming the provider is docker) :
gitea:
image: docker.io/gitea/gitea
...
labels:
- "traefik.enable=true"
- "traefik.http.routers.gitea.rule=Host(`example.com`) && PathPrefix(`/gitea`)"
- "traefik.http.services.gitea-websecure.loadbalancer.server.port=3000"
- "traefik.http.middlewares.gitea-stripprefix.stripprefix.prefixes=/gitea"
- "traefik.http.routers.gitea.middlewares=gitea-stripprefix"
This config assumes that you are handling HTTPS on the traefik side and using HTTP between Gitea and traefik.
Then you MUST set something like [server] ROOT_URL = http://example.com/gitea/ correctly in your configuration.