aboutsummaryrefslogtreecommitdiffstats
path: root/docs/content/doc/usage/reverse-proxies.en-us.md
blob: b8cebee574bbf8aff68e439f535f25dcbec74501 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
---
date: "2018-05-22T11:00:00+00:00"
title: "Usage: Reverse Proxies"
slug: "reverse-proxies"
weight: 17
toc: false
draft: false
menu:
  sidebar:
    parent: "usage"
    name: "Reverse Proxies"
    weight: 16
    identifier: "reverse-proxies"
---

# Reverse Proxies

**Table of Contents**

{{< toc >}}

## Nginx

If you want Nginx to serve your Gitea instance, add the following `server` section to the `http` section of `nginx.conf`:

```apacheconf
server {
    listen 80;
    server_name git.example.com;

    location / {
        proxy_pass http://localhost:3000;
        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 inside the `http` section of `nginx.conf`:

```apacheconf
server {
    listen 80;
    server_name git.example.com;

    # Note: Trailing slash
    location /git/ { 
        # Note: Trailing slash
        proxy_pass http://localhost:3000/;
        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/git/` 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](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](https://nodejs.org/en/download/) 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.

```apacheconf
server {
    listen 80;
    server_name git.example.com;

    location /_/static/assets/ {
        alias /path/to/gitea/public/;
    }

    location / {
        proxy_pass http://localhost:3000;
    }
}
```

### Two nodes and two domains

Set `[server] STATIC_URL_PREFIX = http://cdn.example.com/gitea` in your configuration.

```apacheconf
# application server running Gitea
server {
    listen 80;
    server_name git.example.com;

    location / {
        proxy_pass http://localhost:3000;
    }
}
```

```apacheconf
# static content delivery server
server {
    listen 80;
    server_name cdn.example.com;

    location /gitea/ {
        alias /path/to/gitea/public/;
    }

    location / {
        return 404;
    }
}
```

## Resolving Error: 413 Request Entity Too Large

This error indicates nginx is configured to restrict the file upload size.

In your nginx config file containing your Gitea proxy directive, find the `location { ... }` block for Gitea and add the line
`client_max_body_size 16M;` to set this limit to 16 megabytes or any other number of choice.
If you use Git LFS, this will also limit the size of the largest file you will be able to push.

## 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):

```apacheconf
<VirtualHost *:80>
    ...
    ProxyPreserveHost On
    ProxyRequests off
    AllowEncodedSlashes NoDecode
    ProxyPass / http://localhost:3000/ nocanon
</VirtualHost>
```

Note: The following Apache HTTPD mods must be enabled: `proxy`, `proxy_http`.

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):

```apacheconf
<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
</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`.

## Caddy

If you want Caddy to serve your Gitea instance, you can add the following server block to your Caddyfile:

```apacheconf
git.example.com {
    reverse_proxy localhost:3000
}
```

If you still use Caddy v1, use:

```apacheconf
git.example.com {
    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:

```apacheconf
git.example.com {
    route /git/* {
        uri strip_prefix /git
        reverse_proxy localhost:3000
    }
}
```

Or, for Caddy v1:

```apacheconf
git.example.com {
    proxy /git/ 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.

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:

- 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)

```xml
<?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).

```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"
```

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) :

```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.