-
Notifications
You must be signed in to change notification settings - Fork 1.8k
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
Feat/docker #2380
base: master
Are you sure you want to change the base?
Feat/docker #2380
Conversation
The added files are one dockerfile and a start.sh file respectively Packages that match the environment variables provided through the start.sh file are installed
If you are using a Docker container, you can deploy Django and Flask using Gunicorn
The config folder contains the scripts needed to set up the docker image
Thanks for the PR. Is there a reason this wasn't put in the existing |
Simple instructions are written in the README, but I will add more guides if needed. |
No, I'm saying this is just an example. It should go in the existing |
I have just a few thoughts, but I really appreciate this. Should we commit to making all or most of our configuration possible to define through the environment? I think I would like that. It would remove the need for the script that builds the command line. Should we provide the requirements files or let users handle that themselves? For Tornado, users should already have it as a requirement because I think they need to import its APIs. It is sometimes the case that users can write code that is worker agnostic, but other times there is a need to perform concurrent, non-blocking work within a single request and users then import and depend on gevent or eventlet directly already. If we didn't have the requirements files, then the dockerfile itself gets very small. Building on this, we could have the dockerfile install the user-supplied requirements.txt, which should also contain the framework requirement. Some users will need to apt-get install additional libraries for their applications to work, but I don't see a great way to handle that and maybe we shouldn't. I think what I'm seeing from the PR, my comments, and the comment from @jamadden is that this is written as if it could be an official gunicorn quick-start image, but I worry that the set of users for whom that is practical is small. With some changes, I feel like an example becomes sufficient because configuring gunicorn through the environment would be easy enough that a fairly boilerplate dockerfile would be a better starting point than a stock image. |
Docker/Dockerfile
Outdated
@@ -0,0 +1,17 @@ | |||
FROM python:3.8.4-slim | |||
ENV PYTHONIOENCODING UTF-8 | |||
ARG DEBIAN_FRONTEND=noninteractive |
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 it reasonable for there to be any other choice here? If we're not running any apt commands in the dockerfile, do we even need this at all?
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 the expectation is that users will use this as a FROM
image?
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 the expectation is that users will use this as a FROM image?
Yes, like this nginx image from dockerhub
https://hub.docker.com/_/nginx
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.
ARG DEBIAN_FRONTEND=noninteractive
has been deleted.
Docker/Dockerfile
Outdated
|
||
COPY ./config /config | ||
|
||
ENV CONFIG_FILE_PATH=/config/config.py |
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.
/work/gunicorn.conf.py would be the default location for this.
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.
If the user manually configures the gunicorn.conf.py file, adds gunicorn.conf.py to the docker container, and then enters the path to gunicorn.conf.py in the environment variable $CONFIG_FILE_PATH, the gunicorn runs based on the specified file.
Docker/Dockerfile
Outdated
pip3 install -r /config/sync-requirements.txt &&\ | ||
/config/install.sh | ||
|
||
WORKDIR /work |
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 might prefer /app or /gunicorn. Is the expectation that users will volume mount this path or that they will use FROM
and add their code to this path?
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 set path is /work, but there is no problem even if the user uses a different path. Users can enter other environment variables to suit their environment.
So I put everything related to the settings in /config so that it doesn't overlap with the user's configuration.
This idea was benchmarked on Celery's Github. Like Celery, we put GunicornDockerimage in a new top-level directory that Gunicorn can officially support. I think you can put it in the /example folder as you said. Django and Celery officially support Docker images. |
edit Dockerfile delete DEBIAN_FRONTEND argument edit install.sh System environment $REQUIRENMENTS_FILE_PATH was added When the user sets $REQUIRENMENTS_FILE_PATH, the container tries to install it as a pip requirements file
Added example of using REQUIRENMENTS_FILE_PATH in README
Users can record the framework and version they use in requirements file that records the package dependencies pointed to by the $REQUIRENMENTS_FILE_PATH environment variable.
async-requirements and sync-requirements files are merged an requirements file dockerfile has been changed
Users can use the gunicorn configuration within the container by entering the location of the preconfigured gunicorn.conf.py file in the $CONFIG_FILE_PATH environment variable A sample configuration file gunicorn.conf.py has been added
README.md file updated Added description of environment value $CONFIG_FILE_PATH
@tilgovi what about having it in this week release. I like the idea. Btw any idea where we coudl host an "official" build? apparently docker hub has became too much restrictive in term of pricing. Thoughts? |
I don't think we should publish an image. The Django image that is referenced has been deprecated for reasons similar to my objection. A user likely needs their own requirements.txt anyway, so it doesn't help to pre-install Gunicorn in the image. That means the image is really just a Python image. I think it's useful to have as an example, but I will leave a separate review comment asking for some changes. We should not hold up release for this because I think most users will find the examples in the repository. They can be added after releasing. |
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 worry that the config.sh script complicates the example and makes it less accessible as an educational tool. A gunicorn.conf.py file in the example that sets values from the environment directly might be more helpful. Something like this would also make sense in any kind of Gunicorn application template. This would be analogous to how the Rails templates install a Puma config that reads from the environment, but sets defaults: https://github.com/rails/rails/blob/6-0-stable/railties/lib/rails/generators/rails/app/templates/config/puma.rb.tt
I think the example can be simplified by removing REQUIREMENTS_FILE_PATH
. It made sense when the idea was to ship a base image, because there was a separation between the user's requirements and the base requirements. I would just expect now a single requirements.txt in the work path.
I don't think a separation between /config and /work is helpful, nor is CONFIG_FILE_PATH. Gunicorn accepts an argument on the command line to set the config file path, so if the default execution is gunicorn
then the user can docker run app --config <path>
. The entrypoint script should not be necessary.
Fear enough. I will make the release today. I think it would be good anyway to have a good template for docker images, so anyone can install it. Including on windows for a basic dev environment. That would solve a lot of issues for some developers today that doesn't use UNIX / Linux systems. |
I sympathize enough. I would appreciate it if you think of it as a sample rather than an official image. I also agree with what you said is more useful to configure using the gunicorn.conf.py file. |
The reason I put the config file in the /config folder is because the user could overwrite files like start.sh that should be in /config, which could cause the container not to work properly. |
… variable via START_OPTION gunicorn's installation syntax was added. A branch statement depending on the presence or absence of REQUIRENMENTS_FILE_PATH has been added. A branch statement depending on the presence or absence of CONFIG_FILE_PATH has been added.
Examples using gevent and flask have been added to the requirenments.txt file.
The unused environment variable CONFIG_FILE_PATH has been removed. Corrected the command to edit permissions on deleted files. like config.sh, config/install.sh, /config/requirements.txt
Remove any comments related to the config.sh file.
@tilgovi |
--- | ||
### **Configuration** | ||
|
||
### Environment variables required |
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 specify these as environment variables when they can all be passed to the Gunicorn CLI?
examples/docker/Dockerfile
Outdated
@@ -0,0 +1,10 @@ | |||
# You can also use your favorite Python Docker image. | |||
FROM python:3.8.4-slim | |||
ENV PYTHONIOENCODING UTF-8 |
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 think this is only needed for the Windows Server containers, and it's included upstream for those: docker-library/python#557
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 Linux images get it from here: https://github.com/docker-library/python/blob/5590cdd4367f088277bb5494d0a0b0f65e9ab491/3.8/buster/Dockerfile#L14
Port options have been added to the example code.
If you are using a Docker container, you can deploy Django and Flask using Gunicorn.