The original address
I’ve been learning Python recently, I’ve implemented a personal blog application in Flask, and I want to deploy it to a server. As a novice, I stumbled all the way and finally got it basically done. The information on the Internet is not very friendly to novices, they are fragmented, so I sorted it out, on the one hand, as my own record, convenient for future reference, on the other hand, I also hope to help novices like me.
The premise
-
Have a server (otherwise make wool), purchase can refer to high quality foreign VPS recommendation
-
There are personal domain names (of course, you can use IP access directly, but it’s a bit weird isn’t it? To buy a domain name, go to GoDaddy
1. Install git
You can build your own Git server on Github or Bitbucket, but I don’t think it’s necessary. Bitbucket is a free private repository
sudo yum install git
Copy the code
The following is no different from our local development. Configure SSH key, clone code, do not expand, recommend to put the project directory in /home/www/
2. Installation of Mysql
Add MySQL YUM source
$wget 'https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm'
$sudo rpm -Uvh mysql57-community-release-el7- 11.noarch.rpm
$yum repolist all | grep mysql
mysql-connectors-community/x86_64 MySQL Connectors Community 36
mysql-tools-community/x86_64 MySQL Tools Community 47
mysql57-community/x86_64 MySQL 5.7 Community Server 187
Copy the code
Install the latest version
$sudo yum install mysql-community-server
Copy the code
Start the MySQL service
$sudo service mysqld start
$sudo systemctl start mysqld #CentOS 7
$sudo systemctl status mysqld
● mysqld.service - MySQL Community Server
Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
Active: active (running) since Sat 2017-05-27 12:56:26 CST; 15s ago
Process: 2482 ExecStartPost=/usr/bin/mysql-systemd-start post (code=exited, status=0/SUCCESS)
Process: 2421 ExecStartPre=/usr/bin/mysql-systemd-start pre (code=exited, status=0/SUCCESS)
Main PID: 2481 (mysqld_safe)
CGroup: /system.slice/mysqld.service
├ ─ 2481 / bin/sh/usr/bin/mysqld_safe - basedir = / usr
├ ─ 2147 / usr/sbin/mysql.txt -- conf =/ usr/sbin/mysql.txt -- conf =/ usr/sbin/mysql.txt -- conf =/ usr/sbin/mysql.txt -- conf =/ usr/sbin/mysql.txt
Copy the code
It indicates that the system is running
Change the password
$ mysql -uroot -p
Copy the code
Run the grep “temporary password” /var/log/mysqld.log command to query the default password of the root user
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'NewPassword';
Copy the code
Modify the code
Set the default encoding in /etc/my.cnf
[client]
default-character-set = utf8
[mysqld]
default-storage-engine = INNODB
character-set-server = utf8
collation-server = utf8_general_ci # case insensitive
collation-server = utf8_bin # case sensitive
collation-server = utf8_unicode_ci # more accurate than UTf8_general_ci
Copy the code
Creating a database
mysql> CREATE DATABASE <datebasename> CHARACTER SET utf8;
Copy the code
3. Install PYTHon3 PIp3
CentOS 7 has Python 2 installed by default. If you need to use Python 3, you can manually download the Python source code and compile it.
Install Python 3
sudo mkdir /usr/local/python3 Create the installation directory
$ wget --no-check-certificate https://www.python.org/ftp/python/3.62./Python3.62..tgz Download the Python source file
# Note: when wget gets HTTPS, add --no-check-certifica
$ tar -xzvf Python3.62..tgz Unzip the package
$ cd Python3.62. Go to the unzip directory
sudo ./configure --prefix=/usr/local/python3 # specify the directory to create
sudo make
sudo make install # build install
Copy the code
Configure: error: no acceptable C compiler found in $PATH configure: error: no acceptable C compiler found in $PATH
Sudo yum install gcc-C ++ sudo yum install gcc-C ++
Configure the coexistence of two versions
Create python3 soft link:
$ sudo ln -s /usr/local/python3/bin/python3 /usr/bin/python3
Copy the code
This allows you to use Python 2 through the Python command, python3 to use Python 3.
Install the PIP
$ sudo yum -y install epel-release Install the EPEL extension source first
$ sudo yum -y install python-pip # python installed - PIP
$ sudo yum clean all # to clear the cache
Copy the code
It seems that piP2 can only be installed in this way. To install PIP in Python 3, you can install it from the following source code.
# Download source code
$ wget --no-check-certificate https://github.com/pypa/pip/archive/9.01..tar.gz
$ tar -zvxf 9.01..tar.gz Unzip the file
$ cd pip9.01.
$ python3 setup.py install # Install using Python 3
Copy the code
Create a link:
$ sudo ln -s /usr/local/python3/bin/pip /usr/bin/pip3
Copy the code
Upgrade PIP
$ pip install --upgrade pip
Copy the code
4. Install gunicorn
Gunicorn (Unicorn) is a highly efficient Python WSGI Server, which is usually used to run WSGI Applications (our own authoring specification that follows WSGI Application) or WSGI Framework (such as Django,Paster), which is equivalent to Tomcat in Java. WSGI is one such protocol: it is an interface between Python programs and user requests. The WSGI server’s job is to accept and analyze the user’s request, call the appropriate Python object to process the request, and return the corresponding result. To put it simply, Gunicorn encapsulates the underlying implementation of HTTP. We start the service through Gunicorn, and user requests and services are transmitted through Gunicorn
Creating a Virtual Environment
cd /home/www/blog
mkdir venv
python3 -m venv venv
Copy the code
Activating the virtual environment:
source venv/bin/activate
Copy the code
Then install dependencies from the requirements.txt file:
pip3 install -r requirements.txt
Copy the code
Install the gunicorn
pip3 install gunicorn
Copy the code
Create a wsgi.py file in the project root directory
from app import create_app
application = create_app('production')
if __name__ == '__main__':
application.run()
Copy the code
No longer start the service through manage.py, which is only used at development time
Start the service:
gunicorn -w 4 -b 127.0. 01.:8000 wsgi:application
Copy the code
5. Install Nginx
Nginx is a high-performance Web server. It is usually used as a reverse proxy server on the front end. The so-called “reverse” and “forward” are just English translation. Proxy service, in short, a request is sent from the LAN through a proxy server and then to a server on the Internet. The proxy for this process is forward proxy. If a request comes in from the Internet, it goes to a proxy server and is forwarded by the proxy server to the target server on the LAN, the proxy server is the reverse proxy (as opposed to forward).
Forward proxy: {client — Proxy server} — server
Reverse proxy: Client — {proxy server — > server}
{} indicates LAN
Nginx can do both forward and reverse.
$ yum -y install nginx
Copy the code
Start the nginx service
$ service nginx start
Copy the code
Stop the nginx service
$ service nginx stop
Copy the code
Restart the nginx service
$ service nginx restart
Copy the code
Smooth restart
Nginx configuration changes can be reloaded without first closing and then opening
$ nginx -s reload
Copy the code
After startup, enter the IP address of the server in the browser and you can see it
Yum install nginx
Add the configuration
The nginx configuration file is /etc/nginx/nginx.conf
server {
listen 80;
server_name adisonhyh.com;
location / {
proxy_pass http://127.0. 01.:8000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }}Copy the code
- Listen for the HTTP default port number 80
- Server_name: indicates the domain name of the personal website
- Proxy the request to port 8000 of the machine (the port specified by gunicorn to start the service) and copy the remaining proxy_set_header
Gunicorn and Nginx:
Gunicorn can be serviced separately, but production environments generally do not. Firstly, static resources (JSCSSIMG) will occupy a lot of request resources, while Gunicorn should pay more attention to the request and processing of actual business rather than waste resources on static resource requests. In addition, running Gunicorn alone does not allow multiple processes and ports to load balance.
Nginx can handle all static file requests as the front-end server. In this case, Gunicorn is the back-end server. Nginx will forward dynamic requests to the back-end server, so we can have multiple Gunicorn processes. Then let NGINx load balance forwarding requests to multiple Gunicorn processes to improve server processing efficiency and capacity. Finally, nginx can also configure a lot of security-related, authentication-related processing, so that your website can focus more on business writing, leaving some non-business things like forwarding rules to Nginx.
After configuration, open the local browser, enter the domain name, should be able to access.
6.supervisor
Supervisor is a good choice if you need the process to run all the time and automatically restart it if it is interrupted for any reason. The Supervisor manages the processes by starting them as children of the Supervisor by fork/exec, so all we need to do is add the path of the executable that will manage the processes to the Supervisor configuration file. If the supervisor process is abnormal, the parent process can obtain information about the abnormal supervisor process. By setting AutoStart =true in the configuration file, the parent process can automatically restart the abnormal supervisor process.
The installation supervisor
$ pip install supervisor
$ echo_supervisord_conf > supervisor.conf Generate the Supervisor default configuration file
$ vim supervisor.conf Modify the Supervisor configuration file to add the Gunicorn process management
Copy the code
Add to the bottom of the blog supervisor.conf configuration file (note that my working path is WWW /home/blog/)
[the program: blog] command = / home/WWW/blog/venv/bin/gunicorn w4 - b0.0.0.0:8000 wsgi: application; Supervisor start command directory=/home/ WWW /blog; Project folder path startSecs =0; Start time stopWaitSecs =0; Autostart =false; Autorestart =false; Whether automatic restart stdout_logfile = / home/WWW/blog/logs/gunicorn log; The log log stderr_logfile = / home/WWW/blog/logs/gunicorn err; The error logCopy the code
Start Gunicorn with Supervsior
$ sudo supervisord -c supervisor.conf
$ sudo supervisorctl start blog
Copy the code
To access the website, enter the configured address in the address bar of the browser.
7. fabric
As a final step, we use Fabric for remote operation and deployment. Fabric is a Python tool similar to Makefiles, but capable of executing commands on remote servers.
Install the fabric
pip install fabric
Copy the code
Create a new fabfile.py file in the blog directory
import os
from fabric.api import local, env, run, cd, sudo, prefix, settings, execute, task, put
from fabric.contrib.files import exists
from contextlib import contextmanager
env.hosts = ['204.152.201.69']
env.user = 'root'
env.password = '* * * *'# your password
env.group = "root"
DEPLOY_DIR = '/home/www/blog'
VENV_DIR = os.path.join(DEPLOY_DIR, 'venv')
VENV_PATH = os.path.join(VENV_DIR, 'bin/activate')
@contextmanager
def source_virtualenv(a):
with prefix("source {}".format(VENV_PATH)):
yield
def update(a):
with cd('/home/www/blog/'):
sudo('git pull')
def restart(a):
with cd(DEPLOY_DIR):
if not exists(VENV_DIR):
run("virtualenv {}".format(VENV_DIR))
with settings(warn_only=True) :with source_virtualenv():
run("pip install -r {}/requirements.txt".format(DEPLOY_DIR))
with settings(warn_only=True):
stop_result = sudo("supervisorctl -c {}/supervisor.conf stop all".format(DEPLOY_DIR))
if not stop_result.failed:
kill_result = sudo("pkill supervisor")
if not kill_result:
sudo("supervisord -c {}/supervisor.conf".format(DEPLOY_DIR))
sudo("supervisorctl -c {}/supervisor.conf reload".format(DEPLOY_DIR))
sudo("supervisorctl -c {}/supervisor.conf status".format(DEPLOY_DIR))
sudo("supervisorctl -c {}/supervisor.conf start all".format(DEPLOY_DIR))
@task
def deploy(a):
execute(update)
execute(restart)
Copy the code
Now, if the code is updated, you can perform remote deployment directly locally
fab deploy
Copy the code