Foreman with Docker alpine

I want to run Foreman within docker container. I am especially interested in running foreman in small docker alpine container. My attempt right now is failing while I am updateing gems:

journald_native.h:37:14: error: #error Cannot include <systemd/sd-journal.h>. Please use linux version with systemd-journal installed
#error Cannot include <systemd/sd-journal.h>. Please use linux version with systemd-journal installed

What is the best way skip this dependency and install foreman without logging using journald. It would be fine to just log to stdout.

If you’re talking about the main foreman application (from foreman.git) then bundle install --without journald should exclude the dependency.

Thank you very much ! Thats working and I was able to succeed the installation from source.

Is there a way to find out wich gems are actually needed to install… and restrict installation to that gems only. Or, vice verse, to get a list of gems that are not needed ?

Right now I’ve like 500 gems installed, and I doubt they are all needed.

You could take a look at the Dockerfile we have in the repo itself:

Note that we explicitly chose not to use Alpine because there may be dragons we don’t know about. Personally I’ve read a few horror stories about Alphine + musl, particular around DNS. The size overhead is worth the known base.

Yes you are right, I should have taken a closer look into the foreman git project itself.
Thank you very much !

… since I worked with checkout for version 1.19.1 I’ve overlooked the docker related stuff.

just worth mentioning that if you are playing around, it does get published on every commit at https://quay.io/repository/foreman/foreman

I am still working on Dockerfile using alpine (ruby:2.5-alpine).
Actually I can build everything. However I have the following major issue, If I use the approach as in the official git repo as follows:

  1. createing a temporary image to build foreman and
  2. copy some build products over to a clean/slim image

If doing so I end up in image/container that is not able to run rails as expected. Instead I encounter the following situation:

1.) there are only executables rails and rake in the /home/foreman/bin folder.

bash-5.0> ls bin
rails   rake

2.) I cannot run the foreman server (or any other rails application I guess):

bash-5.0> bin/rails 
Could not find rake-12.3.2 in any of the sources
Run `bundle install` to install missing gems. 

3.) if I again install the gems (something like “bundle install --without …”) then I am able to run command from step 2
4.) seems like all the gems are already compiled and somehow still cached, installation from step 3 is pretty fast (seems like there is no internet access needed)

Question: What is likely reason that rails installation is broken. (Because I did basically same steps as here: https://github.com/theforeman/foreman/blob/develop/Dockerfile)

Steps that failed in my setup with docker alpine:

  1. RUN ./node_modules/webpack/bin/webpack.js --config config/webpack.config.js && npm run analyze && rm -rf public/webpack/stats.json
  • npm run analyze: the analyze script is not available
  1. COPY --from=builder --chown=1001:1001 ${HOME}/.bundle/config ${HOME}/.bundle/config
  • because folder .bundle is empty

Please publish the dockerfile somewhere…

BTW, wait is your end goal for using alphine?

Here is my Dockerfile: https://pastebin.com/PEUaT96z
My goal is to run TheForeman in Docker-container in productive environment. I do prefer alpine linux because I am using already around 1 dozen containers based on alpine in productive environment (jenkins, ldap, postgres, nginx, postfix, …). I like mostly because of its small memory footprint.

I think the issue you face is the fact you remove sqlite during the build process, sadly due to a bug, a db is needed to run certain tasks, in order to solve it we use a in memory sqlite db during build process and remove it afterwards.

let us know how much smaller does it get, AFAIU it should not have a huge impact on actual container memory, maybe on image size, but would not expect less than 50-100MB… while the current image is around 600MB…

This isn’t really a bug but rather a design. For some tasks a database is required because validation determines limits based on database table columns. I’d love to get rid of this because it would also make packaging easier, but it’s probably going to be hard.

which validations do you refer to ? AFAIU apipie requires it (anything else?) and I’m not sure why would it need a running db to generate its configuration?

Perhaps @iNecas can enlighten us, but my understanding is that a field’s maximum length isn’t actually specified anywhere. Rather it looks at the database to determine this.

Note that personally I’d be heavily in favor of static models describing the fields rather than a runtime determination.

i’ve gave it a go, and it seems like the alpine ruby implementation makes some assumptions on where bundle configuration lives (it defaults to /usr/local/bundle/config) (see Image assumptions at https://hub.docker.com/_/ruby/).

I gave it a try at https://github.com/ohadlevy/foreman/commit/8995cba7c7c6f95e4f3ef55bee435254f2e8cc24

the resulting image can be pulled by using:
docker pull quay.io/ohadlevy/foreman:alpine

I ran out of time to give this a full run - hopefully it gets you on the right direction…

It does seems like the image size saving are significant… but I’m not sure if we are not missing anything.

REPOSITORY                             TAG                 IMAGE ID            CREATED             SIZE
quay.io/ohadlevy/foreman               alpine              dec2d9730520        15 minutes ago      360 MB
quay.io/foreman/foreman                develop             3184ccb498c2        2 hours ago         646 MB

Really interesting !
May I ask regarding your compose file: https://github.com/ohadlevy/foreman/blob/8995cba7c7c6f95e4f3ef55bee435254f2e8cc24/docker-compose.yml
What is purpose of containers/services: worker and redis ? How does they interact with main application ?

since 1.23 redis is used for cache, and worker is the background task executor that foreman uses (aka as dynflow).

@Marian_Thieme: When your container image is done, feel free to open a PR to add the Dockerfile to core. I believe it might become handy for some of our users.

Hi Timo, yes I will do, providing it is running smoothly in my envirnment.

1 Like