|
| 1 | +title: Configure Python 3, Flask and Gunicorn on Ubuntu 18.04 LTS |
| 2 | +slug: python-3-flask-gunicorn-ubuntu-1804-bionic-beaver |
| 3 | +meta: Instructions for configuring Ubuntu 18.04 Bionic Beaver with Python 3, Flask and Green Unicorn (Gunicorn). |
| 4 | +category: post |
| 5 | +date: 2018-06-14 |
| 6 | +modified: 2018-06-15 |
| 7 | +newsletter: False |
| 8 | +headerimage: /img/180614-ubuntu-flask-gunicorn/header.jpg |
| 9 | +headeralt: Flask, Green Unicorn and Ubuntu logos. Copyright their respective owners. |
| 10 | + |
| 11 | + |
| 12 | +[Ubuntu Linux's](/ubuntu.html) latest Long Term Support (LTS) |
| 13 | +[operating system](/operating-systems.html) version is |
| 14 | +[18.04](http://releases.ubuntu.com/18.04/) and was released in April 2018. |
| 15 | +The 18.04 update is code named "Bionic Beaver" and it includes |
| 16 | +[Python 3](/python-2-or-3.html) by default. However, there are bunch of |
| 17 | +dependencies you will need to install to get this release set up as a |
| 18 | +[development environment](/development-environments.html). |
| 19 | + |
| 20 | +In this tutorial we will get Python 3.6 configured with development system |
| 21 | +packages to start a new [Flask](/flask.html) web application project and |
| 22 | +run it with [Green Unicorn (Gunicorn)](/green-unicorn-gunicorn.html). |
| 23 | + |
| 24 | + |
| 25 | +## Our Tools |
| 26 | +Our project will use the Ubuntu 18.04 release along with a few other |
| 27 | +libraries. Note that if you are using the older 16.04 LTS release, there |
| 28 | +is also |
| 29 | +[a guide that will walk you through setting up that version](/blog/python-3-flask-green-unicorn-ubuntu-1604-xenial-xerus.html) |
| 30 | +as your development environment. |
| 31 | + |
| 32 | +We will install the following tools as we step through the rest of |
| 33 | +the sections in this tutorial: |
| 34 | + |
| 35 | +* [Ubuntu 18.04 LTS (Bionic Beaver)](http://releases.ubuntu.com/18.04/) |
| 36 | +* [Python](/why-use-python.html) version |
| 37 | + [3.6.5](https://docs.python.org/3/whatsnew/3.6.html) |
| 38 | + (default in Ubuntu 18.04) |
| 39 | +* [Flask](/flask.html) web framework version |
| 40 | + [1.0.2](http://flask.pocoo.org/docs/1.0/changelog/#version-1-0-2) |
| 41 | +* [Green Unicorn (Gunicorn)](/green-unicorn-gunicorn.html) version |
| 42 | + [19.8.1](http://docs.gunicorn.org/en/stable/news.html) |
| 43 | + |
| 44 | +If you're running on Mac OS X or Windows, use virtualization software such |
| 45 | +as [Parallels](https://www.parallels.com/products/desktop/) or |
| 46 | +[VirtualBox](https://www.virtualbox.org/wiki/Downloads) with the |
| 47 | +[Ubuntu .iso file](http://releases.ubuntu.com/18.04/). Either the amd64 or |
| 48 | +i386 version for 18.04 will work. I am using amd64 for development and testing |
| 49 | +in this tutorial. |
| 50 | + |
| 51 | +When you boot up to the Ubuntu desktop you should see a screen like this one. |
| 52 | + |
| 53 | +<img src="/img/180614-ubuntu-flask-gunicorn/ubuntu-desktop.jpg" width="100%" class="shot rnd outl"> |
| 54 | + |
| 55 | +We're ready to get our development environment configured. |
| 56 | + |
| 57 | + |
| 58 | +## System Packages |
| 59 | +Open up a terminal window to proceed with the setup. |
| 60 | + |
| 61 | +Use the following two commands to check which version of Python 3 is installed |
| 62 | + |
| 63 | +```bash |
| 64 | +python3 --version |
| 65 | +which python3 |
| 66 | +``` |
| 67 | + |
| 68 | +The Python version should be 3.6.5 and the location `/usr/bin/python3`. |
| 69 | + |
| 70 | +Our Ubuntu installation requires a few system packages to do development |
| 71 | +rather than just run Python scripts. Run the following `apt-get` command |
| 72 | +and enter your `sudo` password to allow restricted system access. |
| 73 | + |
| 74 | +```bash |
| 75 | +sudo apt-get install python3-dev python3-pip python3-virtualenv |
| 76 | +``` |
| 77 | + |
| 78 | +We should see the following prompt requesting `sudo` access. Enter `y` to |
| 79 | +let the system package manager complete the installation. |
| 80 | + |
| 81 | +```bash |
| 82 | +Reading package lists... Done |
| 83 | +Building dependency tree |
| 84 | +Reading state information... Done |
| 85 | +The following packages were automatically installed and are no longer required: |
| 86 | + linux-headers-4.15.0-20 linux-headers-4.15.0-20-generic |
| 87 | + linux-image-4.15.0-20-generic linux-modules-4.15.0-20-generic |
| 88 | + linux-modules-extra-4.15.0-20-generic |
| 89 | +Use 'sudo apt autoremove' to remove them. |
| 90 | +The following additional packages will be installed: |
| 91 | + dh-python libexpat1-dev libpython3-dev libpython3.6-dev python3-setuptools |
| 92 | + python3-wheel python3.6-dev |
| 93 | +Suggested packages: |
| 94 | + python-setuptools-doc |
| 95 | +The following NEW packages will be installed: |
| 96 | + dh-python libexpat1-dev libpython3-dev libpython3.6-dev python3-dev |
| 97 | + python3-pip python3-setuptools python3-virtualenv python3-wheel |
| 98 | + python3.6-dev |
| 99 | +0 upgraded, 10 newly installed, 0 to remove and 11 not upgraded. |
| 100 | +Need to get 3,617 kB/3,661 kB of archives. |
| 101 | +After this operation, 20.2 MB of additional disk space will be used. |
| 102 | +Do you want to continue? [Y/n] |
| 103 | +``` |
| 104 | + |
| 105 | +The package manager will do the dirty work and should report when the |
| 106 | +installation finishes successfully. |
| 107 | + |
| 108 | +```bash |
| 109 | +(...clipped a bunch of installation lines for brevity...) |
| 110 | +Unpacking python3-wheel (0.30.0-0.2) ... |
| 111 | +Setting up python3-wheel (0.30.0-0.2) ... |
| 112 | +Setting up python3-virtualenv (15.1.0+ds-1.1) ... |
| 113 | +Setting up python3-pip (9.0.1-2.3~ubuntu1) ... |
| 114 | +Setting up libexpat1-dev:amd64 (2.2.5-3) ... |
| 115 | +Processing triggers for man-db (2.8.3-2) ... |
| 116 | +Setting up python3-setuptools (39.0.1-2) ... |
| 117 | +Setting up dh-python (3.20180325ubuntu2) ... |
| 118 | +Setting up libpython3.6-dev:amd64 (3.6.5-3) ... |
| 119 | +Setting up python3.6-dev (3.6.5-3) ... |
| 120 | +Setting up libpython3-dev:amd64 (3.6.5-3) ... |
| 121 | +Setting up python3-dev (3.6.5-3) ... |
| 122 | +``` |
| 123 | + |
| 124 | +The packages we need are now installed. We can continue on to install our |
| 125 | +Python-specific dependencies. |
| 126 | + |
| 127 | + |
| 128 | +## Virtual environment |
| 129 | +We installed [virtualenv](https://virtualenv.pypa.io/en/latest/) |
| 130 | +and [pip](https://pypi.org/project/pip) to handle our |
| 131 | +[application dependencies](/application-dependencies.html). |
| 132 | +We can now use them to download and install Flask and Gunicorn. |
| 133 | + |
| 134 | + |
| 135 | +Create a directory to store your virtualenvs. Then create a new virtualenv |
| 136 | +within that directory. |
| 137 | + |
| 138 | +```bash |
| 139 | +# make sure pip and setuptools are the latest version |
| 140 | +pip3 install --upgrade pip setuptools |
| 141 | +# the tilde ("~") specifies the user's home directory, such as "/home/matt" |
| 142 | +cd ~ |
| 143 | +mkdir venvs |
| 144 | +# specify the system python3 installation |
| 145 | +python3 -m venv venvs/flask1804 |
| 146 | +``` |
| 147 | + |
| 148 | +Activate the virtualenv. |
| 149 | + |
| 150 | +```bash |
| 151 | +source ~/venvs/flask1804/bin/activate |
| 152 | +``` |
| 153 | + |
| 154 | +Our prompt will change when the virutalenv is activated. |
| 155 | + |
| 156 | +<img src="/img/180614-ubuntu-flask-gunicorn/venv-activated.jpg" width="100%" class="shot rnd outl"> |
| 157 | + |
| 158 | +Our virtualenv is now activated with Python 3. We can install any |
| 159 | +dependencies we need such as Flask and Gunicorn. |
| 160 | + |
| 161 | + |
| 162 | +## Flask and Gunicorn |
| 163 | +We're going to use `pip` within our new virtualenv but it's a good |
| 164 | +idea to update it to the latest version. We should also install the |
| 165 | +`wheel` package to remove installation warnings when `pip` tries to |
| 166 | +use [Python wheels](https://pythonwheels.com/), which are the newest |
| 167 | +standard in an admittedly long line of Python distribution package |
| 168 | +models. |
| 169 | + |
| 170 | +```bash |
| 171 | +pip install --upgrade pip |
| 172 | +pip install wheel |
| 173 | +``` |
| 174 | + |
| 175 | +We can now install Flask and Green Unicorn via the `pip` command. |
| 176 | + |
| 177 | +```bash |
| 178 | +pip install flask gunicorn |
| 179 | +``` |
| 180 | + |
| 181 | +Look for output similar to the following to ensure the libraries installed |
| 182 | +without an issue. |
| 183 | + |
| 184 | +```bash |
| 185 | +(flask1804) matt@ubuntu:~$ pip install flask gunicorn |
| 186 | +Collecting flask |
| 187 | + Using cached https://files.pythonhosted.org/packages/7f/e7/08578774ed4536d3242b14dacb4696386634607af824ea997202cd0edb4b/Flask-1.0.2-py2.py3-none-any.whl |
| 188 | +Collecting gunicorn |
| 189 | + Using cached https://files.pythonhosted.org/packages/55/cb/09fe80bddf30be86abfc06ccb1154f97d6c64bb87111de066a5fc9ccb937/gunicorn-19.8.1-py2.py3-none-any.whl |
| 190 | +Collecting click>=5.1 (from flask) |
| 191 | + Using cached https://files.pythonhosted.org/packages/34/c1/8806f99713ddb993c5366c362b2f908f18269f8d792aff1abfd700775a77/click-6.7-py2.py3-none-any.whl |
| 192 | +Collecting Werkzeug>=0.14 (from flask) |
| 193 | + Using cached https://files.pythonhosted.org/packages/20/c4/12e3e56473e52375aa29c4764e70d1b8f3efa6682bef8d0aae04fe335243/Werkzeug-0.14.1-py2.py3-none-any.whl |
| 194 | +Collecting itsdangerous>=0.24 (from flask) |
| 195 | + Using cached https://files.pythonhosted.org/packages/dc/b4/a60bcdba945c00f6d608d8975131ab3f25b22f2bcfe1dab221165194b2d4/itsdangerous-0.24.tar.gz |
| 196 | +Collecting Jinja2>=2.10 (from flask) |
| 197 | + Using cached https://files.pythonhosted.org/packages/7f/ff/ae64bacdfc95f27a016a7bed8e8686763ba4d277a78ca76f32659220a731/Jinja2-2.10-py2.py3-none-any.whl |
| 198 | +Collecting MarkupSafe>=0.23 (from Jinja2>=2.10->flask) |
| 199 | + Using cached https://files.pythonhosted.org/packages/4d/de/32d741db316d8fdb7680822dd37001ef7a448255de9699ab4bfcbdf4172b/MarkupSafe-1.0.tar.gz |
| 200 | +Building wheels for collected packages: itsdangerous, MarkupSafe |
| 201 | + Running setup.py bdist_wheel for itsdangerous ... done |
| 202 | + Stored in directory: /home/matt/.cache/pip/wheels/2c/4a/61/5599631c1554768c6290b08c02c72d7317910374ca602ff1e5 |
| 203 | + Running setup.py bdist_wheel for MarkupSafe ... done |
| 204 | + Stored in directory: /home/matt/.cache/pip/wheels/33/56/20/ebe49a5c612fffe1c5a632146b16596f9e64676768661e4e46 |
| 205 | +Successfully built itsdangerous MarkupSafe |
| 206 | +Installing collected packages: click, Werkzeug, itsdangerous, MarkupSafe, Jinja2, flask, gunicorn |
| 207 | +Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 click-6.7 flask-1.0.2 gunicorn-19.8.1 itsdangerous-0.24 |
| 208 | +``` |
| 209 | + |
| 210 | +Create a new directory named `flask1804` under your home directory (not |
| 211 | +within the `venvs` subdirectory) that will store our Flask test project. |
| 212 | +Change directory into the new folder. |
| 213 | + |
| 214 | +```bash |
| 215 | +mkdir ~/flask1804 |
| 216 | +cd ~/flask1804 |
| 217 | +``` |
| 218 | + |
| 219 | +Create a new file named `__init__.py` within our `flaskproj` directory so |
| 220 | +we can test to make sure Flask is working properly. I usually use |
| 221 | +[Vim](/vim.html) but [Emacs](/emacs.html) and other |
| 222 | +[development environments](/development-environments.html) work great as |
| 223 | +well. |
| 224 | + |
| 225 | +Within `__init__.py` write the following code. |
| 226 | + |
| 227 | +```python |
| 228 | +from flask import Flask, Response |
| 229 | + |
| 230 | + |
| 231 | +app = Flask(__name__) |
| 232 | + |
| 233 | +@app.route("/") |
| 234 | +def index(): |
| 235 | + return Response("It works!"), 200 |
| 236 | + |
| 237 | +if __name__ == "__main__": |
| 238 | + app.run(debug=True) |
| 239 | +``` |
| 240 | + |
| 241 | + |
| 242 | +We could run our app with the Flask development server using the |
| 243 | +`python __init__.py` command. Instead run the Flask app with |
| 244 | +Gunicorn. Go to the directory above the `flask1804` folder, in our |
| 245 | +case we can enter `cd ~` then use the `gunicorn` command: |
| 246 | + |
| 247 | +```bash |
| 248 | +gunicorn flask1804.app:app |
| 249 | +``` |
| 250 | + |
| 251 | +We should see: |
| 252 | + |
| 253 | +```bash |
| 254 | +[2018-06-15 15:54:31 -0400] [5174] [INFO] Starting gunicorn 19.8.1 |
| 255 | +[2018-06-15 15:54:31 -0400] [5174] [INFO] Listening at: http://127.0.0.1:8000 (5174) |
| 256 | +[2018-06-15 15:54:31 -0400] [5174] [INFO] Using worker: sync |
| 257 | +[2018-06-15 15:54:31 -0400] [5177] [INFO] Booting worker with pid: 5177 |
| 258 | +``` |
| 259 | + |
| 260 | +Great now we can bring up our shell Flask app in the web browser at |
| 261 | +the `localhost:8000` or `127.0.0.1:8000` address. |
| 262 | + |
| 263 | +<img src="/img/180614-ubuntu-flask-gunicorn/it-works.jpg" width="100%" class="shot rnd outl"> |
| 264 | + |
| 265 | +Now you're ready for some real [Flask](/flask.html) development! |
| 266 | + |
| 267 | + |
| 268 | +## Ready to Code |
| 269 | +That provides a quick configuration for getting started on 18.04 LTS |
| 270 | +developing [Flask](/flask.html) applications with the |
| 271 | +[Gunicorn](/green-unicorn-gunicorn.html) [WSGI server](/wsgi-servers.html). |
| 272 | + |
| 273 | +Next up you should check out the following tutorials that use this |
| 274 | +Flask configuration: |
| 275 | + |
| 276 | +* [Responding to SMS Text Messages with Python & Flask](/blog/respond-sms-text-messages-python-flask.html) |
| 277 | +* [How to Add Hosted Monitoring to Flask Web Applications](/blog/hosted-monitoring-flask-web-apps.html)) |
| 278 | + |
| 279 | +Alternatively you can also determine what to code next in your Python |
| 280 | +project by reading the |
| 281 | +[Full Stack Python table of contents page](/table-of-contents.html). |
| 282 | + |
| 283 | +Questions? Contact me via Twitter |
| 284 | +[@fullstackpython](https://twitter.com/fullstackpython) |
| 285 | +or [@mattmakai](https://twitter.com/mattmakai). I'm also on GitHub with |
| 286 | +the username [mattmakai](https://github.com/mattmakai). |
| 287 | + |
| 288 | +Something wrong with this post? Fork |
| 289 | +[this page's source on GitHub](https://github.com/mattmakai/fullstackpython.com/blob/master/content/posts/180614-flask-gunicorn-ubuntu-1804.markdown) |
| 290 | +and submit a pull request. |
0 commit comments