Docker: environment-based configuration

At least for the env variables we’re already loading through Docker-Compose, like the DB ones and SELF_URL_PATH, we could just make them available for the php-fpm process, and load them from config.php using getenv(). I made a simple proof of concept following these steps:

  1. add the -E flag to the last line of app/startup.sh i.e. sudo -E -u app /usr/sbin/php-fpm7 -F
  2. set clear_env = no at www.conf, from the app Dockerfile just before the memory_limit change, i.e. RUN sed -i.bak 's/;clear_env = .*/clear_env = no/i' /etc/php7/php-fpm.d/www.conf
  3. change config.php to read the env variables, e.g. define('DB_PASS', getenv('DB_PASS'));

Do you think this could be a reasonable approach?

yes, i think it’s a good idea (even though current sed hack is frankly not a high bar to clear), and i’ve seen it being done this way in other container setups.

a few random thoughts:

  • are there security implications of keeping the environment? i dunno
  • how do we handle extant tt-rss installations?

i would prefer to remove runtime rewriting entirely because its prone to breakage. container could ship prepared config.php with getenv()s in place and we could put it on a storage volume when it is first initialized. this way we won’t need to touch it on any further changes.

if people want to move to new environment-ready setup they’d just need to delete previously generated config.php and rebuild. otherwise, unless they change SELF_URL_PATH their existing config.php would just continue to work.

there’s only 29 relevant defines in config.php and they are rarely changes, it wouldn’t be hard to define relevant environment variables in the Dockerfile.

additionally, while we are at it, it would be a good idea to allow further customization of config.php - for example, if you need to add plugin-related defines. something like an optional config.d directory with optional snippets mapped into container that would be included into config.php at runtime.

I’m splitting this to a separate thread so it’s more visible.

We’re moving to an environment-based customization of compose setup instead of current sed-based limited hacks.

This way, the entirety of config.php can be overridden using environment variables passed to app & updater containers as needed.

No further modifications would be made for already existing config.php, this means all existing installations would just use old configuration.

Here’s the development branch for testing (dynamic setup) - https://git.tt-rss.org/fox/ttrss-docker-compose/src/branch/dynamic-getenv

Static development branch - https://git.tt-rss.org/fox/ttrss-docker-compose/src/branch/static-dockerhub-env

Q: What will change for my already installed tt-rss?
A: Nothing, you just won’t be able to change SELF_URL_PATH from .yml anymore, unless you move to the new setup

Q: How do I move to the new setup?
A: Move all customized config.php defines to .env, and delete config.php on the app storage volume so it gets recreated. Hopefully, you will never need to dig into it manually again.

Any additional things you might want to add to config.php go into ./config.d.

The following change prefixes all config-related environment variables with TTRSS_ in case we need to implement environment filtering later and to prevent potential clashes with other environment variables.

https://git.tt-rss.org/fox/ttrss-docker-compose/commit/99323f8665eb966a99752979141358c192b2d6d1

the only important consequence for this is SELF_URL_PATH in .env becoming TTRSS_SELF_URL_PATH.

since we keep previous config.php as-is i’m not sure if there’s any point in adding some kind of compatibility wrapper for self url path specifically.

What about storing these configs within the database with columns key and value? With a minimal GUI like browsers do in “about:config”. This way could end up with just two config-locations:

  • environment variables for pointing to the database and perhaps dev-logging stuff
  • config table (key-value store) in the database for everything else

This way dev and prod environments can easily be separated / configured. Symfony e. g. uses a similar approach.

no, i’m not going to move config.php contents to the database.

Are there reasons or things I did not think of?

seems like unneeded complexity that doesn’t bring anything you can’t do with a simple configuration file.

getenv() stuff is good enough, compatible with other deployments, and i don’t need to change anything.

i’m going to start merging this into normal static/dynamic branches, also new docker hub images are going to be built using environment-aware setup. heads up, etc.

this also includes image ttrss-fpm-pgsql-static:21.01-6d8f2221b which i’m going to rebuild using new scripts.

relevant development branches are going to be archived.

one important migration aspect is that if you try to use new docker images with old scripts, you’re likely going to have a bad time. so, update the scripts.

Hey @fox - I had asked you here about manually overriding the directories in nginx.conf… without having too clear an understanding how this change works, I was wondering if an environment variable for those overrides would be a thing?

Pretty please?

Out-of-the-box, nginx doesn’t support environment variables inside most configuration blocks.

:thinking:

Drats. Thanks for looking into it, though :slight_smile:

Hi

If I’m not mistaken there isn’t an environment variable for FEED_FETCH_NO_CACHE_TIMEOUT anymore. Is it possible to show me the error of my ways or add it?

Thanks

You are mistaken. https://git.tt-rss.org/fox/tt-rss/wiki/GlobalConfig

https://git.tt-rss.org/fox/tt-rss/src/branch/master/classes/config.php#L115

Make sure you prefix it with TTRSS_

Many thanks

Apologies, I’ll put myself on probation