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

Configuration: audit, clean, extend & improve #7488

Closed
12 tasks done
ErisDS opened this issue Oct 5, 2016 · 12 comments
Closed
12 tasks done

Configuration: audit, clean, extend & improve #7488

ErisDS opened this issue Oct 5, 2016 · 12 comments
Assignees
Labels
server / core Issues relating to the server or core of Ghost

Comments

@ErisDS
Copy link
Member

ErisDS commented Oct 5, 2016

As the refactor of config is done, and we've had a chance to use it for a little while, it would be good to revisit it again before the end of alpha. There are a couple of outstanding todos from #6982 plus I'd like to look at what config options we provide. Do they make sense? Are there some things which should not be config? Some things which should be and aren't?

Things that definitely need review/audit:

- [ ] catch the error thrown from nconf, and rethrow it in a prettyier, clearer, more Ghost-like fashion (see #7488 (comment)):

/Users/hannah/Ghost/node_modules/nconf/lib/nconf/stores/file.js:160
    throw new Error("Error parsing your configuration file: [" + this.file + ']: ' + ex.message);
    ^

Error: Error parsing your configuration file: [/Users/hannah/Ghost/config.development.json]: Unexpected token d
...

Anyone who has something else they'd like reconsidered, please add a comment!

TODOs from #6982:

  • revisit the use of keys with nconf's .file()
  • remove the default database config, add client to the config.development.json file

TODO's from #7692

  • remove config.set('theme:..`), look at the TODO written in the PR

Issue fixes

@ErisDS ErisDS added config server / core Issues relating to the server or core of Ghost labels Oct 5, 2016
@ErisDS ErisDS added this to the 1.0.0-alpha.6 milestone Oct 5, 2016
kirrg001 pushed a commit that referenced this issue Oct 10, 2016
refs #7488 

If you want to set properties for our configuration values using
environment variables on the command line, Linux and MacOS return an
invalid identifier error.

```
$ export database:connection:host=127.0.0.1
-bash: export: `database:connection:host=127.0.0.1': not a valid
identifier
```

According to the nconf documentation a custom separator can be set. The
docs suggest `'__'` which this PR adds.
kirrg001 added a commit to kirrg001/Ghost that referenced this issue Oct 10, 2016
refs TryGhost#7488

- if multiple projects use nconf, they all operate on the same cached nconf instance
- that can cause trouble
ErisDS pushed a commit that referenced this issue Oct 10, 2016
refs #7488

- if multiple projects use nconf, they all operate on the same cached nconf instance
- that can cause trouble
@ErisDS
Copy link
Member Author

ErisDS commented Oct 13, 2016

I just added a todo here to revist all of our checks against config.get('env') to see if some can be moved to be config. E.g. the checks which prevent rpc pings unless we're in production could be configuration overrides added to the defaults or to the default testing & dev envs.

@kirrg001
Copy link
Contributor

E.g. the checks which prevent rpc pings unless we're in production could be configuration overrides added to the defaults or to the default testing & dev envs.

Can you show an example?maybe pseudo code?

@ErisDS
Copy link
Member Author

ErisDS commented Oct 13, 2016

Instead of doing if (config.get('env') === 'production') we would have if (config.get('enableRPCPings')) or something.
I'm just suggesting that where possible, we should use a specific/named config variable

@kirrg001
Copy link
Contributor

Agree, if a unit can be enabled or disabled per product definition, then it would makes sense 👍

ErisDS added a commit to ErisDS/Ghost that referenced this issue Oct 13, 2016
kirrg001 pushed a commit that referenced this issue Oct 13, 2016
closes #4172, closes #6948, refs #7491, refs #7488, refs #7542, refs #7484

* 🎨 Co-locate all admin-related code in /admin
- move all the admin related code from controllers, routes and helpers into a single location
- add error handling middleware explicitly to adminApp
- re-order blogApp middleware to ensure the shared middleware is mounted after the adminApp
- TODO: rethink the structure of /admin, this should probably be an internal app

* 💄 Group global middleware together

- There are only a few pieces of middleware which are "global"
- These are needed for the admin, blog and api
- Everything else is only needed in one or two places

* ✨ Introduce a separate blogApp

- create a brand-new blogApp
- mount all blog/theme only middleware etc onto blogApp
- mount error handling on blogApp only

* 🎨 Separate error handling for HTML & API JSON

- split JSON and HTML error handling into separate functions
- re-introduce a way to not output the stack for certain errors
- add more tests around errors & an assertion framework for checking JSON Errors
- TODO: better 404 handling for static assets

Rationale:

The API is very different to the blog/admin panel:
 - It is intended to only ever serve JSON, never HTML responses
 - It is intended to always serve JSON

Meanwhile the blog and admin panel have no need for JSON errors,
when an error happens on those pages, we should serve HTML pages
which are nicely formatted with the error & using the correct template

* 🐛 Fix checkSSL to work for subapps

- in order to make this work on a sub app we need to use the pattern `req.originalUrl || req.url`

* 🔥 Get rid of decide-is-admin (part 1/2)

- delete decide-is-admin & tests
- add two small functions to apiApp and adminApp to set res.isAdmin
- mount checkSSL on all the apps
- TODO: deduplicate the calls to checkSSL by making blogApp a subApp :D
- PART 2/2: finish cleaning this up by removing it from where it's not needed and giving it a more specific name

Rationale:

Now that we have both an adminApp and an apiApp,
we can temporarily replace this weird path-matching middleware
with middleware that sets res.isAdmin for api & admin

* 🎨 Wire up prettyURLs on all Apps

- prettyURLs is needed for all requests
- it cannot be global because it has to live after asset middleware, and before routing
- this does not result in duplicate redirects, but does result in duplicate checks
- TODO: resolve extra middleware in stack by making blogApp a sub app

* ⏱ Add debug to API setup

* 🎨 Rename blogApp -> parentApp in middleware

* 🎨 Co-locate all blog-related code in /blog

- Move all of the blogApp code from middleware/index.js to blog/app.js
- Move routes/frontend.js to blog/routes.js
- Remove the routes/index.js and routes folder, this is empty now!
- @todo is blog the best name for this? 🤔
- @todo sort out the big hunk of asset-related mess
- @todo also separate out the concept of theme from blog

* 🎉 Replace middleware index with server/app.js

- The final piece of the puzzle! 🎉 🎈 🎂
- We no longer have our horrendous middleware/index.js
- Instead, we have a set of app.js files, which all use a familiar pattern

* 💄 Error handling fixups
@ErisDS ErisDS modified the milestone: 1.0.0-alpha.6 Oct 24, 2016
mixonic pushed a commit to mixonic/Ghost that referenced this issue Oct 28, 2016
refs TryGhost#7488 

If you want to set properties for our configuration values using
environment variables on the command line, Linux and MacOS return an
invalid identifier error.

```
$ export database:connection:host=127.0.0.1
-bash: export: `database:connection:host=127.0.0.1': not a valid
identifier
```

According to the nconf documentation a custom separator can be set. The
docs suggest `'__'` which this PR adds.
mixonic pushed a commit to mixonic/Ghost that referenced this issue Oct 28, 2016
refs TryGhost#7488

- if multiple projects use nconf, they all operate on the same cached nconf instance
- that can cause trouble
mixonic pushed a commit to mixonic/Ghost that referenced this issue Oct 28, 2016
closes TryGhost#4172, closes TryGhost#6948, refs TryGhost#7491, refs TryGhost#7488, refs TryGhost#7542, refs TryGhost#7484

* 🎨 Co-locate all admin-related code in /admin
- move all the admin related code from controllers, routes and helpers into a single location
- add error handling middleware explicitly to adminApp
- re-order blogApp middleware to ensure the shared middleware is mounted after the adminApp
- TODO: rethink the structure of /admin, this should probably be an internal app

* 💄 Group global middleware together

- There are only a few pieces of middleware which are "global"
- These are needed for the admin, blog and api
- Everything else is only needed in one or two places

* ✨ Introduce a separate blogApp

- create a brand-new blogApp
- mount all blog/theme only middleware etc onto blogApp
- mount error handling on blogApp only

* 🎨 Separate error handling for HTML & API JSON

- split JSON and HTML error handling into separate functions
- re-introduce a way to not output the stack for certain errors
- add more tests around errors & an assertion framework for checking JSON Errors
- TODO: better 404 handling for static assets

Rationale:

The API is very different to the blog/admin panel:
 - It is intended to only ever serve JSON, never HTML responses
 - It is intended to always serve JSON

Meanwhile the blog and admin panel have no need for JSON errors,
when an error happens on those pages, we should serve HTML pages
which are nicely formatted with the error & using the correct template

* 🐛 Fix checkSSL to work for subapps

- in order to make this work on a sub app we need to use the pattern `req.originalUrl || req.url`

* 🔥 Get rid of decide-is-admin (part 1/2)

- delete decide-is-admin & tests
- add two small functions to apiApp and adminApp to set res.isAdmin
- mount checkSSL on all the apps
- TODO: deduplicate the calls to checkSSL by making blogApp a subApp :D
- PART 2/2: finish cleaning this up by removing it from where it's not needed and giving it a more specific name

Rationale:

Now that we have both an adminApp and an apiApp,
we can temporarily replace this weird path-matching middleware
with middleware that sets res.isAdmin for api & admin

* 🎨 Wire up prettyURLs on all Apps

- prettyURLs is needed for all requests
- it cannot be global because it has to live after asset middleware, and before routing
- this does not result in duplicate redirects, but does result in duplicate checks
- TODO: resolve extra middleware in stack by making blogApp a sub app

* ⏱ Add debug to API setup

* 🎨 Rename blogApp -> parentApp in middleware

* 🎨 Co-locate all blog-related code in /blog

- Move all of the blogApp code from middleware/index.js to blog/app.js
- Move routes/frontend.js to blog/routes.js
- Remove the routes/index.js and routes folder, this is empty now!
- @todo is blog the best name for this? 🤔
- @todo sort out the big hunk of asset-related mess
- @todo also separate out the concept of theme from blog

* 🎉 Replace middleware index with server/app.js

- The final piece of the puzzle! 🎉 🎈 🎂
- We no longer have our horrendous middleware/index.js
- Instead, we have a set of app.js files, which all use a familiar pattern

* 💄 Error handling fixups
geekhuyang pushed a commit to geekhuyang/Ghost that referenced this issue Nov 20, 2016
refs TryGhost#7488 

If you want to set properties for our configuration values using
environment variables on the command line, Linux and MacOS return an
invalid identifier error.

```
$ export database:connection:host=127.0.0.1
-bash: export: `database:connection:host=127.0.0.1': not a valid
identifier
```

According to the nconf documentation a custom separator can be set. The
docs suggest `'__'` which this PR adds.
geekhuyang pushed a commit to geekhuyang/Ghost that referenced this issue Nov 20, 2016
refs TryGhost#7488

- if multiple projects use nconf, they all operate on the same cached nconf instance
- that can cause trouble
geekhuyang pushed a commit to geekhuyang/Ghost that referenced this issue Nov 20, 2016
closes TryGhost#4172, closes TryGhost#6948, refs TryGhost#7491, refs TryGhost#7488, refs TryGhost#7542, refs TryGhost#7484

* 🎨 Co-locate all admin-related code in /admin
- move all the admin related code from controllers, routes and helpers into a single location
- add error handling middleware explicitly to adminApp
- re-order blogApp middleware to ensure the shared middleware is mounted after the adminApp
- TODO: rethink the structure of /admin, this should probably be an internal app

* 💄 Group global middleware together

- There are only a few pieces of middleware which are "global"
- These are needed for the admin, blog and api
- Everything else is only needed in one or two places

* ✨ Introduce a separate blogApp

- create a brand-new blogApp
- mount all blog/theme only middleware etc onto blogApp
- mount error handling on blogApp only

* 🎨 Separate error handling for HTML & API JSON

- split JSON and HTML error handling into separate functions
- re-introduce a way to not output the stack for certain errors
- add more tests around errors & an assertion framework for checking JSON Errors
- TODO: better 404 handling for static assets

Rationale:

The API is very different to the blog/admin panel:
 - It is intended to only ever serve JSON, never HTML responses
 - It is intended to always serve JSON

Meanwhile the blog and admin panel have no need for JSON errors,
when an error happens on those pages, we should serve HTML pages
which are nicely formatted with the error & using the correct template

* 🐛 Fix checkSSL to work for subapps

- in order to make this work on a sub app we need to use the pattern `req.originalUrl || req.url`

* 🔥 Get rid of decide-is-admin (part 1/2)

- delete decide-is-admin & tests
- add two small functions to apiApp and adminApp to set res.isAdmin
- mount checkSSL on all the apps
- TODO: deduplicate the calls to checkSSL by making blogApp a subApp :D
- PART 2/2: finish cleaning this up by removing it from where it's not needed and giving it a more specific name

Rationale:

Now that we have both an adminApp and an apiApp,
we can temporarily replace this weird path-matching middleware
with middleware that sets res.isAdmin for api & admin

* 🎨 Wire up prettyURLs on all Apps

- prettyURLs is needed for all requests
- it cannot be global because it has to live after asset middleware, and before routing
- this does not result in duplicate redirects, but does result in duplicate checks
- TODO: resolve extra middleware in stack by making blogApp a sub app

* ⏱ Add debug to API setup

* 🎨 Rename blogApp -> parentApp in middleware

* 🎨 Co-locate all blog-related code in /blog

- Move all of the blogApp code from middleware/index.js to blog/app.js
- Move routes/frontend.js to blog/routes.js
- Remove the routes/index.js and routes folder, this is empty now!
- @todo is blog the best name for this? 🤔
- @todo sort out the big hunk of asset-related mess
- @todo also separate out the concept of theme from blog

* 🎉 Replace middleware index with server/app.js

- The final piece of the puzzle! 🎉 🎈 🎂
- We no longer have our horrendous middleware/index.js
- Instead, we have a set of app.js files, which all use a familiar pattern

* 💄 Error handling fixups
@kirrg001
Copy link
Contributor

/Users/hannah/Ghost/node_modules/nconf/lib/nconf/stores/file.js:160
throw new Error("Error parsing your configuration file: [" + this.file + ']: ' + ex.message);
^
Error: Error parsing your configuration file: [/Users/hannah/Ghost/config.development.json]: Unexpected token d
...

If a custom config file can't be parsed, then Ghost won't be able to print a nice error, because logging depends on config! If config can't be load, logging can't be initialised. Even if we force logging to initialise with a default config, we would have to add try/catch statements to the logging adapter and to the bootstrapping of Ghost, because config loads synchronously! Or we could load config asynchronous. But all of this because we can't parse a JSON file?

I suggest that, as we have a config validation issue, which is committed as must have for 1.0.0, we only care in Ghost-CLI and show the user that his custom config file is invalid and that's why he can't start Ghost.

kirrg001 added a commit to kirrg001/Ghost that referenced this issue Feb 18, 2017
kirrg001 added a commit that referenced this issue Feb 18, 2017
* 🐛  delete client if auth url has changed

no issue

* 🎨  update default auth config

refs #7488
@ErisDS
Copy link
Member Author

ErisDS commented Mar 2, 2017

Couple of notes / thoughts as I'm moving around:

  • reconsider: in overrides.json, times key needs to be changed to something like scheduling as it is part of that aspect of Ghost.
  • minifyAssets needs revisiting as it is doesn't do anything really
  • internalApps should possibly be apps.internal?
  • think about content paths:
    • I would like to make it possible at some point soon (not necessarily for 1.0) to change the path for where themes are stored - this would be the only available customisation, no adapters. we will keep it in mind
    • I would like adapters to all live in /content/adapters by default, rather than having separate folders.

ErisDS added a commit to ErisDS/Ghost that referenced this issue Mar 7, 2017
refs TryGhost#7488, TryGhost#7491

- At the moment, we use the same asset helper function for both admin and theme
- Both functions are (rightly or wrongly) a wrapper around meta.getAssetUrl()
- The usecases in these contexts are v. different:
    - asset for the admin is used only in the generated index.html file
    - ghost="true" is always true in this case, except for the favicon which is ALREADY a separate case
    - minifyInProduction is only used to the admin panel, not documented or supposed to be used for themes
- For themes, the helper doesn't take any arguments, it should just call to getAssetUrl()
  If we do want to introduce some sort of .min path adjuster we should give it a better name!
- For the admin panel, minifyInProduction means exactly what it says - minify if env === production,
  it makes no sense IMO to move this to config because we control it and also plus "minifyAssets" made it
  sound like we had an asset pipeline when all this did was change the output from .js to .min.js or .css to .min.css
@kirrg001
Copy link
Contributor

@ErisDS How about creating smaller config issues, assign to the milestone if they are required for the beta and close this one?

ErisDS added a commit to ErisDS/Ghost that referenced this issue Mar 23, 2017
refs TryGhost#7488

- This has always been documented as top-level "compress", and yet the code references server.compress
- Should be top level, I think?
kirrg001 pushed a commit that referenced this issue Apr 3, 2017
refs #7488

- This has always been documented as top-level "compress", and yet the code references server.compress
- Should be top level
@kirrg001 kirrg001 added this to the 1.0.0 Launch milestone Apr 3, 2017
@kirrg001 kirrg001 removed this from the 1.0.0 Backlog milestone May 12, 2017
@kirrg001 kirrg001 self-assigned this May 25, 2017
@kirrg001
Copy link
Contributor

kirrg001 commented May 29, 2017

I just went over the last tasks from the issue.

in overrides.json, times key needs to be changed to something like scheduling as it is part of that aspect of Ghost.

We are using the times object for multiple purposes. e.g. scheduling and image size timeout. The idea was to start a collection with every possible static time configuration.

minifyAssets needs revisiting as it is doesn't do anything really

Was already removed and replaced by useMinFiles, see a413d70.

internalApps should possibly be apps.internal

yeah can do that in case we would like to add apps.external later 👍

I would like adapters to all live in /content/adapters by default, rather than having separate folders.

done already, see 1b965fa and be5b584

I would like to make it possible at some point soon (not necessarily for 1.0) to change the path for where themes are stored - this would be the only available customisation, no adapters.

We will keep that in mind.

should route keywords be configuration

Probably yes. I've tested a case a couple of days ago to change /subscribe to /something - it worked pretty good. But when looking at the priority and the effort (testing every single case), i would like to raise a (community) issue for now - can be also done by us after the beta. I will raise an issue for now.

configuration options for caching

Was partially done for theme and admin. I will also add it for the cache control.

our use of paths in overrides.json
revisit paths like /ghost/ and /ghost/api/

Not sure what to reconsider here 🤔 This needs more context.

kirrg001 added a commit to kirrg001/Ghost that referenced this issue May 29, 2017
refs TryGhost#7488

- simply rename the config usage
- we might want to add `apps.external` later
kirrg001 added a commit to kirrg001/Ghost that referenced this issue May 29, 2017
refs TryGhost#7488

- cache control can be overridden if needed
kevinansfield pushed a commit that referenced this issue May 31, 2017
refs #7488

- simply rename the config usage
- we might want to add `apps.external` later
kevinansfield pushed a commit that referenced this issue May 31, 2017
refs #7488

- cache control can be overridden if needed
@kirrg001
Copy link
Contributor

closed via #8491

@ErisDS
Copy link
Member Author

ErisDS commented Jun 5, 2017

I would like to make it possible at some point soon (not necessarily for 1.0) to change the path for where themes are stored - this would be the only available customisation, no adapters.

We will keep that in mind.

our use of paths in overrides.json
revisit paths like /ghost/ and /ghost/api/

Not sure what to reconsider here 🤔 This needs more context.

To clarify what I meant by this (sorry, I realise there is not anywhere near enough information), I was thinking about the fact that we have a huge block of "paths" in overrides.json, however:

The admin path, /ghost/ and the api path /ghost/api/ are not there, instead they are littered throughout the code base. This is a cleanup thing, not a breaking change so doesn't need to be looked at urgently.

Meanwhile with regard to the path for themes, that is derived from the ONLY path that is allowed to be overridden, because in defaults.json we have:

 "paths": {
        "contentPath": "content/"
    },

However, themePath is not something that can be overridden on its own, because it is calculated based on content path, using the getContentPath() function. I left an item here to reconsider this - is this the correct thing to do, or should all the individual content paths be items in the defaults.json that can be overridden individually? E.g.

 "paths": {
        "imagePath": "content/images",
        "themesPath": "content/themes"
    },

Again, don't think it's urgent, just wanted to clarify because I saw this. Let me know if it makes sense now?

@kirrg001
Copy link
Contributor

kirrg001 commented Jun 5, 2017

👍 Thank you!

I agree to the custom theme and image paths. We can add this later as a none breaking change and support both notations. You either specify a contentPath or override the content path by e.g. contentImagePath - if only one option is specified, it's possible to detect that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
server / core Issues relating to the server or core of Ghost
Projects
None yet
Development

No branches or pull requests

2 participants