-
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
Add ability to create deployable zipfiles #5179
Conversation
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.
Took a first pass. Overall, looks good, though I'm still working through some of the details. Just the one question about the file permissions on the zip file so far.
Thinking about the wsgi.conf stuff: what if the extract script created a symlink from current/wsgi.py to cfgov/cfgov/wsgi.py? This serves no long-term value, but if my mental model of this stuff is correct, it would avoid that breakage you talk about. Once we've switched to this new deployment format everywhere, we could remove that function and THEN make the change to wsgi.conf |
# --login, it guarantees /etc/profile is always sourced, unlike the | ||
# non-login, non-interactive shell you get by default with `docker run`. | ||
|
||
exec "$@" |
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.
Maybe setting --login via SHELL (see our top-level Dockerfile) is better than a dummy entrypoint?
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.
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.
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.
I agree, it seems like it should work that way, and I tried for a while to make that work on #5144. Unfortunately, SHELL
in Dockerfile
only affects ENTRYPOINT
and CMD
when used in shell form, and that was causing other issues with the shell env (can't remember the exact issue). So yeah, for now, probably easiest to just keep it as is.
That's a good suggestion, as it'll smooth the migration path. I've added that behavior in d5ea0d6. |
b109d47
to
2fb4a86
Compare
This adds a new Python package to this repository that allows for the creation of deployable zipfiles that automatically create a virtual environment with all project requirements when they are unpacked. This is functionality that today is provided by the drama-free-django repository [0]; however, that project supports quite a few other optional behaviors that are no longer needed by cf.gov. This has motivated the migration of this deployable zipfile behavior into cfgov-refresh. The main interface with this new behavior is a create.py script that can be invoked like this from the project root: cfgov/deployable_zipfile/create.py ./cfgov # path to project code being deployed ./requirements/deployment.txt # requirements to include in zipfile output_zipfile_name # output filename, appended with .zip --extra-static=path/to/fonts # optional, see below --extra-python=python3 # optional, see below This is functionally similar to the "no-drama build" command in drama-free-django. This script has no external (non-Python) dependencies and thus does not need to be run inside of a virtual environment with regular cfgov-refresh requirements. The optional --extra-static argument can be used to include additional static files in the zip, in a static.in subdirectory. This can be used to store the private font files used by cf.gov, documented here [1]. Like drama-free-django, the deployable zipfile creation process involves creating Python wheels for all requirements. This uses the version of Python that you use to invoke the script. You can optionally provide a second version of Python (e.g. Python 3) so that the zip contains wheels for multiple versions. This makes it possible to use the same zipfile to run cf.gov in Python 2 and 3. This code brings in logic from an existing drama-free-django PR [2]. The deployable zipfile can be deployed in a way that is almost completely compatible with how drama-free-django zipfiles work today, like this: path/to/deployable.zip -d /path/to/deploy/zip If the destination directory does not exist, it will be created. To maintain backwards compatibility, the zip is extracted to a "current" subdirectory of the specified location. In this subdirectory, a "venv" subdirectory is created to hold a Python virtual environment with all requirements. This virtual environment is configured with a special behavior related to environment variables, consistent with drama-free-django: if an "environment.json" file exists within the root of the deployed location (the "current" subdirectory), it will be loaded as environment variables on Python startup. This means that even a regular invocation of /path/to/venv/bin/python will include those variables in the environment. A new Docker-based setup for generating these deployable zipfiles has been created under docker/deployable-zipfile, comparable to the existing docker/drama-free-django setup. This can be invoked locally with: docker/deployable-zipfile/build.sh This will generate a "cfgov_current_build.zip" file in the root of this project. NOTE: The major difference between zipfiles generated with this approach and those generated with drama-free-django are that DFD zips include a wsgi.py file, and these do not. In order to use these zipfiles with our current deployment process, you'll need to make an additional change to our Apache wsgi.conf file here [3] to point to ${CFGOV_CURRENT}/cfgov/cfgov/wsgi.py. [0] https://github.com/cfpb/drama-free-django [1] https://cfpb.github.io/cfgov-refresh/installation/#webfonts [2] drama-free-django PR 22 [3] https://github.com/cfpb/cfgov-refresh/blob/e3f0822c4787a301cceaa6eb782a25d82bcd1900/cfgov/apache/conf.d/wsgi.conf#L6
This adds a new Python package to this repository that allows for the creation of deployable zipfiles that automatically create a virtual environment with all project requirements when they are unpacked.
This is functionality that today is provided by the drama-free-django repository; however, that project supports quite a few other optional behaviors that are no longer needed by cf.gov. This has motivated the migration of this deployable zipfile behavior into cfgov-refresh.
The main interface with this new behavior is a create.py script that can be invoked like this from the project root:
This is functionally similar to the
no-drama build
command in drama-free-django. This script has no external (non-Python) dependencies and thus does not need to be run inside of a virtual environment with regular cfgov-refresh requirements.The optional
--extra-static
argument can be used to include additional static files in the zip, in a static.in subdirectory. This can be used to store the private font files used by cf.gov, documented here.Like drama-free-django, the deployable zipfile creation process involves creating Python wheels for all requirements. This uses the version of Python that you use to invoke the script.
You can optionally provide a second version of Python (e.g. Python 3) so that the zip contains wheels for multiple versions. This makes it possible to use the same zipfile to run cf.gov in Python 2 and 3. This code brings in logic from an existing drama-free-django PR by @rosskarchner.
The deployable zipfile can be deployed in a way that is almost completely compatible with how drama-free-django zipfiles work today, like this:
If the destination directory does not exist, it will be created. To maintain backwards compatibility, the zip is extracted to a
current
subdirectory of the specified location.In this subdirectory, a
venv
subdirectory is created to hold a Python virtual environment with all requirements.This virtual environment is configured with a special behavior related to environment variables, consistent with drama-free-django: if an
environment.json
file exists within the root of the deployed location (thecurrent
subdirectory), it will be loaded as environment variables on Python startup. This means that even a regular invocation of/path/to/venv/bin/python
will include those variables in the environment.A new Docker-based setup for generating these deployable zipfiles has been created under
docker/deployable-zipfile
, comparable to the existingdocker/drama-free-django
setup.This can be invoked locally with:
This will generate a
cfgov_current_build.zip
file in the root of this project.NOTE: The major difference between zipfiles generated with this approach and those generated with drama-free-django are that DFD zips include a
wsgi.py
file, and these do not. In order to use these zipfiles with our current deployment process, you'll need to make an additional change to our Apache wsgi.conf file here to point to${CFGOV_CURRENT}/cfgov/cfgov/wsgi.py
:I haven't included that change in this PR as it would break the existing DFD-based process.
Testing
The best way to test this is using the Docker setup mentioned above, after making the Apache config change also mentioned above. The build generated with that setup can be used successfully with our internal Ansible/Docker process.
Todos
current
subdirectory as part of deploying the zipfile.Checklist