Running Gogs behind a reverse proxy allows you to serve it on standard ports (80/443) with a clean and nice URL in the browser address bar, add TLS termination, and integrate with existing web server infrastructure.
Make sure the EXTERNAL_URL in your custom/conf/app.ini matches the actual URL users will access. When using a reverse proxy for TLS termination, keep PROTOCOL = http in Gogs and set EXTERNAL_URL to https://. The reverse proxy handles the encryption, and Gogs communicates with it over plain HTTP on the local network.
Caddy
Add the following server block to your Caddyfile and reload:gogs.example.com {
proxy / http://localhost:3000
}
Set the matching external URL in custom/conf/app.ini:[server]
EXTERNAL_URL = https://gogs.example.com/
Caddy automatically provisions TLS certificates via Let’s Encrypt when you use a domain name.
To serve Gogs under a subpath, note the trailing /:example.com {
proxy /gogs/ http://localhost:3000
}
Set the matching external URL in custom/conf/app.ini:[server]
EXTERNAL_URL = https://example.com/gogs/
NGINX
Add the following server block inside the http section of your nginx.conf (or in a file under sites-available), then reload the NGINX configuration:server {
listen 80;
server_name gogs.example.com;
location / {
proxy_pass http://localhost:3000;
}
}
Set the matching external URL in custom/conf/app.ini:[server]
EXTERNAL_URL = http://gogs.example.com/
To serve Gogs under a subpath, note the trailing / on both the location and proxy_pass directives:server {
listen 80;
server_name example.com;
location /gogs/ {
proxy_pass http://localhost:3000/;
}
}
Set the matching external URL in custom/conf/app.ini:[server]
EXTERNAL_URL = http://example.com/gogs/
Install Certbot and obtain a Let’s Encrypt certificate:sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d gogs.example.com
Certbot will automatically modify your Nginx configuration to use HTTPS. Your Nginx server block will look similar to:server {
listen 443 ssl;
server_name gogs.example.com;
ssl_certificate /etc/letsencrypt/live/gogs.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/gogs.example.com/privkey.pem;
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;
}
}
server {
listen 80;
server_name gogs.example.com;
return 301 https://$host$request_uri;
}
Set the matching external URL in custom/conf/app.ini:[server]
EXTERNAL_URL = https://gogs.example.com/
Certbot sets up automatic renewal via a cron job or systemd timer. Verify with:sudo certbot renew --dry-run
Large file uploads
If you encounter HTTP 413 Request Entity Too Large errors when pushing large files through NGINX, add client_max_body_size to your server block:
server {
listen 80;
server_name gogs.example.com;
client_max_body_size 50m;
location / {
proxy_pass http://localhost:3000;
}
}
Adjust the client_max_body_size value to match or exceed the maximum file size you expect users to push. The default NGINX limit is only 1 MB.
Apache 2
Create or edit your virtual host configuration file (e.g. /etc/apache2/vhost.d/gogs.conf):<VirtualHost *:80>
ServerName gogs.example.com
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://127.0.0.1:3000
ProxyPassReverse / http://127.0.0.1:3000
</VirtualHost>
Set the matching external URL in custom/conf/app.ini:[server]
EXTERNAL_URL = http://gogs.example.com/
To serve Gogs under a subpath, omit the trailing slash after the port number in the ProxyPass directives:<VirtualHost *:80>
ServerName example.com
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPass /gogs http://127.0.0.1:3000
ProxyPassReverse /gogs http://127.0.0.1:3000
</VirtualHost>
Set the matching external URL in custom/conf/app.ini:[server]
EXTERNAL_URL = http://example.com/gogs/
Enable the ssl module in addition to the proxy modules:sudo a2enmod proxy proxy_http ssl
sudo systemctl restart apache2
Apache virtual host configuration:<VirtualHost *:443>
ServerName gogs.example.com
SSLEngine on
SSLCertificateFile /path/to/cert.pem
SSLCertificateKeyFile /path/to/key.pem
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://127.0.0.1:3000/
ProxyPassReverse / http://127.0.0.1:3000/
</VirtualHost>
# Redirect HTTP to HTTPS
<VirtualHost *:80>
ServerName gogs.example.com
Redirect permanent / https://gogs.example.com/
</VirtualHost>
Set the matching external URL in custom/conf/app.ini:[server]
EXTERNAL_URL = https://gogs.example.com/
lighttpd
Add the following to your lighttpd configuration:server.modules += ( "mod_proxy" )
$HTTP["host"] == "gogs.example.com" {
proxy.server = ( "" => ( ( "host" => "127.0.0.1", "port" => "3000" ) ) )
}
Set the matching external URL in custom/conf/app.ini:[server]
EXTERNAL_URL = http://gogs.example.com/
To serve Gogs under a subpath, requires lighttpd 1.4.46 or later for the proxy.header directive:server.modules += ( "mod_proxy" )
$HTTP["url"] =~ "^/gogs/" {
proxy.server = ( "" => ( ( "host" => "localhost", "port" => "3000" ) ) )
proxy.header = ( "map-urlpath" => ( "/gogs/" => "/" ) )
}
Set the matching external URL in custom/conf/app.ini:[server]
EXTERNAL_URL = http://example.com/gogs/
IIS
Create a new website in IIS and use the following web.config file.
If you do not need HTTPS handled by IIS, remove the entire RedirectToHttps rule section from the configuration below.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.webServer>
<rewrite>
<rules>
<rule name="RedirectToHttps" stopProcessing="true">
<match url=".*" />
<conditions>
<add input="{HTTPS}" pattern="off" ignoreCase="true" />
</conditions>
<action type="Redirect"
url="https://{HTTP_HOST}{REQUEST_URI}"
redirectType="Permanent"
appendQueryString="false" />
</rule>
<rule name="ReverseProxyInboundRule" stopProcessing="true">
<match url="(.*)" />
<action type="Rewrite"
url="http://localhost:3000/{R:1}" />
</rule>
</rules>
<outboundRules>
<rule name="ReverseProxyOutboundRule"
preCondition="ResponseIsHtml">
<match filterByTags="A, Form, Img"
pattern="^http(s)?://localhost:3000/(.*)" />
<action type="Rewrite"
value="http{R:1}://gogs.example.com/{R:2}" />
</rule>
<preConditions>
<preCondition name="ResponseIsHtml">
<add input="{RESPONSE_CONTENT_TYPE}"
pattern="^text/html" />
</preCondition>
</preConditions>
</outboundRules>
</rewrite>
</system.webServer>
</configuration>
Then set the matching external URL in custom/conf/app.ini:
[server]
EXTERNAL_URL = https://gogs.example.com/
Native HTTPS
If you are not using a reverse proxy, Gogs can serve HTTPS directly. Update the [server] section of custom/conf/app.ini:
[server]
PROTOCOL = https
EXTERNAL_URL = https://gogs.example.com/
CERT_FILE = custom/https/cert.pem
KEY_FILE = custom/https/key.pem
| Option | Description | Default |
|---|
PROTOCOL | Set to https to enable native TLS. | http |
CERT_FILE | Path to the TLS certificate file (PEM format). | custom/https/cert.pem |
KEY_FILE | Path to the TLS private key file (PEM format). | custom/https/key.pem |
TLS_MIN_VERSION | Minimum TLS version. Options: TLS10, TLS11, TLS12, TLS13. | TLS12 |