Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add support for external server for serving the static assets #6311

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions conf/defaults.ini
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ enforce_domain = false
# The full public facing url
root_url = %(protocol)s://%(domain)s:%(http_port)s/

# The public facing url for static assets
# static_url = <calculated according to root_url>

# Log web requests
router_logging = false

Expand Down
4 changes: 4 additions & 0 deletions conf/sample.ini
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@
# If you use reverse proxy and sub path specify full url (with sub path)
;root_url = http://localhost:3000

# The public facing url where static assets are stored. This is the "public" directory
# from the grafana release (dont forget to setup CORS!)
;static_url = http://my-cdn.com/grafana/public

# Log web requests
;router_logging = false

Expand Down
17 changes: 17 additions & 0 deletions docs/sources/installation/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,23 @@ callback URL to be correct).
> in front of Grafana that exposes it through a subpath. In that
> case add the subpath to the end of this URL setting.

### static_url

The url where the front end files (HTML, JS, and CSS
files) are accessible. By default grafana is serving those in the same server.
For optimization you can put those files on a host optimized for serving static
files (like a CDN or S3 like server).

> **Note** You will need to setup CORS headers on your static server to make this work
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bit confused about line :) the CORS headers would be needed on the grafana-server http api, not the static server

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes.
Because system.js loads its JS using XHR, then the static server must have cors configured to enable XHR from the grafana server URL

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oh, yea your right


CORS settings example for Apache:

Header set Access-Control-Allow-Origin "*"

CORS settings example for Nginx:

add_header Access-Control-Allow-Origin "*";

### static_root_path

