Skip to content

Document ability to use Functions Framework as a WSGI app #43

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

Closed
di opened this issue May 12, 2020 · 4 comments
Closed

Document ability to use Functions Framework as a WSGI app #43

di opened this issue May 12, 2020 · 4 comments
Labels
documentation Improvements or additions to documentation enhancement New feature or request

Comments

@di
Copy link
Member

di commented May 12, 2020

While #36 removed the example of fine-tuning gunicorn, it's still possible to use the Functions Framework as a WSGI app in this way.

We should document how to do this if you need finer control over the HTTP server used, and also document some other WSGI servers that users could use instead of gunicorn if they need to.

@di di added the documentation Improvements or additions to documentation label May 14, 2020
@someone1
Copy link

someone1 commented Jul 2, 2020

Sorry to lurk onto this - but the example Dockerfile's use of CMD exec functions-framework --target=hello seems to conflict with the README.md's guidance of using CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 -e FUNCTION_TARGET=hello functions_framework:app.

Additionally, using functions-framework outputs the following log suggesting we shouldn't use it as found in the example Dockerfile:

   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.

Is using function-framework as the entrypoint/cmd in Docker production-ready? If so, should the README and log outputs be updated to reflect that? If not, should the Dockerfile examples be updated to something that is production ready?

@di
Copy link
Member Author

di commented Jul 2, 2020

Is it possible you're using an older version of the repo, or an older version of the framework, or have some of the Docker layers cached? Since version 1.4.0, invoking functions-framework will use gunicorn as a production HTTP server by default.

Building the example Dockerfile gives me the following:

$ docker build -t foo . && docker run -it foo
Sending build context to Docker daemon   2.26MB
Step 1/7 : FROM python:3.7-slim
 ---> 7e61acc68112
Step 2/7 : ENV APP_HOME /app
 ---> Running in fc8547ea7c82
Removing intermediate container fc8547ea7c82
 ---> 4e7b96ad14c7
Step 3/7 : WORKDIR $APP_HOME
 ---> Running in 7c1692337e18
Removing intermediate container 7c1692337e18
 ---> 8b5d0a1917fe
Step 4/7 : COPY . .
 ---> 6060bfbd412f
Step 5/7 : RUN pip install gunicorn functions-framework
 ---> Running in 6bfc44611d78
Collecting gunicorn
  Downloading gunicorn-20.0.4-py2.py3-none-any.whl (77 kB)
Collecting functions-framework
  Downloading functions_framework-2.0.0-py3-none-any.whl (21 kB)
Requirement already satisfied: setuptools>=3.0 in /usr/local/lib/python3.7/site-packages (from gunicorn) (45.1.0)
Collecting click<8.0,>=7.0
  Downloading click-7.1.2-py2.py3-none-any.whl (82 kB)
Collecting watchdog>=0.10.0
  Downloading watchdog-0.10.3.tar.gz (94 kB)
Collecting cloudevents<1.0
  Downloading cloudevents-0.3.0-py3-none-any.whl (26 kB)
Collecting flask<2.0,>=1.0
  Downloading Flask-1.1.2-py2.py3-none-any.whl (94 kB)
Collecting pathtools>=0.1.1
  Downloading pathtools-0.1.2.tar.gz (11 kB)
Collecting Werkzeug>=0.15
  Downloading Werkzeug-1.0.1-py2.py3-none-any.whl (298 kB)
Collecting Jinja2>=2.10.1
  Downloading Jinja2-2.11.2-py2.py3-none-any.whl (125 kB)
Collecting itsdangerous>=0.24
  Downloading itsdangerous-1.1.0-py2.py3-none-any.whl (16 kB)
Collecting MarkupSafe>=0.23
  Downloading MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl (27 kB)
Building wheels for collected packages: watchdog, pathtools
  Building wheel for watchdog (setup.py): started
  Building wheel for watchdog (setup.py): finished with status 'done'
  Created wheel for watchdog: filename=watchdog-0.10.3-py3-none-any.whl size=73871 sha256=b83e6a9b18502f9e804c26cccbed2455eb498b8a3b8549bca45c6bf843b9374b
  Stored in directory: /root/.cache/pip/wheels/27/21/35/9d1e531f9de5335147dbef07e9cc99d312525ba128a93d1225
  Building wheel for pathtools (setup.py): started
  Building wheel for pathtools (setup.py): finished with status 'done'
  Created wheel for pathtools: filename=pathtools-0.1.2-py3-none-any.whl size=8784 sha256=452f069740a235eefed3845fab97a27f6a49770f75258795324e94bd7730f944
  Stored in directory: /root/.cache/pip/wheels/3e/31/09/fa59cef12cdcfecc627b3d24273699f390e71828921b2cbba2
Successfully built watchdog pathtools
Installing collected packages: gunicorn, click, pathtools, watchdog, cloudevents, Werkzeug, MarkupSafe, Jinja2, itsdangerous, flask, functions-framework
Successfully installed Jinja2-2.11.2 MarkupSafe-1.1.1 Werkzeug-1.0.1 click-7.1.2 cloudevents-0.3.0 flask-1.1.2 functions-framework-2.0.0 gunicorn-20.0.4 itsdangerous-1.1.0 pathtools-0.1.2 watchdog-0.10.3
WARNING: You are using pip version 20.0.2; however, version 20.1.1 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
Removing intermediate container 6bfc44611d78
 ---> 347c1de2a315
Step 6/7 : RUN pip install -r requirements.txt
 ---> Running in 9af3481eb650
WARNING: You are using pip version 20.0.2; however, version 20.1.1 is available.
You should consider upgrading via the '/usr/local/bin/python -m pip install --upgrade pip' command.
Removing intermediate container 9af3481eb650
 ---> af2de3fe8bae
Step 7/7 : CMD exec functions-framework --target=hello
 ---> Running in 489432a1b73a
Removing intermediate container 489432a1b73a
 ---> 7d495285d82c
Successfully built 7d495285d82c
Successfully tagged foo:latest
[2020-07-02 20:13:52 +0000] [1] [INFO] Starting gunicorn 20.0.4
[2020-07-02 20:13:52 +0000] [1] [INFO] Listening at: http://0.0.0.0:8080 (1)
[2020-07-02 20:13:52 +0000] [1] [INFO] Using worker: threads
[2020-07-02 20:13:52 +0000] [8] [INFO] Booting worker with pid: 8

Note that there is no warning and that it invokes gunicorn.

@someone1
Copy link

someone1 commented Jul 2, 2020

Ahhh - I think the confusion was that the root README recommends we run functions-framework --target hello --debug which I guess starts a different server with the --debug flag.

After I saw the warning message and how the cloud run http example README says to use gunicorn but the Dockerfile uses functions-framework had me thinking the Dockerfile was using a development server as the --debug option logs out:

* Serving Flask app "hello" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.

So I guess the answer to my question is, functions-framework without the --debug flag will start the service suitable for production (using gunicorn) and the mismatch between README and Dockerfile is unimportant.

Apologies for the confusion!

@josephlewis42 josephlewis42 added the enhancement New feature or request label Aug 15, 2023
@jama22
Copy link
Contributor

jama22 commented Jan 11, 2025

Closing as stale. i don't think we're going to do this anytime soon, but if someone wants to make a PR to the README.md I'll happily review

@jama22 jama22 closed this as completed Jan 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants