Host ODK Central Docker images on GitHub container registry

Thanks for all the answers!
I went with GH Actions&Packages simply because it's all in one place.
Of course the images could be built elsewhere (CircleCI) or hosted elsewhere (DockerHub).

Storage for public repos is free, and it looks like GHA minutes won't be exhausted by commit frequency * build minutes. So AFAICT free lunch.

I totally missed https://hub.docker.com/r/getodk/pyxform-http. Are there other official ODK images for Central?

I'll post to showcases once/if I've got Central on Kubernetes to work.

2 Likes

the way i see it:

the service image could easily be prebuilt and distributed as a packaged container. but, building this image takes very little time to begin with.

the nginx image needs a little work: right now the SHAs/version tags of the submodule repos are built into it (files/prebuild/write-version.sh) as a part of the build process. somehow that information would have to be provided at run-time instead. prebuilding this image would definitely save some time.

the enketo image absolutely cannot be prepackaged. this is a limitation with enketo: its configuration is incorporated into its source code at build time.

the secrets image just contains local secret keys. it weighs nothing and does nothing at build time. but it's also pretty easy to prebuild, it's just a COPY command for a single script file.

so, the two images that can be easily prebuilt right now is really cheap to build. the rest take some work and a mountain of work respectively.

1 Like

Help me understand:
The nginx images runs a command that generates version tags. If GHA would rebuild the image on every push, wouldn't that solve that problem by keeping the version info up to date?

Re enketo config: isn't that similar to the service config? In Kubernetes, files can be provided through a configmap, which is a key-value store of filename - filecontent. Configmaps are mounted as volumes to the running container. This provides any file configs (such as https://github.com/dbca-wa/central/blob/master/enketo.dockerfile#L13-L14) at runtime.
Does https://github.com/dbca-wa/central/blob/master/enketo.dockerfile#L6-L11 mean that "mounting config at runtime" won't work?

nginx:
no. it's a cross-dependency. the frontend is served statically by nginx. it needs to report to the user the version of the frontend and the backend and the central repositories. this cannot be done just by building the image when the frontend is updated.

enketo:
no. like, when enketo is compiled from source, it bakes its configuration in. it is not like a normal service where upon boot enketo will read from a file on disk.

1 Like

So the nginx and service images would have to be rebuilt both together whenever either frontend or backend change? Would that keep the version numbers in sync?

And enketo's config requires the user-defined value domain, got it. So until enketo allows to provide domain at runtime, every user has to build it themselves with their respective value for domain.

So the nginx and service images would have to be rebuilt both together whenever either frontend or backend change? Would that keep the version numbers in sync?

yes.

and the enketo situation is afaik being addressed. so this dream may yet happen. i'd be all for prebuilding more.

3 Likes

Yay! Nginx/service could easily be built and pushed by GH actions. Is that something you'd consider a PR for?

Good news about enketo too. Is that discussion happening in the open?

The Enketo PR to pull client settings out of the build is at https://github.com/enketo/enketo-express/pull/210. The next step will be to update the image: https://github.com/enketo/enketo-express/issues/161.

2 Likes

I'm playing around building our own enketo image. So far, I've removed the parts of

COPY files/enketo/config.json.template ${ENKETO_SRC_DIR}/config/config.json.template
COPY files/enketo/config.json.template ${ENKETO_SRC_DIR}/config/config.json

in the Dockerfile and removed this line from start-enketo.sh:

/bin/bash -c "SECRET=$(cat /etc/secrets/enketo-secret) LESS_SECRET=$(cat /etc/secrets/enketo-less-secret) API_KEY=$(cat /etc/secrets/enketo-api-key) envsubst '\$DOMAIN:\$SECRET:\$LESS_SECRET:\$API_KEY:\$SUPPORT_EMAIL' < ${CONFIG_PATH}.template > $CONFIG_PATH"

I will mount the completely rendered config.json at run time into the container. As far as I can see, this works without any problems...

Did I miss something?

This will work as long as you’re ok with anyone who gets the URL of your server being able to make API requests and/or you have some other way of limiting access to the Enketo install. What you’ve done is used the default, insecure API keys instead of generating ones specific to your server install. Having API access to Enketo means being able to read all form definitions on that server, publish new forms, and possibly read some form data.

This is not secure enough for the standard install but could possibly meet your needs.

EDIT: I now see you’re copying in the generated config file with secrets. As far as I know those won’t be picked up until you rebuild but you should double check this.

Now I remember that this commit came in last year which should make it possible to pick up new configuration items without rebuilding. We intended to do some verification around it but never had a chance to.

2 Likes

Is this tangentially related to SSL certificates for DB connections?
If the Enketo secrets can be provided at runtime, could SSL certificates be provided too? (I remember that between knex and slonik, one needs a file path, the other file contents.)

It works like a charm for us. We've also tested if we could create enketo links if our api key in Central is different than in Enketo. The result was: no.

We've also removed the secrets from the docker volume, so we won't lose them if sbd. accidentally executes docker-compose down.

As far as I can tell there is currently no technical obstacle anymore to provide pre-build docker images. If you are interested, I could make a PR with a new setup.

3 Likes

This could be interesting and would simplify a possible deployment in kubernetes. I'm I right?

It'd be great to see a draft PR so we see what the changes are. If you have a public repo, you can share that too. My hope is that we can add this to Central.

Thank you, @yanokwa ! I'll have a look in two weeks, if I can fit this task in our next sprint.

1 Like

FYI: I've just started working on this.

3 Likes

Here it is: I'm very excited about your feedback!

4 Likes

Thanks for starting making PR! I will try it out and leave any feedback.

Additionally I was wondering if anyone has started on this:

A distant dream would be a working helm chart for ODK Central 3,

In any event, a project we are starting soon could include some work on such a Helm chart.

That's for getting the ball rolling again @TobiasMcNulty with PR #546 :tada:

Did you start on a Helm chart by any chance? I have done this a few times before & would happily contribute one - just don't want to duplicate efforts!