{"id":329296,"date":"2023-08-17T07:00:00","date_gmt":"2023-08-17T07:00:00","guid":{"rendered":"http:\/\/itteacheritfreelance.hk\/wordpress\/?guid=913531b81ea15bb0b1779758c2b38083"},"modified":"2023-08-17T07:00:00","modified_gmt":"2023-08-17T07:00:00","slug":"how-to-deploy-a-flask-application-in-python-with-gunicorn","status":"publish","type":"post","link":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/2023\/08\/17\/how-to-deploy-a-flask-application-in-python-with-gunicorn\/","title":{"rendered":"How to deploy a Flask application in Python with Gunicorn"},"content":{"rendered":"<p class=\"syndicated-attribution\"><meta name= \\\"keywords \\\" content= \\\"\u96fb\u5b50\u8a08\u7b97\u6a5f, \u6559\u80b2, IT \u96fb\u8166\u73ed,\u96fb\u8166\u88dc\u7fd2\uff0c \u96fb\u8166\u73ed\uff0c \u5bb6\u6559\uff0c \u79c1\u4eba\u8001\u5e2b\uff0c \u8cc7\u8a0a\u6280\u8853\uff0c \u7a0b\u5e8f\u8a2d\u8a08\uff0c \u96fb\u5b50\u8a08\u7b97\u6a5f\uff0c \u904a\u6232\uff0c \u860b\u679c\uff0c \u96fb\u5f71\uff0c \u8a08\u7b97\u6a5f\uff0c\u7de8\u78bc\uff0c Java\uff0c C\/C++\uff0c JavaScript\uff0c PHP\uff0c HTML\uff0c CSS\uff0c MySQL\uff0c mobile\uff0c Android\uff0c \u52d5\u6f2b\uff0c Python\uff0c teacher\uff0c \u88dc\u7fd2\uff0c \u96fb\u8166\u88dc\u7fd2 \u8cc7\u8a0a, \u7535\u5b50\u8ba1\u7b97\u673a, IT ,Game, apple, movie, Computer,student,Java,\u6559\u80b2, ,\u5b66\u751f, \u5b66\u4e60, learn, \u6559\u5b66,  Android, apple,anime, animation, \u4fe1\u606f\u6280\u672f, \u7a0b\u5e8f\u8bbe\u8ba1, \u79fb\u52a8\u7535\u8bdd, \u8cc7\u8a0a\u79d1\u6280,Game, Jeu, Juego,Call Of Duty ,\u4f7f\u547d\u53ec\u559a , \u6e38\u620f, \u7535\u5b50\u6e38\u620f,, \u591a\u4eba\u7535\u5b50\u6e38\u620f, \u7f51\u7edc\u6e38\u620f\uff0conline\uff0conline game, \u624b\u673a\u6e38\u620f, mobile \\\"><\/p>\n<p><span>How to deploy a Flask application in Python with Gunicorn<\/span><\/p>\n<p><a href=\"https:\/\/flask.palletsprojects.com\/en\/2.3.x\/#\">Flask<\/a> is a popular web framework for building web applications in <a href=\"https:\/\/developers.redhat.com\/topics\/python\">Python<\/a>. It is considered a microframework because it provides only the bare essentials for web development, focusing on simplicity and extensibility.\u00a0<\/p>\n<p>Flask is one of the most popular frameworks for developing REST applications in Python. Flask also has a server to do local deployments and test the application, but no one would go with it to production. So we need another server to deploy the application in production, and one option is to use a <a href=\"https:\/\/peps.python.org\/pep-3333\/\">WSGI<\/a> (Web Server Gateway Interface) server like <a href=\"https:\/\/gunicorn.org\/\">Gunicorn<\/a>.<\/p>\n<p>In this tutorial, you will learn how to create a Flask application, configure it to Gunicorn, and containerize it.<\/p>\n<h2>The application<\/h2>\n<p>Let&#8217;s create a simple Hello World application using Flask as a web framework.<\/p>\n<p>You\u2019ll need to install Python 3 and <code>pip<\/code>.<\/p>\n<h3>Setup<\/h3>\n<p>Create a new file with the name <code>requirements.txt<\/code> with the dependencies required for the project:<\/p>\n<pre>\n<code class=\"language-python\">Flask\n\nGunicorn<\/code><\/pre>\n<p>Then update the <code>pip<\/code> dependencies and install the dependencies by running the following command:<\/p>\n<pre>\n<code class=\"language-python\">pip3 install --upgrade pip\n\npip3 install -r requirements.txt<\/code><\/pre>\n<h3>Application<\/h3>\n<p>Create a new file named <code>app.py<\/code> containing the Flask REST endpoint:<\/p>\n<pre>\n<code class=\"language-python\">from flask import Flask\n\napp = Flask(__name__)\n\n\n\n@app.route('\/')\n\ndef hello_world():\n\n\u00a0\u00a0\u00a0\u00a0return 'Hello, World!'<\/code><\/pre>\n<h3>Running<\/h3>\n<p>Let&#8217;s test the application locally:<\/p>\n<pre>\n<code class=\"language-python\">flask --app app run<\/code><\/pre>\n<p>The output will be similar to the following:<\/p>\n<pre>\n\u00a0* Serving Flask app 'app'\n\n\u00a0* Debug mode: off\n\nWARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.\n\n\u00a0* Running on http:\/\/127.0.0.1:5000\n\nPress CTRL+C to quit<\/pre>\n<p>If you send a request to the defined endpoint, you&#8217;ll get the predefined output:<\/p>\n<pre>\ncurl localhost:5000\/\n\nHello, World!<\/pre>\n<p>So far, so good, but as the log message says, we need another way to use a WSGI server for going to production. So, let&#8217;s do it.<\/p>\n<h3>WSGI<\/h3>\n<p>WSGI stands for Web Server Gateway Interface. It is a specification for a standardized interface between web servers and web applications or frameworks written in Python. WSGI defines a contract that allows web servers to communicate with Python web applications, enabling them to work together seamlessly.<\/p>\n<p>This separation of concerns allows web servers to focus on handling low-level networking tasks, such as accepting incoming requests and managing connections. In contrast, web applications can focus on handling the application logic and generating responses.<\/p>\n<p>You can switch between server implementations with minimal application changes. In this case, we&#8217;ll use Gunicorn.<\/p>\n<p>First, we configure the Gunicorn server by creating a new file named gunicorn_config.py, where we&#8217;ll configure things like the number of workers and threads and open port or timeout.<\/p>\n<pre>\n<code class=\"language-python\">import os\n\n\n\nworkers = int(os.environ.get('GUNICORN_PROCESSES', '2'))\n\nthreads = int(os.environ.get('GUNICORN_THREADS', '4'))\n\n# timeout = int(os.environ.get('GUNICORN_TIMEOUT', '120'))\n\nbind = os.environ.get('GUNICORN_BIND', '0.0.0.0:8080')\n\n\n\nforwarded_allow_ips = '*'\n\nsecure_scheme_headers = { 'X-Forwarded-Proto': 'https' }<\/code><\/pre>\n<p>Now, the last thing to do is start the Gunicorn server with the application deployed.<\/p>\n<p>Let&#8217;s run the following command in the terminal:<\/p>\n<pre>\n<code class=\"language-python\">gunicorn --config gunicorn_config.py app:app<\/code><\/pre>\n<p>The first <code>app<\/code> is the name of the Python file containing the Flask application.<\/p>\n<p>The output shows the application up and running in Gunicorn:<\/p>\n<pre>\n[2023-07-17 22:55:05 +0200] [15903] [INFO] Starting gunicorn 20.1.0\n\n[2023-07-17 22:55:05 +0200] [15903] [INFO] Listening at: http:\/\/0.0.0.0:8080 (15903)\n\n[2023-07-17 22:55:05 +0200] [15903] [INFO] Using worker: gthread\n\n[2023-07-17 22:55:05 +0200] [15904] [INFO] Booting worker with pid: 15904\n\n[2023-07-17 22:55:05 +0200] [15905] [INFO] Booting worker with pid: 15905<\/pre>\n<p>If you re-access the service using port 8080, you&#8217;ll get the Hello World again.<\/p>\n<pre>\n<code class=\"language-python\">curl localhost:8080\/\n\nHello, World!<\/code><\/pre>\n<p>Now, with the application up and running locally, it&#8217;s time to containerize it.<\/p>\n<h2>Containerization<\/h2>\n<p>Generally speaking, to containerize an application, you create a Dockerfile with all the instructions and dependencies required to run the application.<\/p>\n<h3>Dockerfile<\/h3>\n<p>The base image contains Python, so we only copy the application files, install the requirements to run the application, and use Gunicorn to start it.<\/p>\n<pre>\n<code class=\"language-python\">FROM python:3.7.3-slim\n\nCOPY requirements.txt \/\n\nRUN pip3 install --upgrade pip\n\nRUN pip3 install -r \/requirements.txt\n\n\n\nCOPY . \/app\n\nWORKDIR \/app\n\n\n\nEXPOSE 8080\n\n\n\nCMD [\"gunicorn\",\"--config\", \"gunicorn_config.py\", \"app:app\"]<\/code><\/pre>\n<h3>Building the container<\/h3>\n<p>We are going to use <a href=\"https:\/\/podman-desktop.io\/\">Podman Desktop<\/a> to build the container. With Podman (or Docker) running, let&#8217;s build the container running the following command:<\/p>\n<pre>\n<code class=\"language-python\">podman build -t hello-flask:1.0.0 .<\/code><\/pre>\n<p>The output shows the building steps executed:<\/p>\n<pre>\nSTEP 1\/8: FROM python:3.7.3-slim\n\nSTEP 2\/8: COPY requirements.txt \/\n\n--> 7721820f5f2e\n\nSTEP 3\/8: RUN pip3 install --upgrade pip\n\n\u2026\n\nSTEP 8\/8: CMD [\"gunicorn\",\"--config\", \"gunicorn_config.py\", \"app:app\"]\n\nCOMMIT hello-flask:1.0.0\n\n--> 7bf50a7a7936\n\nSuccessfully tagged localhost\/hello-flask:1.0.0\n\n7bf50a7a7936d9b87af74b7d49a94c69d217712901d78ba170acb1f28f800d51<\/pre>\n<p class=\"Indent1\"><strong>[ Learn more:\u00a0<a href=\"https:\/\/developers.redhat.com\/articles\/2023\/03\/01\/podman-desktop-introduction\">What is Podman Desktop? A developer&#8217;s introduction<\/a> ]<\/strong><\/p>\n<h3>Running the container<\/h3>\n<p>To run the container, use Podman (or Docker):<\/p>\n<pre>\n<code class=\"language-bash\">podman run -it --rm -p 8080:8080 hello-flask:1.0.0<\/code><\/pre>\n<pre>\n<code class=\"language-python\">[2023-07-18 07:35:29 +0000] [1] [INFO] Starting gunicorn 21.0.1\n\n[2023-07-18 07:35:29 +0000] [1] [INFO] Listening at: http:\/\/0.0.0.0:8080 (1)\n\n[2023-07-18 07:35:29 +0000] [1] [INFO] Using worker: gthread\n\n[2023-07-18 07:35:29 +0000] [4] [INFO] Booting worker with pid: 4\n\n[2023-07-18 07:35:29 +0000] [5] [INFO] Booting worker with pid: 5<\/code><\/pre>\n<h3>Kubernetes<\/h3>\n<p>If you want to try the application in <a href=\"https:\/\/developers.redhat.com\/topics\/kubernetes\">Kubernetes<\/a>, use the following YAML file:<\/p>\n<pre>\n<code class=\"language-yaml\">apiVersion: apps\/v1\n\nkind: Deployment\n\nmetadata:\n\n\u00a0\u00a0labels:\n\n\u00a0\u00a0\u00a0\u00a0app: hello-service\n\n\u00a0\u00a0name: hello-service\n\nspec:\n\n\u00a0\u00a0replicas: 1\n\n\u00a0\u00a0selector:\n\n\u00a0\u00a0\u00a0\u00a0matchLabels:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app: hello-service\n\n\u00a0\u00a0template:\n\n\u00a0\u00a0\u00a0\u00a0metadata:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0labels:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0app: hello-service\n\n\u00a0\u00a0\u00a0\u00a0spec:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0containers:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0- name: hello-service\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0image: quay.io\/lordofthejars\/hello-flask:1.0.0\u00a0\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ports:\n\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0- containerPort: 8080\n\n---\n\napiVersion: v1\n\nkind: Service\n\nmetadata:\n\n\u00a0\u00a0name: hello-service\n\n\u00a0\u00a0labels:\n\n\u00a0\u00a0\u00a0\u00a0app: hello-service\u00a0\u00a0\u00a0\u00a0\n\nspec:\n\n\u00a0\u00a0ports:\n\n\u00a0\u00a0- name: http\n\n\u00a0\u00a0\u00a0\u00a0port: 8080\n\n\u00a0\u00a0selector:\n\n\u00a0\u00a0\u00a0\u00a0app: hello-service\n\n\u00a0\u00a0type: LoadBalancer<\/code><\/pre>\n<p>Use any Kubernetes cluster (minikube, kind, etc.) or a cloud Kubernetes implementation like <a href=\"https:\/\/developers.redhat.com\/developer-sandbox\">OpenShift<\/a> for free in the <a href=\"https:\/\/developers.redhat.com\/developer-sandbox\">Developer Sandbox for Red Hat OpenShift<\/a>.<\/p>\n<h2>Conclusion<\/h2>\n<p>Flask is one of the most popular frameworks in Python to develop web applications, but when it comes to moving to production, you need a server like Gunicorn to deploy it.<\/p>\n<p>Containerizing the application is a simple process of putting these steps into a Dockerfile and choosing the right base image.<\/p>\n<p><span><span lang=\"\" about=\"https:\/\/developers.redhat.com\/user\/670471\" typeof=\"schema:Person\" property=\"schema:name\" datatype=\"\" xml:lang=\"\">asotobue<\/span><\/span><br \/>\n<span>Thu, 08\/17\/2023 &#8211; 07:00<\/span><br \/>\n<a href=\"https:\/\/developers.redhat.com\/author\/alex-soto\" hreflang=\"en\">Alex Soto Bueno<\/a><\/p>\n\n<p class=\"syndicated-attribution\"><figure class= \\\"wp-block-image alignnone \\\"><img src= \\\"http:\/\/itteacheritfreelance.hk\/test\/wordpress\/wp-content\/uploads\/2016\/05\/logo2-2.png\\\" alt=\\\"IT\u96fb\u8166\u88dc\u7fd2 java\u88dc\u7fd2 \u70ba\u5927\u5bb6\u914d\u5c0d\u96fb\u8166\u88dc\u7fd2,IT freelance, \u79c1\u4eba\u8001\u5e2b, PHP\u88dc\u7fd2,CSS\u88dc\u7fd2,XML,Java\u88dc\u7fd2,MySQL\u88dc\u7fd2,graphic design\u88dc\u7fd2,\u4e2d\u5c0f\u5b78ICT\u88dc\u7fd2,\u4e00\u5c0d\u4e00\u79c1\u4eba\u88dc\u7fd2\u548cFreelance\u81ea\u7531\u5de5\u4f5c\u914d\u5c0d\u3002\\\"\/><figcaption>\u7acb\u523b\u8a3b\u518a\u53ca\u5831\u540d\u96fb\u8166\u88dc\u7fd2\u8ab2\u7a0b\u5427!<\/figcaption><\/figure>\r\n<\/br>Find A Teacher Form:\r\n<\/br>https:\/\/docs.google.com\/forms\/d\/1vREBnX5n262umf4wU5U2pyTwvk9O-JrAgblA-wH9GFQ\/viewform?edit_requested=true#responses\r\n<\/br><\/br>Email:\r\n<\/br>public1989two@gmail.com<br><br><br><br><br><br><br>\r\n<a href=www.itsec.hk style=color:#FFFFFF;>www.itsec.hk<\/a><br>\r\n<a href=\\\"www.itsec.vip\\\" style=color:#FFFFFF;>www.itsec.vip<\/a><br>\r\n<a href=\\\"www.itseceu.uk\\\" style=color:#FFFFFF;>www.itseceu.uk<\/a><br><\/p>","protected":false},"excerpt":{"rendered":"<div class=\"mh-excerpt\"><p>How to deploy a Flask application in Python with Gunicorn<br \/>\nFlask is a popular web framework for building web applications in Python. It is considered a microframework because it provides only the bare essentials for web development, focusing on simplici&#8230;<\/p>\n<\/div>","protected":false},"author":2026,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"slim_seo":{"title":"How to deploy a Flask application in Python with Gunicorn - ITTeacherITFreelance.hk","description":"How to deploy a Flask application in Python with Gunicorn Flask is a popular web framework for building web applications in Python. It is considered a microfram"},"footnotes":""},"categories":[10700],"tags":[],"_links":{"self":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/329296"}],"collection":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/2026"}],"replies":[{"embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=329296"}],"version-history":[{"count":1,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/329296\/revisions"}],"predecessor-version":[{"id":329297,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/329296\/revisions\/329297"}],"wp:attachment":[{"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=329296"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=329296"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/itteacheritfreelance.hk\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=329296"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}