Skip to content

Refactor Dockerfile#712

Open
crosspolar wants to merge 63 commits intomasterfrom
dockerfile_without_poetry_dev_dependencies
Open

Refactor Dockerfile#712
crosspolar wants to merge 63 commits intomasterfrom
dockerfile_without_poetry_dev_dependencies

Conversation

@crosspolar
Copy link
Copy Markdown
Contributor

@crosspolar crosspolar commented Nov 20, 2025

I've added a new dockerfile for prod

  • without dev to remove those dependencies from the final docker image
  • non-root-user

@crosspolar crosspolar force-pushed the dockerfile_without_poetry_dev_dependencies branch from b7bf055 to d5bf3b8 Compare November 24, 2025 07:07
@Theophile-Madet
Copy link
Copy Markdown
Collaborator

Looks great, I don't have time to test properly today but I keep it on my list.

It should make the images smaller which will make deployment faster, that's great.

@crosspolar crosspolar changed the title Dockerfile without poetry dev dependencies Refactor Dockerfile Nov 28, 2025
Copy link
Copy Markdown
Collaborator

@Theophile-Madet Theophile-Madet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I run docker compose build web (with the one backslash removed), then up -d web, I get the following error:

web-1  | The po files under /app/tapir/translations/locale/de/LC_MESSAGES are in a seemingly not writable location. mo files will not be updated/created.
web-1  | processing file django.po in /app/tapir/translations/locale/de/LC_MESSAGES
web-1  | CommandError: compilemessages generated one or more errors.

@crosspolar
Copy link
Copy Markdown
Contributor Author

crosspolar commented Dec 16, 2025

@Theophile-Madet : I think the mounted volume in the compose-file overwrites the already copied files and their permissions?! I moved the compilemessage into the dockerfile, what do you think? Do we have other write-operations?

@crosspolar
Copy link
Copy Markdown
Contributor Author

While I feel comfortable using docker, I still do mistakes. So I should be transparent, that I've used GPT5-mini for assistance (with which I mostly feel less comfortable, ironically)

@Theophile-Madet
Copy link
Copy Markdown
Collaborator

Theophile-Madet commented Jan 6, 2026

I think the mounted volume in the compose-file overwrites the already copied files and their permissions?!

It does, that's what we need: the files from the host machine being copied in the container when we develop, and the other way around if the container generates files.
The permission changes are sometimes annoying but I don't see a way around it?

I moved the compilemessage into the dockerfile, what do you think?

I think it's fine in the dockerfile 👍

Do we have other write-operations?

At what point? During development we write all the time.

I think we need Poetry to be installed in the dev version so that we can add or update packages from inside the container.

I'm not experienced with Docker either, we'll have to do what we can!

Copy link
Copy Markdown

@techge techge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay I had a complete look at it. But being honest, I do not feel competent to really evaluate the code. Much of it has to do with the tapir setup and environment details that I am not familiar with. What I have seen and what I did understand, did not look insane though.

So... LGTM in a way 😬 I am sorry.

run: docker compose run web make check-formatting
- name: Check translations
run: docker compose run web make check-translations
run: docker compose run --user=$(id -u):$(id -g) web make check-translations
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the user defined here and not in the Dockerfile/Docker Compose? I am not at all familiar in how to do it the right way, so this is not complaint, I just do not understand, why using it here and not on other places as well/in the main definition.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In docker-compose it's luck I guess that user on docker and my machine is the same, but github was different. If your local machine would be different you would need an .env (I will add the documentation) and maybe better here would be UID=$(id -u) GID=$(id -g) docker compose run -v .:/app --rm web make test

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I meant why don't we define the user/group in the docker-compose.yml instead of in the cli?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't managed to make that work yet. It would need to take UID/GID from host environment during build right? btw, how does this work on windows?

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Well, as I said I don't know much about it, just wanted to check, if you thought about that. You clearly did, so it is what it is 🤷 🙃 Thank you again for your efforts!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, $(id -u) is the ID of the user that is running the command, right?

So when I run the thing locally it's going to use my ID and on the github runner it's going to be the ID of the runner's user. Since the default user ID is 1000 we usually have the same ID for our local user and for nonroot but if my local user has another ID then the command is run inside the container as a non-existing user, which somehow works but is not what we want.

