2018-05-23 13:21:17 +08:00
---
date: "2018-05-22T11:00:00+00:00"
2023-04-06 17:06:32 +08:00
title: "Reverse Proxies"
2018-05-23 13:21:17 +08:00
slug: "reverse-proxies"
2023-07-26 12:53:13 +08:00
sidebar_position: 16
2020-12-09 14:47:06 +08:00
toc: false
2018-05-23 13:21:17 +08:00
draft: false
Refactor docs (#23752)
This was intended to be a small followup for
https://github.com/go-gitea/gitea/pull/23712, but...here we are.
1. Our docs currently use `slug` as the entire URL, which makes
refactoring tricky (see https://github.com/go-gitea/gitea/pull/23712).
Instead, this PR attempts to make future refactoring easier by using
slugs as an extension of the section. (Hugo terminology)
- What the above boils down to is this PR attempts to use directory
organization as URL management. e.g. `usage/comparison.en-us.md` ->
`en-us/usage/comparison/`, `usage/packages/overview.en-us.md` ->
`en-us/usage/packages/overview/`
- Technically we could even remove `slug`, as Hugo defaults to using
filename, however at least with this PR it means `slug` only needs to be
the name for the **current file** rather than an entire URL
2. This PR adds appropriate aliases (redirects) for pages, so anything
on the internet that links to our docs should hopefully not break.
3. A minor nit I've had for a while, renaming `seek-help` to `support`.
It's a minor thing, but `seek-help` has a strange connotation to it.
4. The commits are split such that you can review the first which is the
"actual" change, and the second is added redirects so that the first
doesn't break links elsewhere.
---------
Signed-off-by: jolheiser <john.olheiser@gmail.com>
2023-04-28 11:33:41 +08:00
aliases:
- /en-us/reverse-proxies
2018-05-23 13:21:17 +08:00
menu:
sidebar:
2023-03-23 23:18:24 +08:00
parent: "administration"
2018-05-23 13:21:17 +08:00
name: "Reverse Proxies"
2023-07-26 12:53:13 +08:00
sidebar_position: 16
2018-05-23 13:21:17 +08:00
identifier: "reverse-proxies"
---
2020-12-08 12:52:26 +08:00
# Reverse Proxies
2024-05-19 23:22:54 +08:00
## General configuration
1. Set `[server] ROOT_URL = https://git.example.com/` in your `app.ini` file.
2. Make the reverse-proxy pass `https://git.example.com/foo` to `http://gitea:3000/foo` .
3. Make sure the reverse-proxy does not decode the URI. The request `https://git.example.com/a%2Fb` should be passed as `http://gitea:3000/a%2Fb` .
4. Make sure `Host` and `X-Fowarded-Proto` headers are correctly passed to Gitea to make Gitea see the real URL being visited.
### 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:
1. Use `[server] ROOT_URL = https://common.example.com/gitea/` in your `app.ini` file.
2. Make the reverse-proxy pass `https://common.example.com/gitea/foo` to `http://gitea:3000/foo` .
3. The container registry requires a fixed sub-path `/v2` at the root level which must be configured:
- Make the reverse-proxy pass `https://common.example.com/v2` to `http://gitea:3000/v2` .
- Make sure the URI and headers are also correctly passed (see the general configuration above).
2020-12-09 14:47:06 +08:00
## Nginx
2024-05-19 23:22:54 +08:00
If you want Nginx to serve your Gitea instance, add the following `server` section to the `http` section of `nginx.conf` .
2018-05-23 13:21:17 +08:00
2024-05-19 23:22:54 +08:00
Make sure `client_max_body_size` is large enough, otherwise there would be "413 Request Entity Too Large" error when uploading large files.
2018-05-23 13:21:17 +08:00
2024-05-19 23:22:54 +08:00
```nginx
server {
...
2018-05-23 13:21:17 +08:00
location / {
2023-05-10 13:28:44 +08:00
client_max_body_size 512M;
2018-05-23 13:21:17 +08:00
proxy_pass http://localhost:3000;
2023-09-07 01:49:45 +08:00
proxy_set_header Connection $http_connection;
proxy_set_header Upgrade $http_upgrade;
2022-02-27 02:32:09 +08:00
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;
2018-05-23 13:21:17 +08:00
}
}
```
2020-12-08 12:52:26 +08:00
## Nginx with a sub-path
2018-05-23 13:21:17 +08:00
2024-05-19 23:22:54 +08:00
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` :
2018-05-23 13:21:17 +08:00
2024-05-19 23:22:54 +08:00
```nginx
2018-05-23 13:21:17 +08:00
server {
2024-05-19 23:22:54 +08:00
...
location ~ ^/(gitea|v2)($|/) {
2023-05-10 13:28:44 +08:00
client_max_body_size 512M;
2024-05-19 23:22:54 +08:00
# make nginx use unescaped URI, keep "%2F" as-is, remove the "/gitea" sub-path prefix, pass "/v2" as-is.
2023-05-10 13:28:44 +08:00
rewrite ^ $request_uri;
2024-05-19 23:22:54 +08:00
rewrite ^(/gitea)?(/.*) $2 break;
2023-05-10 13:28:44 +08:00
proxy_pass http://127.0.0.1:3000$uri;
# other common HTTP headers, see the "Nginx" config section above
2024-05-19 23:22:54 +08:00
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;
2018-05-23 13:21:17 +08:00
}
}
```
2024-05-19 23:22:54 +08:00
Then you **MUST** set something like `[server] ROOT_URL = http://git.example.com/gitea/` correctly in your configuration.
2018-05-23 13:21:17 +08:00
2020-12-09 14:47:06 +08:00
## Nginx and serve static resources directly
2020-11-28 14:12:22 +08:00
We can tune the performance in splitting requests into categories static and dynamic.
2019-10-22 20:11:01 +08:00
CSS files, JavaScript files, images and web fonts are static content.
The front page, a repository view or issue list is dynamic content.
2021-11-28 21:28:30 +08:00
Nginx can serve static resources directly and proxy only the dynamic requests to Gitea.
2019-10-22 20:11:01 +08:00
Nginx is optimized for serving static content, while the proxying of large responses might be the opposite of that
2020-12-22 23:54:12 +08:00
(see [https://serverfault.com/q/587386 ](https://serverfault.com/q/587386 )).
2019-10-22 20:11:01 +08:00
2020-02-16 07:00:40 +08:00
Download a snapshot of the Gitea source repository to `/path/to/gitea/` .
2020-07-15 03:45:23 +08:00
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.
2020-02-16 07:00:40 +08:00
(You will need to have [Node with npm ](https://nodejs.org/en/download/ ) and `make` installed to generate the static resources)
2019-10-22 20:11:01 +08:00
Depending on the scale of your user base, you might want to split the traffic to two distinct servers,
2020-12-09 14:47:06 +08:00
or use a cdn for the static files.
2019-10-22 20:11:01 +08:00
2020-12-08 12:52:26 +08:00
### Single node and single domain
2019-10-22 20:11:01 +08:00
Set `[server] STATIC_URL_PREFIX = /_/static` in your configuration.
2024-05-19 23:22:54 +08:00
```nginx
2019-10-22 20:11:01 +08:00
server {
listen 80;
server_name git.example.com;
2022-06-22 16:15:49 +08:00
location /_/static/assets/ {
alias /path/to/gitea/public/;
2019-10-22 20:11:01 +08:00
}
location / {
proxy_pass http://localhost:3000;
}
}
```
2020-12-08 12:52:26 +08:00
### Two nodes and two domains
2019-10-22 20:11:01 +08:00
Set `[server] STATIC_URL_PREFIX = http://cdn.example.com/gitea` in your configuration.
2024-05-19 23:22:54 +08:00
```nginx
2021-11-28 21:28:30 +08:00
# application server running Gitea
2019-10-22 20:11:01 +08:00
server {
listen 80;
server_name git.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
```
2024-05-19 23:22:54 +08:00
```nginx
2019-10-22 20:11:01 +08:00
# static content delivery server
server {
listen 80;
server_name cdn.example.com;
2022-06-22 16:15:49 +08:00
location /gitea/ {
alias /path/to/gitea/public/;
2019-10-22 20:11:01 +08:00
}
location / {
return 404;
}
}
```
2020-12-08 12:52:26 +08:00
## Apache HTTPD
2018-05-23 13:21:17 +08:00
2019-03-10 05:15:45 +08:00
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):
2018-05-23 13:21:17 +08:00
2020-12-09 14:47:06 +08:00
```apacheconf
2018-05-23 13:21:17 +08:00
< VirtualHost * :80 >
...
ProxyPreserveHost On
ProxyRequests off
2019-07-21 02:44:53 +08:00
AllowEncodedSlashes NoDecode
ProxyPass / http://localhost:3000/ nocanon
2024-05-19 23:22:54 +08:00
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
2018-05-23 13:21:17 +08:00
< / VirtualHost >
```
2021-10-16 11:34:07 +08:00
Note: The following Apache HTTPD mods must be enabled: `proxy` , `proxy_http` .
2018-05-23 13:21:17 +08:00
2019-12-21 01:58:26 +08:00
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.
2020-12-08 12:52:26 +08:00
## Apache HTTPD with a sub-path
2018-05-23 13:21:17 +08:00
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):
2020-12-09 14:47:06 +08:00
```apacheconf
2018-05-23 13:21:17 +08:00
< VirtualHost * :80 >
...
< Proxy * >
Order allow,deny
Allow from all
< / Proxy >
2019-07-27 06:09:12 +08:00
AllowEncodedSlashes NoDecode
# Note: no trailing slash after either /git or port
ProxyPass /git http://localhost:3000 nocanon
2024-05-19 23:22:54 +08:00
ProxyPreserveHost On
RequestHeader set "X-Forwarded-Proto" expr=%{REQUEST_SCHEME}
2018-05-23 13:21:17 +08:00
< / VirtualHost >
```
2021-10-16 11:34:07 +08:00
Then you **MUST** set something like `[server] ROOT_URL = http://git.example.com/git/` correctly in your configuration.
2018-05-23 13:21:17 +08:00
2021-10-16 11:34:07 +08:00
Note: The following Apache HTTPD mods must be enabled: `proxy` , `proxy_http` .
2018-05-23 13:21:17 +08:00
2020-12-08 12:52:26 +08:00
## Caddy
2018-05-23 13:21:17 +08:00
2019-03-10 05:15:45 +08:00
If you want Caddy to serve your Gitea instance, you can add the following server block to your Caddyfile:
2018-05-23 13:21:17 +08:00
2024-05-19 23:22:54 +08:00
```
2018-05-23 13:21:17 +08:00
git.example.com {
2020-05-31 10:16:32 +08:00
reverse_proxy localhost:3000
}
```
2020-12-08 12:52:26 +08:00
## Caddy with a sub-path
2018-05-23 13:21:17 +08:00
2019-03-10 05:15:45 +08:00
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:
2018-05-23 13:21:17 +08:00
2024-05-19 23:22:54 +08:00
```
2018-05-23 13:21:17 +08:00
git.example.com {
2020-05-31 10:16:32 +08:00
route /git/* {
uri strip_prefix /git
reverse_proxy localhost:3000
}
}
```
2018-05-24 08:24:04 +08:00
Then set `[server] ROOT_URL = http://git.example.com/git/` in your configuration.
2020-03-30 05:11:15 +08:00
2020-12-08 12:52:26 +08:00
## IIS
2020-03-30 05:11:15 +08:00
If you wish to run Gitea with IIS. You will need to setup IIS with URL Rewrite as reverse proxy.
1. Setup an empty website in IIS, named let's say, `Gitea Proxy` .
2. Follow the first two steps in [Microsoft's Technical Community Guide to Setup IIS with URL Rewrite ](https://techcommunity.microsoft.com/t5/iis-support-blog/setup-iis-with-url-rewrite-as-a-reverse-proxy-for-real-world/ba-p/846222#M343 ). That is:
2020-12-09 14:47:06 +08:00
- 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 ](https://www.iis.net/downloads/microsoft/application-request-routing )
- Once the module is installed in IIS, you will see a new Icon in the IIS Administration Console called URL Rewrite.
- Open the IIS Manager Console and click on the `Gitea Proxy` Website 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 Rule` action from the right pane of the management console and select the `Reverse Proxy Rule` from the `Inbound and Outbound Rules` category.
- 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 response` is set and set the `From:` field as above and the `To:` to your external hostname, say: `git.example.com`
- Now edit the `web.config` for your website to match the following: (changing `127.0.0.1:3000` and `git.example.com` as appropriate)
2020-03-30 05:11:15 +08:00
```xml
<?xml version="1.0" encoding="UTF-8"?>
< configuration >
2021-06-25 20:38:41 +08:00
< system.web >
< httpRuntime requestPathInvalidCharacters = "" / >
< / system.web >
2020-03-30 05:11:15 +08:00
< system.webServer >
2021-05-14 12:36:53 +08:00
< security >
< requestFiltering >
< hiddenSegments >
< clear / >
< / hiddenSegments >
< denyUrlSequences >
< clear / >
< / denyUrlSequences >
< fileExtensions allowUnlisted = "true" >
< clear / >
< / fileExtensions >
< / requestFiltering >
< / security >
2020-03-30 05:11:15 +08:00
< rewrite >
2021-05-14 12:36:53 +08:00
< rules useOriginalURLEncoding = "false" >
2020-03-30 05:11:15 +08:00
< rule name = "ReverseProxyInboundRule1" stopProcessing = "true" >
< match url = "(.*)" / >
2021-05-14 12:36:53 +08:00
< action type = "Rewrite" url = "http://127.0.0.1:3000{UNENCODED_URL}" / >
2020-03-30 05:11:15 +08:00
< 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" / >
2021-05-14 12:36:53 +08:00
< 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 >
2020-03-30 05:11:15 +08:00
< / system.webServer >
< / configuration >
```
2021-10-24 23:48:26 +08:00
## 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
2022-07-28 09:22:47 +08:00
2021-10-24 23:48:26 +08:00
```
frontend http-in
...
acl acl_gitea hdr(host) -i gitea.example.com
use_backend gitea if acl_gitea
...
```
add the previously defined backend section
2022-07-28 09:22:47 +08:00
2021-10-24 23:48:26 +08:00
```
backend gitea
server localhost:3000 check
```
2022-01-09 19:53:03 +08:00
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.
2021-10-24 23:48:26 +08:00
## 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
2022-07-28 09:22:47 +08:00
2021-10-24 23:48:26 +08:00
```
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.
2022-04-20 22:08:23 +08:00
## 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).
```yaml
gitea:
image: gitea/gitea
...
labels:
- "traefik.enable=true"
- "traefik.http.routers.gitea.rule=Host(`example.com`)"
- "traefik.http.services.gitea-websecure.loadbalancer.server.port=3000"
```
2022-06-22 16:15:49 +08:00
This config assumes that you are handling HTTPS on the traefik side and using HTTP between Gitea and traefik.
2023-02-23 15:34:09 +08:00
## 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) :
```yaml
gitea:
image: 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.