postgres icon indicating copy to clipboard operation
postgres copied to clipboard

Make it easier to test load all the `.sql` files during a `docker build` operation.

Open zero-below opened this issue 4 years ago • 0 comments

Issue: Make it easy to test load all files from docker-entrypoint-initdb.d and verify they work, during a docker build, without fully starting the final db instance.

I have a Dockerfile that does FROM postgis/postgis:10-3.0-alpine, which itself has FROM postgres:10-alpine or such. Then we add a bunch of machine generated .sql files into docker-entrypoint-initdb.d, to effectively create a readonly db artifact that can be used in our various environments. Sometimes we find issues where they don't integrate well in our final container we build (ex, one file creates an index on a column that changed in another). But we don't find out until we actually run the container. We actually used to do at the end of our Dockerfile a RUN /docker-entrypoint.sh postgres --describe-config to create that behaviour, but at some point a while back, the adding of the _pg_want_help function caused these options to short-circuit the db load process there (it always exits with success regardless of whether the docker-entrypoint-initdb.d files are valid or not).

In order to catch this at build time, I have created a hacked up dbtest.sh that sources the docker-entrypoint.sh, then runs a limited version of the startup process that basically does everything in _main except the final exec $@. But I'm concerned that this will be hard to keep in sync with the docker-entrypoint.sh if other changes are made in the future.

I feel like this would be best to modify the docker-entrypoint.sh to allow it to stub out that part of the startup into a separate function. Or, add a magic keyword to the docker-entrypoint.sh to activate special init-db-but-don't-launch behavior. It also feels like this would be generally useful for people, and also would maybe give people the option to create containers where the initdb.d stuff is already loaded into tables during the container build process (though that specific feature might be bad, too). In our case, /var/lib/postgresql/data isn't kept in the build, so the full load of the docker-entrypoint-initdb.d will happen on container load, which happens to work well for us.

I can create a PR, but was wondering if there are preferences here as to the preferred paths, first. I think option 3 below seems least disruptive, but also slightly harder to use for some users...

  1. Create a magic keyword that when docker-entrypoint.sh postgres-load-only and it does everything but the exec "$@" at the end of _main.
  2. Create a fake option docker-entrypoint.sh postgres --load-only that shell strips out and then lets the init start and then skips the exec "$@" at the end of _main
  3. Move all of the init stuff into a function called something like docker_init_all that takes almost everything out of _main into a function, and _main would just be effectively docker_init_all $@;exec "$@". Then a user could just source docker-entrypoint.sh and then docker_init_all to clone that functionality. In a dockerfile, it could look like RUN . /docker-entrypoint.sh ; docker_init_all

zero-below avatar May 11 '20 23:05 zero-below