Move root-required bits of drama-free-django build into Dockerfile#5145
Move root-required bits of drama-free-django build into Dockerfile#5145hkeeler merged 16 commits intocfpb:masterfrom
Conversation
This change was made to make it easier to run the build and test processes as alternate users, which is sometimes necessary to make the volumes permissions line up with the Docker host. Additionally, changes paths using `/`, which was causing permissions issues when running as non-root.
chosak
left a comment
There was a problem hiding this comment.
Generally this looks good, and works for me locally. I added a bunch of questions, and a few other things:
-
Is there somewhere sensible to put your note above about the ID warning? Maybe in the DFD README? Or are people not even going to notice that?
-
There are a bunch of warnings during the Yarn build:
warning Skipping preferred cache folder "/.cache/yarn" because it is not writable. warning Selected the next writable cache folder in the list, will be "/tmp/.yarn-cache-501".I don't know enough about Yarn to know what this means, but these don't appear during our normal frontend builds. Is this something to be concerned about?
-
We get similar warnings during the DFD build about pip:
WARNING: The directory '/.cache/pip/http' or its parent directory is not owned by the current user and the cache has been disabled. Please check the permissions and owner of that directory. If executing pip with sudo, you may want sudo's -H flag.
| # This is used by DFD to set Django's settings.STATIC_ROOT. | ||
| echo '{"static_out": "../../../static"}' > ./dfd_paths.json | ||
| # Q: Why do we need to override the default? | ||
| # echo '{"static_out": "../static"}' > ./dfd_paths.json |
There was a problem hiding this comment.
This is needed because the default drama-free-django behavior is to set its static_out variable to 'static'. This is used to set Django STATIC_ROOT, which specifies where collectstatic puts its files. The default behavior would have this command collect staticfiles to a static relative path within the DFD deploy.
We instead want these files to go to '../../../static/', in practice going from, say, /srv/cfgov/versions/20190712095508/current to /srv/cfgov/static.
@rosskarchner's open PR #5133 currently includes a change that would set the default static root to /srv/cfgov/static as desired, but that'll only work once cfpb/drama-free-django#25 or something like it removes the DFD behavior that overwrites the static root at runtime.
There was a problem hiding this comment.
Makes sense. I'll change it back.
| # Extract the artifact in /tmp. | ||
| cp "$artifact_volume/$artifact_filename" /tmp | ||
| cd /tmp | ||
| mkdir -p $dfd_test_dir |
There was a problem hiding this comment.
Not a big deal, but I'm curious why you made a new directory for this. I figured that working in /tmp was fine since the container is ephemeral.
There was a problem hiding this comment.
The issue was that by having it in /tmp, it resulted in directories being created in the / root directory, and the non-root user didn't have permission to create those directories. An alternative would be to open up permissions on /, but this seems like a better option.
| RUN yum install -y centos-release-scl && \ | ||
| curl -sL https://rpm.nodesource.com/setup_10.x | bash - && \ | ||
| curl -sL https://dl.yarnpkg.com/rpm/yarn.repo | tee /etc/yum.repos.d/yarn.repo && \ | ||
| yum install -y ${SCL_PYTHON_VERSION} gcc git nodejs which yarn && \ |
There was a problem hiding this comment.
Is the inclusion of which here leftover from debugging?
There was a problem hiding this comment.
Yes, I can remove that. I find it strange that CentOS doesn't have which in its base distribution, but yeah.
|
|
||
| COPY _build.sh _test.sh docker-entrypoint.sh ./ | ||
|
|
||
| ENTRYPOINT [ "./docker-entrypoint.sh"] No newline at end of file |
There was a problem hiding this comment.
| ENTRYPOINT [ "./docker-entrypoint.sh"] | |
| ENTRYPOINT ["./docker-entrypoint.sh"] |
| docker run \ | ||
| --rm \ | ||
| -u $(id -u):$(id -g) \ | ||
| -v $(pwd):/cfgov:cached \ |
There was a problem hiding this comment.
Why is :cached used here in the test script but not in the build script? Is this Mac-specific, as documented here -- is it a no-op when run on Linux systems?
There was a problem hiding this comment.
Unfortunately, it fails currently on Linux. I'll remove it.
| --rm \ | ||
| -u $(id -u):$(id -g) \ | ||
| -v $(pwd):/cfgov:cached \ | ||
| cfgov-dfd-builder ./_test.sh |
There was a problem hiding this comment.
This shouldn't hold up this PR, but, if we are going to maintain this DFD testing capability, I wonder if it's worth entertaining the idea of a distinct Dockerfile just for that purpose. We don't really need everything in the "cfgov-dfd-builder" image just to run the DFD image, and it would be nice to actually determine what is needed. But probably thinking more about that should wait until/if we want to think about migrating Ansible code here.
There was a problem hiding this comment.
Yeah, it does feel a little awkward to have the two scripts that both build the same image, but my assumption was that generally when you'd run test.sh, you would have run build.sh just before it, and so the docker build part would be fully cached and be pretty instant, but I didn't want to make that a requirement to running test.sh, so it's duplicated in both scripts.
As for a separate image, yeah we could. It just seemed like it'd be better to only maintain one Dockerfile that could do both. But if there's a scenario where we'd be running just test.sh, maybe that starts to make more sense.
| @@ -0,0 +1,23 @@ | |||
| FROM centos:7 | |||
There was a problem hiding this comment.
The current versions of the build and test scripts use centos:6(also documented here). I did this deliberately to try to match the current setup. Is there a particular reason to change that version here?
There was a problem hiding this comment.
That was not intentional. Will fix.
The version of pip that comes with SCL python27 has a bug that fails to process PIP_NO_CACHE_DIR correctly. Adding --no-cache-dir overrides the envvar, preventing the error.
|
@chosak, I think I've covered most of your comments.
Seems like a good place. I added a Notes section with those details.
This was occurring because Docker defaults the home directory to
Now Fun fact: |
chosak
left a comment
There was a problem hiding this comment.
Works great for me locally. I'm looking forward to seeing this run on Jenkins.
That's right, this envvar disables the cache with either truthy or falsy value!
That is a fun fact! Makes me feel better about some of our envvar inconsistencies. 😄
Co-Authored-By: Andy Chosak <andy@chosak.org>
|
@hkeeler follow-up question about this PR. One concern I had that motivated the initial implementation as a single script was worrying about caching out-of-date versions of dependencies. Specifically with this line, if and when new commits are merged to drama-free-django master, that line of the Dockerfile won't be re-run, will it? Locally I've encountered "Using cache" during the build step. How does Docker determine which lines to re-run? Would it be a good idea to use |
|
I've opened #5173 to add |
The current drama-free-django Docker-based build tool (see
docker/drama-free-django) works well in most cases, but we've had issues in CI/CD environments where the files written back to the host environment cannot be cleaned up since they're owned byroot. This change moves the theroot-required bits into a newDockerfilewhere all the tools can be installed, and allows the DFD-related processes to run in the container whichever user you'd like.Notes
When running the container as a user that exists on the host, but not in the container, you may notice a warning similar to:
This is not anything to worry about. It simply means the
uid/giddon't match any users/groups setup in the container.Checklist