-
Notifications
You must be signed in to change notification settings - Fork 114
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
Move root-required bits of drama-free-django build into Dockerfile #5145
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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
docker/drama-free-django/_build.sh
Outdated
@@ -62,13 +49,14 @@ no-drama build "${build_args[@]}" | |||
echo "{}" > ./dfd_env.json | |||
|
|||
# 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
docker/drama-free-django/Dockerfile
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the inclusion of which
here leftover from debugging?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I can remove that. I find it strange that CentOS doesn't have which
in its base distribution, but yeah.
docker/drama-free-django/Dockerfile
Outdated
|
||
COPY _build.sh _test.sh docker-entrypoint.sh ./ | ||
|
||
ENTRYPOINT [ "./docker-entrypoint.sh"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ENTRYPOINT [ "./docker-entrypoint.sh"] | |
ENTRYPOINT ["./docker-entrypoint.sh"] |
docker/drama-free-django/test.sh
Outdated
docker run \ | ||
--rm \ | ||
-u $(id -u):$(id -g) \ | ||
-v $(pwd):/cfgov:cached \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
docker/drama-free-django/Dockerfile
Outdated
@@ -0,0 +1,23 @@ | |||
FROM centos:7 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 <[email protected]>
@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 newDockerfile
where 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
/gid
don't match any users/groups setup in the container.Checklist