Wouldn't we want to use the nonroot user that is defined in the dockerfile anyway? That user is used by default if we don't specify --user. What kind of errors do you get when you don't specify --user?

Copy link
Copy Markdown
Contributor Author

@crosspolar crosspolar Feb 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My understanding is this: if you share files from the Docker volume, e.g., all Python files locally or in GitHub Actions, e.g., .coverage, nonroot needs the same UID as the host, otherwise there will be access problems. If this non-root user does not match the UID of the host user who owns the files in the volume, that non-root user will not have permissions to read or write to those files.

That is why for some occasions we have to either sync UID between Host and nonroot or override --user. I have to admit, currently is just a mess of both...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With your suggestion Theo, we would need to set UID/GID of nonroot to the host's user. This would have to be passed as an argument or via the environment.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we would need to set UID/GID of nonroot to the host's user

Is that not already done with ARG UID=1000 ARG GID=1000 in the Dockerfile and UID: ${UID:-1000} GID: ${GID:-1000} in the docker-compose? Then we're sure that we already have nonroot in sync with the host and we can skip all the --user?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought so too, but for some reason it didn't work

@techge
Copy link
Copy Markdown

techge commented Feb 15, 2026

The SonarCloud complaint about the tmp directory is not so bad in our environment. Would not hurt to still use a proper subdirectory as explained in the SonarCloud thingy. You never know what we'll do in the future.

@crosspolar crosspolar force-pushed the dockerfile_without_poetry_dev_dependencies branch from 03685ab to bbead6b Compare February 21, 2026 10:27
@crosspolar
Copy link
Copy Markdown
Contributor Author

@techge thanks for your feedback. I removed the "tmp"-directory now for members-current and used tempfile.TemporaryFile instead of tempfile.NamedTemporaryFile, so the filename should be more random (according to SonarCloud). For the tests, I haven't changed but don't see a problem here.

@techge
Copy link
Copy Markdown

techge commented Feb 22, 2026

I removed the "tmp"-directory now for members-current and used tempfile.TemporaryFile instead of tempfile.NamedTemporaryFile, so the filename should be more random (according to SonarCloud).

As I said I don't think this is thaaaat relevant for us, still, I think you missed the point. The /tmp folder is typically readable by every user. Using a subfolder like /tmp/tapir would prevent that, because this would be created only readable by the current user. This seems to be the reason SonarCloud is complaining about the last two bits.

Copy link
Copy Markdown
Collaborator

@Theophile-Madet Theophile-Madet left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to clarify the --user-thing, I think it's not doing what's expected, see my comment on the corresponding thread.

Also, I think poetry should be installed in the runtime container so that we can update the packages from inside the container.

def test_updatePurchaseTrackingList_userHasTrackingDisabled_userIsNotInExportFile(
self,
@patch("tempfile.TemporaryFile")
def test_updatePurchaseTrackingList_userswithTrackingEnabledOrDisabled_includedOrExcludedInExportFile(
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be two separate tests

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why, it's a nice binary test case

run: docker compose run web make check-formatting
- name: Check translations
run: docker compose run web make check-translations
run: docker compose run --user=$(id -u):$(id -g) web make check-translations
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, $(id -u) is the ID of the user that is running the command, right?

So when I run the thing locally it's going to use my ID and on the github runner it's going to be the ID of the runner's user. Since the default user ID is 1000 we usually have the same ID for our local user and for nonroot but if my local user has another ID then the command is run inside the container as a non-existing user, which somehow works but is not what we want.

Wouldn't we want to use the nonroot user that is defined in the dockerfile anyway? That user is used by default if we don't specify --user. What kind of errors do you get when you don't specify --user?

@crosspolar
Copy link
Copy Markdown
Contributor Author

crosspolar commented Mar 29, 2026

Wouldn't we want to use the nonroot user that is defined in the dockerfile anyway? That user is used by default if we don't specify --user. What kind of errors do you get when you don't specify --user?

https://github.com/SuperCoopBerlin/tapir/actions/runs/23712692142/job/69074844974?pr=712

You can also specifiy UID and GID during build, like I do now. If you want to use volumes for developing or share files such as translation or coverage files, you have to specifiy UID and GID now with

export USER_UID=$(id -u)
export USER_GID=$(id -g)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Don't install dev-dependencies into production container

3 participants