From 00629fea95970e99ba5ef05954bbad0804805df6 Mon Sep 17 00:00:00 2001 From: Jakob Ackermann Date: Tue, 22 Oct 2019 14:11:01 +0200 Subject: [PATCH] [assets] configurable URL for static resources (#7911) * static url * add cors support for static resources * [assets] work on the migration to configurable url for assets Signed-off-by: Jakob Ackermann * [misc] fix whitespace Signed-off-by: Jakob Ackermann * [assets] fix the loading of the manifest.json It is generated dynamically, and as such can not be served by the cdn. Signed-off-by: Jakob Ackermann * Revert "add cors support for static resources" This reverts commit 42f964fd181dbb8b139808b9be623470d4f0e40f Signed-off-by: Jakob Ackermann * [docs] add the STATIC_URL_PREFIX option Signed-off-by: Jakob Ackermann * [docs] reverse-proxy: nginx: add two setups for STATIC_URL_PREFIX Signed-off-by: Jakob Ackermann * [assets] migrate the url of a new asset to the static url prefix REF: f2a3abc683ad4b2177b7c7c6160a2c0b4316120a Signed-off-by: Jakob Ackermann --- custom/conf/app.ini.sample | 2 + .../doc/advanced/config-cheat-sheet.en-us.md | 7 ++ .../doc/usage/reverse-proxies.en-us.md | 68 +++++++++++++++++ modules/setting/setting.go | 4 +- modules/templates/helper.go | 3 + templates/admin/hook_new.tmpl | 14 ++-- templates/base/footer.tmpl | 46 +++++------ templates/base/footer_content.tmpl | 2 +- templates/base/head.tmpl | 44 +++++------ templates/base/head_navbar.tmpl | 2 +- templates/home.tmpl | 2 +- templates/org/settings/hook_new.tmpl | 14 ++-- templates/pwa/manifest_json.tmpl | 10 +-- templates/pwa/serviceworker_js.tmpl | 76 +++++++++---------- templates/repo/migrating.tmpl | 2 +- templates/repo/settings/webhook/list.tmpl | 14 ++-- templates/repo/settings/webhook/new.tmpl | 14 ++-- templates/repo/view_file.tmpl | 2 +- templates/status/404.tmpl | 2 +- templates/status/500.tmpl | 2 +- templates/swagger/ui.tmpl | 10 +-- 21 files changed, 211 insertions(+), 129 deletions(-) diff --git a/custom/conf/app.ini.sample b/custom/conf/app.ini.sample index 337676016..f0204bb06 100644 --- a/custom/conf/app.ini.sample +++ b/custom/conf/app.ini.sample @@ -185,6 +185,8 @@ FILE_EXTENSIONS = .md,.markdown,.mdown,.mkd PROTOCOL = http DOMAIN = localhost ROOT_URL = %(PROTOCOL)s://%(DOMAIN)s:%(HTTP_PORT)s/ +; when STATIC_URL_PREFIX is empty it will follow APP_URL +STATIC_URL_PREFIX = ; The address to listen on. Either a IPv4/IPv6 address or the path to a unix socket. HTTP_ADDR = 0.0.0.0 HTTP_PORT = 3000 diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index f99e9f661..c2744b295 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -138,6 +138,13 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`. - `ROOT_URL`: **%(PROTOCOL)s://%(DOMAIN)s:%(HTTP\_PORT)s/**: Overwrite the automatically generated public URL. This is useful if the internal and the external URL don't match (e.g. in Docker). +- `STATIC_URL_PREFIX`: **\**: + Overwrite this option to request static resources from a different URL. + This includes CSS files, images, JS files and web fonts. + Avatar images are dynamic resources and still served by gitea. + The option can be just a different path, as in `/static`, or another domain, as in `https://cdn.example.com`. + Requests are then made as `%(ROOT_URL)s/static/css/index.css` and `https://cdn.example.com/css/index.css` respective. + The static files are located in the `public/` directory of the gitea source repository. - `HTTP_ADDR`: **0.0.0.0**: HTTP listen address. - If `PROTOCOL` is set to `fcgi`, Gitea will listen for FastCGI requests on TCP socket defined by `HTTP_ADDR` and `HTTP_PORT` configuration settings. diff --git a/docs/content/doc/usage/reverse-proxies.en-us.md b/docs/content/doc/usage/reverse-proxies.en-us.md index 47a5b9557..55c8bb971 100644 --- a/docs/content/doc/usage/reverse-proxies.en-us.md +++ b/docs/content/doc/usage/reverse-proxies.en-us.md @@ -44,6 +44,74 @@ server { Then set `[server] ROOT_URL = http://git.example.com/git/` in your configuration. +## Using Nginx as a reverse proxy 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 snap shot of the gitea source repository to `/path/to/gitea/`. + +We are only interested in the `public/` directory and you can delete the rest. + +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. + +### using a single node and a single domain + +Set `[server] STATIC_URL_PREFIX = /_/static` in your configuration. + +``` +server { + listen 80; + server_name git.example.com; + + location /_/static { + alias /path/to/gitea/public; + } + + location / { + proxy_pass http://localhost:3000; + } +} +``` + +### using 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 / { + 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; + } +} +``` + ## Using Apache HTTPD as a reverse proxy 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): diff --git a/modules/setting/setting.go b/modules/setting/setting.go index d05c52fea..f3dd45d7b 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -99,6 +99,7 @@ var ( LetsEncryptEmail string GracefulRestartable bool GracefulHammerTime time.Duration + StaticURLPrefix string SSH = struct { Disabled bool `ini:"DISABLE_SSH"` @@ -573,7 +574,7 @@ func NewContext() { defaultAppURL += ":" + HTTPPort } AppURL = sec.Key("ROOT_URL").MustString(defaultAppURL) - AppURL = strings.TrimRight(AppURL, "/") + "/" + AppURL = strings.TrimSuffix(AppURL, "/") + "/" // Check if has app suburl. appURL, err := url.Parse(AppURL) @@ -583,6 +584,7 @@ func NewContext() { // Suburl should start with '/' and end without '/', such as '/{subpath}'. // This value is empty if site does not have sub-url. AppSubURL = strings.TrimSuffix(appURL.Path, "/") + StaticURLPrefix = strings.TrimSuffix(sec.Key("STATIC_URL_PREFIX").MustString(AppSubURL), "/") AppSubURLDepth = strings.Count(AppSubURL, "/") // Check if Domain differs from AppURL domain than update it to AppURL's domain // TODO: Can be replaced with url.Hostname() when minimal GoLang version is 1.8 diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 9bb803c01..b5287bf97 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -48,6 +48,9 @@ func NewFuncMap() []template.FuncMap { "AppSubUrl": func() string { return setting.AppSubURL }, + "StaticUrlPrefix": func() string { + return setting.StaticURLPrefix + }, "AppUrl": func() string { return setting.AppURL }, diff --git a/templates/admin/hook_new.tmpl b/templates/admin/hook_new.tmpl index c047efe9a..2292377f6 100644 --- a/templates/admin/hook_new.tmpl +++ b/templates/admin/hook_new.tmpl @@ -11,19 +11,19 @@ {{end}}
{{if eq .HookType "gitea"}} - + {{else if eq .HookType "gogs"}} - + {{else if eq .HookType "slack"}} - + {{else if eq .HookType "discord"}} - + {{else if eq .HookType "dingtalk"}} - + {{else if eq .HookType "telegram"}} - + {{else if eq .HookType "msteams"}} - + {{end}}
diff --git a/templates/base/footer.tmpl b/templates/base/footer.tmpl index 13718620d..7185b2037 100644 --- a/templates/base/footer.tmpl +++ b/templates/base/footer.tmpl @@ -12,38 +12,38 @@ {{template "base/footer_content" .}} - - - + + + {{if .RequireSimpleMDE}} - - - + + + {{end}} {{if .RequireGitGraph}} - - + + {{end}} {{if .RequireHighlightJS}} - + {{end}} {{if .RequireMinicolors}} - + {{end}} {{if .RequireDatetimepicker}} - + {{end}} {{if .RequireDropzone}} - + {{end}} {{if .RequireU2F}} - + {{end}} {{if .EnableCaptcha}} {{if eq .CaptchaType "recaptcha"}} @@ -51,7 +51,7 @@ {{end}} {{end}} {{if .RequireTribute}} - + {{end}} - - - + + + - - + + {{if .EnableHeatmap}} - - + + diff --git a/templates/base/footer_content.tmpl b/templates/base/footer_content.tmpl index 6f680d4cb..364e58a3d 100644 --- a/templates/base/footer_content.tmpl +++ b/templates/base/footer_content.tmpl @@ -16,7 +16,7 @@ {{end}} - JavaScript licenses + JavaScript licenses {{if .EnableSwagger}}API{{end}} {{.i18n.Tr "website"}} {{if (or .ShowFooterVersion .PageIsAdmin)}}{{GoVer}}{{end}} diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index 7cdfdd34b..ae2b6b954 100644 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -70,35 +70,35 @@ THE SOFTWARE. --- Licensing information for additional javascript libraries can be found at: - {{AppSubUrl}}/vendor/librejs.html + {{StaticUrlPrefix}}/vendor/librejs.html @licend The above is the entire license notice for the JavaScript code in this page. */`}} - - - - - + + + + + {{if .RequireSimpleMDE}} - + {{end}} {{if .RequireGitGraph}} - + {{end}} {{if .RequireTribute}} - + {{end}} - - + +