I wanted to develop a web with Python, so I built an environment for a Python web application.
Until now, the mainstream configuration was NGINX <-> uwsgi <-> Flask
, but in April 2018 NGINX released the lightweight AP server NGINX Unit
.
This time, we will use NGINX Unit and build a web application environment with the configuration NGINX <-> NGINX Unit <-> Flask
.
Use NGINX
as the web server, NGINX Unit
as the AP server, and Flask
as the Python web framework.
The server uses a virtual environment of Vagrant and VirtualBox. Please enable the private network.
$ vagrant init centos/7
$ vi Vagrantfile
- # config.vm.network "private_network", ip: "192.168.33.10"
+ config.vm.network "private_network", ip: "192.168.33.10"
$ vagrant up
$ vagrant ssh
Connect to the virtual environment with vagrant ssh
and disable selinux.
$ sudo vi /etc/selinux/config
- SELINUX=enforcing
+ SELINUX=disabled
$ sudo reboot
Build a Python development environment in a virtual environment.
By default, CentOS has Python 2.7.5
installed.
$ python --version
Python 2.7.5
This time we will use Python 3.7.4
.
Install Python on CentOS by referring to the procedure on the Python Official Page. First, install the necessary tools.
$ sudo yum -y groupinstall "development tools"
$ sudo yum install -y bzip2-devel gdbm-devel libffi-devel libuuid-devel ncurses-devel openssl-devel readline-devel sqlite-devel tk-devel wget xz-devel zlib-devel
Download the installer from Python's Official Page (https://www.python.org/downloads/release/python-374/) with wget
.
Unzip after downloading.
$ wget https://www.python.org/ftp/python/3.7.4/Python-3.7.4.tgz
$ tar xzf Python-3.7.4.tgz
Build after unzipping the source code.
$ cd Python-3.7.4
$ ./configure --enable-shared
$ make
$ sudo make install
$ sudo sh -c "echo '/usr/local/lib' > /etc/ld.so.conf.d/custom_python3.conf"
$ sudo ldconfig
The built command will be installed under / usr / local / bin
.
$ which python
/usr/bin/python
$ which python3
/usr/local/bin/python3
$ python3 --version
Python 3.7.4
$ which pip3
/usr/local/bin/pip3
Finally upgrade pip
.
$ pip3 install --upgrade pip --user
The latest version of the pip
command will be installed on your local bin
.
$ which pip
~/.local/bin/pip
$ pip --version
pip 19.2.3 from /home/vagrant/.local/lib/python3.7/site-packages/pip (python 3.7)
That's all for building the Python environment.
Build a Python virtual environment to switch and manage packages for each project.
Python provides venv
as a standard module that supports the creation of virtual environments.
Create a virtual environment using venv
.
# flask_Create a virtual environment called sample
$ python3 -m venv flask_sample
$ ls
venv
Enable the virtual environment created by venv.
$ source flask_sample/bin/activate
(flask_sample)$
You can activate the virtual environment by running the ʻactivate script in the directory created by the
venvmodule. When you enable the virtual environment,
(virtual environment name)` is displayed at the beginning of the prompt.
Go to the directory of the virtual environment you created and check the configuration.
(flask_sample)$ cd flask_sample
(flask_sample)$ ls
bin include lib lib64 pyvenv.cfg
The bin
directory contains the ʻactivate script that activates the virtual environment and the Python package management tool
pipcommand. When you run the
pipcommand in a virtual environment, the commands in this directory are run. The installed packages will be installed in
lib / python3.7 / site-packages and
lib64 / python3.7 / site-packages. In a virtual environment, ignore the
site-packages` directory in Python itself and use the packages in this directory.
You can develop apps without polluting the package of Python itself.
Flask
is a small Python micro-framework. The features listed as standard are minimal and are used when developing small applications.
Plugins are provided so you can extend your functionality.
Use Django
if you want to develop a large application from the beginning.
Install Flask
in the venv virtual environment.
(flask_sample)$ pip install Flask
The structure of the sample project is as follows.
/sample
|- app.py
|- templates
|- index.html
|- post.html
Each code is implemented as follows.
app.py
from flask import Flask ,render_template,request
application = Flask(__name__)
@application.route('/')
def index():
return render_template('index.html')
@application.route('/sample',methods=['POST'])
def sample():
message = request.form['message']
return render_template('post.html',message=message)
if __name__=="__main__":
application.run(host='0.0.0.0')
index.html
<html>
<head>
<meta charset="utf-8" />
<title>Flask Sample</title>
</head>
<body>
<h1>Flask Smaple</h1>
<form action="sample" method="post">
<input type="text" name="message" />
<input type="submit" value="Send" />
</form>
</body>
</html>
post.html
<html>
<head>
<meta charset="utf-8" />
<title>Flask Sample</title>
</head>
<body>
<h1>Flask Smaple</h1>
message:{{message}}
</body>
</html>
After implementation, run ʻapp.py` to launch the Flask application.
(flask_sample)$ python /sample/app.py
* Serving Flask app "app" (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: off
* Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
If you access http: // Virtual environment private IP: 5000 /
with a browser after startup, ʻindex.htmlwill be displayed. If you can confirm it, the operation check of
Flaskis completed. Next, build an AP server with
NGINX Unit`.
NGINX Unit
NGINX Unit is a lightweight application server developed by NGINX.
You can run applications in multiple languages, so you can run applications in different languages on the same server.
The language supports Python
, PHP
, Go
, Perl
, Ruby
, Node.js
, Java
.
In addition, different versions in the language can co-exist and run. (Python2.7 and Python3, etc.)
You can change the settings in real time without stopping the server via API or JSON, so you can change the settings seamlessly without stopping the service.
The Official Document has the installation method for each OS.
Get out of the venv virtual environment and add a yum repository.
(flask_sample)$ deactivate
$ sudo vi /etc/yum.repos.d/unit.repo
[unit]
name=unit repo
baseurl=https://packages.nginx.org/unit/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
Install it.
$ sudo yum install -y unit
$ sudo yum install -y unit-devel unit-go unit-jsc8 unit-perl unit-php unit-python
Sets the automatic startup of the NGINX Unit.
$ sudo systemctl enable unit
Created symlink from /etc/systemd/system/multi-user.target.wants/unit.service to /usr/lib/systemd/system/unit.service.
$ sudo service unit start
Redirecting to /bin/systemctl start unit.service
$ sudo service unit status
Redirecting to /bin/systemctl status unit.service
● unit.service - NGINX Unit
Loaded: loaded (/usr/lib/systemd/system/unit.service; enabled; vendor preset: disabled)
Active: active (running)since fire 2019-11-05 15:42:47 UTC; 7h ago
Main PID: 5714 (unitd)
CGroup: /system.slice/unit.service
├─5714 unit: main v1.12.0 [/usr/sbin/unitd --log /var/log/unit/unit.log --pid /var/run/unit/unit.pid --no-daemon]
├─5716 unit: controller
└─5717 unit: router
You can confirm that NGINX Unit can be started by service unit status
.
Set the NGINX Unit
to run Flask applications.
Set the configuration file to GET
from the NGINX Unit socket and load the Flask application into NGINX Unit
.
Unix sockets for controlling the NGINX Unit
are located in /var/run/unit/control.sock
. (The location depends on the OS)
$ cd /sample
$ sudo curl --unix-socket /var/run/unit/control.sock http://localhost/config/ > config.json
$ vi config.json
{
"listeners": {
"*:8080": {
"pass": "applications/flask_app"
}
},
"applications": {
"flask_app": {
"type": "python",
"processes": 2,
"path": "/sample/",
"module": "app"
}
}
}
--listers: Set the port. The value of pass
in *: 8080
is linked to the hierarchy of ʻapplications`.
PUT the created configuration file to the socket of NGINX Unit to reflect the configuration.
$ sudo curl -X PUT --data-binary @config.json --unix-socket /var/run/unit/control.sock http://localhost/config
{
"success": "Reconfiguration done."
}
When success
returns, the setting is complete. You can also check the settings.
$ sudo curl --unix-socket /var/run/unit/control.sock http://localhost/
{
"certificates": {},
"config": {
"listeners": {
"*:8080": {
"pass": "applications/flask_app"
}
},
"applications": {
"flask_app": {
"type": "python",
"processes": 2,
"path": "/sample/",
"module": "app"
}
}
}
}
Start the virtual environment and access http: // localhost: 8080 /
.
$ source venv/bin/activate
(flask_sample)$ curl http://localhost:8080/
<html>
<head>
<meta charset="utf-8" />
<title>Flask Sample</title>
</head>
<body>
<h1>Flask Smaple</h1>
<form action="sample" method="post">
<input type="text" name="message" />
<input type="submit" value="Send" />
</form>
</body>
</html>
Construction is complete when ʻindex.html is displayed. Even if you access it with a browser, ʻindex.html
is displayed.
That's all for building the NGINX Unit
. Next, build the web server NGINX
.
NGINX
It is an open source web server that is lightweight and fast, and is attracting attention as a potential alternative to Apache. Compared to Apache, it is superior in terms of scalability, and features such as processing performance, parallel processing, and low memory usage. This time it will be used as a proxy server.
NGINX
officially publishes a yum repository, so install from that repository.
Add the repository and install by referring to the description on Official page.
Once out of the Python virtual environment.
Add the yum repository. Add /etc/yum.repos.d/NGINX.repo
.
$ sudo vi /etc/yum.repos.d/NGINX.repo
[NGINX]
name=NGINX repo
baseurl=http://NGINX.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
Check the repository.
$ sudo yum info nginx
Available Packages
Name : NGINX
Arch : x86_64
Epoch : 1
Version : 1.16.1
Release : 1.el7_4.ngx
Size : 754 k
Repo : NGINX/x86_64
Summary : High performance web server
URL : http://NGINX.org/
License : 2-clause BSD-like license
Description : NGINX [engine x] is an HTTP and reverse proxy server, as well as
: a mail proxy server.
If you can confirm that NGINX exists in the repository with the yum info
command, install it.
$ sudo yum install nginx
Set automatic startup, Start NGINX.
$ sudo systemctl enable nginx
$ sudo service start nginx
$ ![nginx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/239179/0d818e0a-7aee-8a07-af95-72d34dfaa824.png)
service status nginx
● NGINX.service - NGINX - high performance web server
Loaded: loaded (/usr/lib/systemd/system/NGINX.service; enabled; vendor preset: disabled)
Active: active (running)
After launching NGINX, access the http: // private IP of the virtual environment
in your browser.
If the following screen is displayed, the startup is complete.
NGINX
operates as a WEB server or proxy server in front of NGINX Unit
.
Proxy the request to the application to the Nginx Unit.
The NGINX
configuration file is located in /etc/nginx/conf.d
.
$ sudo vi /etc/nginx/conf.d/app.conf
upstream unit-python {
server 127.0.0.1:8080;
}
server {
listen 80;
server_name localhost;
location ~ / {
proxy_pass http://unit-python;
proxy_set_header Host $host;
}
}
Restart NGINX and go to http: // localhost /
.
$ sudo service restart nginx
$ curl http://localhost/
<html>
<head>
<meta charset="utf-8" />
<title>Flask Sample</title>
</head>
<body>
<h1>Flask Smaple</h1>
<form action="sample" method="post">
<input type="text" name="message" />
<input type="submit" value="Send" />
</form>
</body>
</html>
If'index.html'is displayed, proxy settings are complete. You can access http: // private IP
of the virtual environment with a browser and check ʻindex.html`.
This completes the construction of the Python web application environment.
We built the environment of the WEB application with NGINX
+ NGINX Unit
+ Flask
.
Since NGINX Unit
specializes in the operation of microservices, I think it will continue to attract attention in the future.
I would like to continue to touch on it.
Recommended Posts