The path to the directory where the front end files (HTML, JS, and CSS
Expand Down
1 change: 1 addition & 0 deletions pkg/api/dtos/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ type IndexViewData struct {
Settings map[string]interface{}
AppUrl string
AppSubUrl string
AppStaticUrl string
GoogleAnalyticsId string
GoogleTagManagerId string
MainNavLinks []*NavLink
Expand Down
1 change: 1 addition & 0 deletions pkg/api/frontendsettings.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ func getFrontendSettingsMap(c *middleware.Context) (map[string]interface{}, erro
"datasources": datasources,
"panels": panels,
"appSubUrl": setting.AppSubUrl,
"appStaticUrl": setting.AppStaticUrl,
"allowOrgCreate": (setting.AllowUserOrgCreate && c.IsSignedIn) || c.IsGrafanaAdmin,
"authProxyEnabled": setting.AuthProxyEnabled,
"buildInfo": map[string]interface{}{
Expand Down
4 changes: 4 additions & 0 deletions pkg/api/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,15 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {

appUrl := setting.AppUrl
appSubUrl := setting.AppSubUrl
appStaticUrl := setting.AppStaticUrl

// special case when doing localhost call from phantomjs
if c.IsRenderCall {
appUrl = fmt.Sprintf("%s://localhost:%s", setting.Protocol, setting.HttpPort)
appSubUrl = ""
appStaticUrl = "public"
settings["appSubUrl"] = ""
settings["appStaticUrl"] = "public"
}

var data = dtos.IndexViewData{
Expand All @@ -62,6 +65,7 @@ func setIndexViewData(c *middleware.Context) (*dtos.IndexViewData, error) {
Settings: settings,
AppUrl: appUrl,
AppSubUrl: appSubUrl,
AppStaticUrl: appStaticUrl,
GoogleAnalyticsId: setting.GoogleAnalyticsId,
GoogleTagManagerId: setting.GoogleTagManagerId,
BuildVersion: setting.BuildVersion,
Expand Down
8 changes: 5 additions & 3 deletions pkg/setting/setting.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var (
Env string = DEV
AppUrl string
AppSubUrl string
AppStaticUrl string
InstanceName string

// build
Expand Down Expand Up @@ -172,7 +173,7 @@ func init() {
logger = log.New("settings")
}

func parseAppUrlAndSubUrl(section *ini.Section) (string, string) {
func parseAppUrlAndSubUrl(section *ini.Section) (string, string, string) {
Copy link
Member

@torkelo torkelo Oct 19, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems a bit strange, why mingle the public url parsing with the static url?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is for generating the default value, which is based on the public_url

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

but seems strange to have that in this function, or am I missing something?

appUrl := section.Key("root_url").MustString("http://localhost:3000/")
if appUrl[len(appUrl)-1] != '/' {
appUrl += "/"
Expand All @@ -184,8 +185,9 @@ func parseAppUrlAndSubUrl(section *ini.Section) (string, string) {
log.Fatal(4, "Invalid root_url(%s): %s", appUrl, err)
}
appSubUrl := strings.TrimSuffix(url.Path, "/")
appStaticUrl := section.Key("static_url").MustString(fmt.Sprintf("%s/public", appSubUrl))

return appUrl, appSubUrl
return appUrl, appSubUrl, appStaticUrl
}

func ToAbsUrl(relativeUrl string) string {
Expand Down Expand Up @@ -464,7 +466,7 @@ func NewConfigContext(args *CommandLineArgs) error {
PluginsPath = makeAbsolute(Cfg.Section("paths").Key("plugins").String(), HomePath)

server := Cfg.Section("server")
AppUrl, AppSubUrl = parseAppUrlAndSubUrl(server)
AppUrl, AppSubUrl, AppStaticUrl = parseAppUrlAndSubUrl(server)

Protocol = HTTP
if server.Key("protocol").MustString("http") == "https" {
Expand Down
11 changes: 10 additions & 1 deletion public/app/system.conf.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
function getBaseURL() {
"use strict";
/* in the case of system.build, window is undefined
We should still pull the plugins from the CDN*/
if(typeof(window) === "undefined") {
return "public";
}
return window.grafanaBootData.settings.appStaticUrl || "public";
}
System.config({
defaultJSExtenions: true,
baseURL: 'public',
baseURL: getBaseURL(),
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure if this change is necessary.
Do the plugin system uses this? in this case this is necessary. If its only the config for the boot.js generation, then I will remove the change.
Please advise.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you cannot change baseURL in system.conf some things are loaded async (plugins and some sections)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dont we want to load those things from the static server? In this case, we need to have system.conf point to the static server.

So for the build, we need it to point to local filesystem 'public', but for the production, we need it to point to the static server.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

non core plugins are fetched via a special route public/plugins/ so this approach wont work.

paths: {
'remarkable': 'vendor/npm/remarkable/dist/remarkable.js',
'tether': 'vendor/npm/tether/dist/js/tether.js',
Expand Down
4 changes: 2 additions & 2 deletions public/views/500.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@

<title>Grafana</title>

<link rel="stylesheet" href="[[.AppSubUrl]]/public/css/grafana.dark.min.css" title="Dark">
<link rel="icon" type="image/png" href="[[.AppSubUrl]]/public/img/fav32.png">
<link rel="stylesheet" href="[[.AppStaticUrl]]/css/grafana.dark.min.css" title="Dark">
<link rel="icon" type="image/png" href="[[.AppStaticUrl]]/img/fav32.png">

</head>

Expand Down
18 changes: 9 additions & 9 deletions public/views/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@

<title>Grafana</title>

<link href='[[.AppSubUrl]]/public/css/fonts.min.css' rel='stylesheet' type='text/css'>
<link href='[[.AppStaticUrl]]/css/fonts.min.css' rel='stylesheet' type='text/css'>

[[if .User.LightTheme]]
<link rel="stylesheet" href="[[.AppSubUrl]]/public/css/grafana.light.min.css">
<link rel="stylesheet" href="[[.AppStaticUrl]]/css/grafana.light.min.css">
[[else]]
<link rel="stylesheet" href="[[.AppSubUrl]]/public/css/grafana.dark.min.css">
<link rel="stylesheet" href="[[.AppStaticUrl]]/css/grafana.dark.min.css">
[[end]]

<link rel="icon" type="image/png" href="[[.AppSubUrl]]/public/img/fav32.png">
<link rel="icon" type="image/png" href="[[.AppStaticUrl]]/img/fav32.png">
<base href="[[.AppSubUrl]]/" />

</head>
Expand Down Expand Up @@ -84,11 +84,11 @@
};
</script>

<!-- build:js [[.AppSubUrl]]/public/app/boot.js -->
<script src="[[.AppSubUrl]]/public/vendor/npm/es6-shim/es6-shim.js"></script>
<script src="[[.AppSubUrl]]/public/vendor/npm/systemjs/dist/system.src.js"></script>
<script src="[[.AppSubUrl]]/public/app/system.conf.js"></script>
<script src="[[.AppSubUrl]]/public/app/boot.js"></script>
<!-- build:js [[.AppStaticUrl]]/app/boot.js -->
<script src="[[.AppStaticUrl]]/vendor/npm/es6-shim/es6-shim.js"></script>
<script src="[[.AppStaticUrl]]/vendor/npm/systemjs/dist/system.src.js"></script>
<script src="[[.AppStaticUrl]]/app/system.conf.js"></script>
<script src="[[.AppStaticUrl]]/app/boot.js"></script>
<!-- endbuild -->

[[if .GoogleAnalyticsId]]
Expand Down
6 changes: 3 additions & 3 deletions tasks/build_task.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,16 @@ module.exports = function(grunt) {
'uglify:genDir'
]);

// task to add [[.AppSubUrl]] to reved path
// task to add [[.AppStaticUrl]] to reved path
grunt.registerTask('remapFilerev', function() {
var root = grunt.config().genDir;
var summary = grunt.filerev.summary;
var fixed = {};

for(var key in summary){
if(summary.hasOwnProperty(key)){
var orig = key.replace(root, root+'/[[.AppSubUrl]]/public');
var revved = summary[key].replace(root, root+'/[[.AppSubUrl]]/public');
var orig = key.replace(root, root+'/[[.AppStaticUrl]]');
var revved = summary[key].replace(root, root+'/[[.AppStaticUrl]]');
fixed[orig] = revved;
}
}
Expand Down