Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Install python/npm dependencies in repostiroy root. (WIP/POC) #21857

Closed
wants to merge 3 commits into from

Conversation

KevinMind
Copy link
Contributor

@KevinMind KevinMind commented Feb 13, 2024

Description

This PR has 2 commits. The aim is to simplify some of our build logic, specifically with how we handle node_modules. The first commit moves our node_modules back to the repo root in /data/olympia. The second uses django staticfiles to source files we need to include in our css/js bundles, removing the need for manually copying and maintaining those files.

Context

Based on the comments so far, seems like we have had premission issues between the container and host.

Tests

Check in the comments but you can test this on a non-linux host using docker in docker.

FROM docker:19.03.12-dind

RUN apk add git nodejs npm make sudo

RUN git clone https://github.com/mozilla/addons-server.git

RUN addgroup -g 12345 nonroot \
    && adduser -u 12345 -G nonroot -S nonroot -s /bin/sh \
    && addgroup nonroot docker \
    && chown -R nonroot:nonroot /addons-server

WORKDIR /addons-server

ENV UID=12345
ENV GID=12345
USER nonroot

CMD ["docker", "compose", "pull"]

@diox
Copy link
Member

diox commented Feb 14, 2024

The reason deps are installed that way is to allow for local envs to have a olympia user in the container with a uid/gid matching ones of the owner the git clone on the host running the container, which is different than the one the image was built with. For that scenario it's slightly inefficient as it forces the deps to be reinstalled from scratch ignoring what's in the image, but that's usually not a big deal as we're not frequently rebuilding the image locally.

We looked into doing this via a recursive chown to fix the deps but figuring out reliably when to do it without killing startup perf locally made this too difficult.

I've not ran your patch locally but this would likely break this locally, unless the user on your local machine happens to have uid=9500/gid=9500, which are the values the image is built for.

@KevinMind
Copy link
Contributor Author

allow for local envs to have a olympia user in the container with a uid/gid matching ones of the owner the git clone on the host running the container, which is different than the one the image was built with.

How can I test this? It's working for me locally and in CI it is working.

@diox
Copy link
Member

diox commented Feb 14, 2024

It's only working in CI because it's not covering the use-case of installing new version of deps on top of an existing image (CI currently doesn't use the docker image for tests, and the build job doesn't care about updating deps on top of it - and even if it did, caching of the deps might hide this)

@KevinMind
Copy link
Contributor Author

I tested this code in a github action that was building the container. Could be there host has 9500 as the UID / GID. No way caching was an issue there cause CI.

I'm trying to build a dind container that can run the docker build but still not working. Do you actually know how and when this edge case can/was reproduced?

@diox
Copy link
Member

diox commented Feb 14, 2024

I don't have time to fully try this now. The approximate STRs are:

  • Clone the repos on your host (Your uid is whatever, but likely not 9500. The default on Ubuntu is 1000, it could be different for multiple users etc).
  • Grab/build an image. That image is using uid=9500.
  • Run that image from the repos clone, with docker compose setting up the volumes for local development.
  • Change required packages to force an update
  • Run make update_deps

Expected results:

  • Everything works, all deps are owned by the right owner in the container

Actual results:

  • Permission issues because some deps are owned by uid=9500, some by uid=

Because the problem depends on how the volume ownership is set up on the host you may need to try this under Linux/Windows w/ WSL, or tweak your Docker settings on Mac.

@KevinMind
Copy link
Contributor Author

Are you sure this is still an issue? I'm not able to reproduce no matter what I do.

I was able to test this using docker in docker. What I did:

  1. pull dind image
docker pull dind
  1. run the container (mounting the checkout git repo)
docker run --privileged --name my-dind-container -v $(pwd):/app -d docker:dind
  1. shell into the container
docker exec -it my-dind-container /bin/sh  
  1. Install some dependencies
apk add make nodejs npm
  1. run the setup for docker compose
docker compose up -d
  1. update pip dependency and node dependency
    added flask and react, react-dom using npm and hashin from the host (docker)
  2. run make update deps
make update_deps
  1. everything worked!

@diox
Copy link
Member

diox commented Feb 14, 2024

You're running a completely different image, but crucially you're running the container as root, which is not how we run addons-server locally, at least in Linux. You'll run into the opposite problem, where files created in the docker image now have the wrong owner (root) on the host, causing permission denied issues when you try to edit the files locally (when you're tweaking deps to add manual logging/debugging statements, or altering the package lock file)

@KevinMind
Copy link
Contributor Author

I set a pairing session for us. I'm not sure I understand exactly the parameters of how to reproduce this. We can do it together and walk through the steps.

@KevinMind
Copy link
Contributor Author

Naive question: if we just built the image locally as the default by modifying the compose.yml, this goes away?

@KevinMind
Copy link
Contributor Author

Reran this test with a nonroot user. To clarify, my nonroot user has UID and GID that is not 9500. Running

make initialize_docker

installs python deps in the container at /deps and installs node_modules in the repo root /data/olympia.

This works, I got an error indexing a document in elastic search (I don't think that is related but will keep digging on that)

Then,

From the host I ran

npm i react --save

This created a new file in /data/olympia/node_moudules/react/** . Running

make update_deps

still works. I don't seem to have any text editors installed in the container, but I can cat, create, echo to files in the react directory. I think the reason this works is that olympia has the same GID/UID as my nonroot user, due to the create_env_file that is run at the beginning.

So.... idk what or how anything could break given that the only change in the commit we are discussing is moving the node_modules to a different path. 🤷 I'm trying to break this thing and I just cannot.

@KevinMind KevinMind changed the title Remove symlinked node_modules, simplify npm install Simplify the javascripts. (WIP/POC) Feb 14, 2024
@KevinMind KevinMind force-pushed the fix-javascript branch 2 times, most recently from 4e4b2c2 to 33e2d5a Compare February 15, 2024 19:56
@KevinMind
Copy link
Contributor Author

KevinMind commented Feb 15, 2024

Okay, I was able to reproduce finally and able to solve (for linux host), I think.. Updated the first commit to reflect those changes. Now I'm getting weird behavior running back on my mac as host where a user with my UID/GID already exists in the container while building it locally 🤷 I really wish it were unproblematic to run docker as root.

@KevinMind KevinMind changed the title Simplify the javascripts. (WIP/POC) Install python/npm dependencies in repostiroy root. (WIP/POC) Feb 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants