TLDR: I have some proposed changes to Ghost that I am interested in implementing. I’d like to check if these changes make sense and are something that upstream would be interested in, before starting on them.
Background
Right now Ghost is a stateful application, persisting some of its data or state to the localdisk (such as themes). This makes running a stateless container of the application, where one only needs to pass in the relevant configuration values (connection strings, etc) not currently possible.
Some pieces of state are stored external to the application environment.
- Database (and all of its data) can be external, with the connection information passed in as environment variables
- Uploaded assets can be stored externally, using a storage adapter.
From looking over the application code, I can identify the following pieces of data that, however, do not have this extractability:
-
routes.yaml
- stored incontent/settings
-
redirects.json
- stored incontent/data
- themes - stored in content/themes
I think for each of these types, it is feasible to change the application to not store this information on disk.
Proposal
I want to make upstream changes to Ghost that will allow it run in a containerized context without any need for persistent discs.
routes.yaml
Right now it is stored in content/settings
. A simple approach is to store the JSON in the settings
table. For the settings.value
column, we only allow 64KiB, so we may need to bump that. Looking at some of the examples in the test files (site_spec
) it looks like it would be difficult to normalize, but we could also do that as well.
In terms of compatibility, we could hook into app startup migration logic to run a one-time port of the routes.yaml
into the database. I’m biased towards that, as putting this information into the database seems desirable even outside of my specific stateless concerns. Otherwise, we can have the database-storage functionality be a config switch.
redirects.json
This one is stored in content/data
. We could move it to settings
, as well. Redirects is similar to the navigation
key
we store in the settings
database already, conceptually. A simple flat array. This one could also be normalized into its own redirects
table, if that seems worthwhile.
Likewise, here, we can hook into the app startup migration logic to do a one-time conversion of the on-disk file into the database, if the file exists. Or have a config switch.
themes
When storage adapters were added, themes were not migrated to use that same storage engine, though there was some plans around doing so. It seems like we could still resolve the theme zip from the same “storage connector” that we fetch other things to, and extract it to a temporary directory on startup.
The migration here is tricky. To mirror our storage
config flag, we could have a themeStorage
config flag that would need to be set for this to work. The themeStorage
would have the same API has the storage adapters, and would implement retrieval/saving of the zip.
Conclusion and misc contribution thoughts
In the contribution guidelines, it says that all non-issues need to be posted here, so I posted this here. I understand the need to keep feature-request issues from the backlog to avoid getting bogged down, but has there been consideration of allowing technical improvement/refactoring tickets/issues to be filed as issues? Especially if there is an interest or intent from the reporter to implement the change. Perhaps there could be an auto-expiration of such issues if no progress is made in X days. It feels strange to need to go outside my principal development platform to talk about developmental details.