赞
踩
如需转载请注明出处。
win10 64位、Python 3.6.3、Notepad++、Chrome 67.0.3396.99(正式版本)(64 位)
注:作者编写时间2018-03-28,linux、python 3.5.2
以下内容均是加入自己的理解与增删,以记录学习过程。不限于翻译,部分不完全照搬作者Miguel Grinberg的博客,版权属于作者,感谢他提供免费学习的资料。
那么基于Linux内核的Linux发行版本有N多,如主流Linux发行版(常见的Ubuntu、CentOS、Debian、等等)、中国内地Linux发行版(雨林木风YLMF OS 哈哈、红旗Linux、等等)。
本章将学习把 Microblog部署到Linux服务器。将在Microblog应用程序的生命周期中达到一个里程碑,接下来将讨论如何在生产服务器上部署应用程序,以便真实用户可以访问它。
本章仅致力于探索 传统的托管,在此将使用 运行Ubuntu的专用Linux服务器,以及广受欢迎的Raspberry Pi小型计算机。
在部署项目时,需要解决的第一个问题是 在哪里找到服务器。在国内(中国)用的多可能就是阿里云、腾讯云、UCloud了;国际可选择 AWS。不过在不花钱的情况下练习部署,Vagrant、VirtualBox两个工具结合,也可以在自己的计算机上创建类似于付费虚拟服务器的 虚拟服务器。
就操作系统选择而言,从技术角度看,我们这个应用程序可以部署在任何主要的操作系统上,包括各种开源Linux和BSD发行版的列表、以及商业OS X和Microsoft Windows。
由于OS X 和Windows是未经优化用作服务器的桌面操作系统,故将其作为候选者丢弃。Linux或BSD操作系统之间的选择很大程度上取决于偏好,因此选择最受欢迎的 Linux。而就Linux发行版而言,将按人气选择Ubuntu。
免费方案是 自己的计算机上运行虚拟机(后续研究)。在计算机上安装 Vagrant和VirtualBox,然后创建名为 Vagrantfile
的文件,用如下内容描述VM的规范:
Vagrantfile:Vagrant配置
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.provider "virtualbox" do |vb|
vb.memory = "1024"
end
end
此文件配置具有1GB RAM的Ubuntu 16.04服务器,可以从IP地址为192.168.33.10的主机访问该服务器。要创建服务器,请运行以下命令:
$ vagrant up
参阅Vagrant 命令行文档以了解管理虚拟服务器的其他选项。
在此,服务器并不像在自己计算机上那样拥有桌面。所以得通过SSH客户端
来连接到服务器,并通过命令行处理它。由于我用的是win10,则可选择 Cygwin、Git、Windows Subsystem for Linux中的任一个,它们提供OpenSSH。在此,我使用Git。
如果使用的是来自第三方提供商的虚拟服务器,则在创建服务器时,会获得一个IP地址。可使用如下命令打开与全新服务器的终端会话:
Administrator@Cchen-PC MINGW64 /
$ ssh ubuntu@<腾讯云-公网IP>
ubuntu@<腾讯云-公网IP>'s password:输入密码
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-130-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
ubuntu@VM-0-10-ubuntu:~$
PS:腾讯云主机Ubuntu系统默认用户名为 ubuntu
,登录服务器时每一次都是以默认账户ubuntu
进行登录。
如果使用Vagrant VM,则可以使用如下命令打开终端会话:
$ vagrant ssh
如果使用的Windows并拥有Vagrant VM,注意 将需要从shell运行上述命令,它能调用OpenSSHd ssh
命令。
如果使用的虚拟服务器,建议创建一个常规用户账户来进行部署工作,并配置此账户以便在不使用密码的情况下登录,不仅更方便而且更安全。
接下来将配置 ubuntu
账户已使用公钥身份验证,以便无需键入密码即可登录。
首先,腾讯云控制平台 安全组 开放公网端口 至少要开放22端口。
将已打开的具有服务器的终端会话暂时保留(不关闭),然后在本地计算机上其中第二个终端(Git),用如下命令检查 ~/.ssh
目录的内容:
Administrator@Cchen-PC MINGW64 /
$ ls ~/.ssh
id_rsa id_rsa.pub
如果目录列表显示如同上述名为 id_rsa 和id_rsa.pub的文件,那么意味着已有一个密钥。如果没有这两个文件 或根本没有~/.ssh
目录 ,那么需要通过运行以下命令来创建SSH密钥对
,该命令也是OpenSSH工具集的一部分:
$ ssh-keygen -t rsa -b 1024
注意这个命令,观察 腾讯云平台生成的私钥长度比本地生成的要短,即本地生成公钥对时 需生成1024bits长度的密钥。故 加上 -b
参数。
将提示输入一些内容,建议在所有提示中按Enter键接受默认值。当然,如果知道在做什么,想要做什么,可不接受默认值。
运行上述命令后,将会具有上方所列出的两个文件(以我为例,这两个文件将存放在C:\Users\Administrator\.ssh
)。id_rsa.pub文件 是你的公钥,它是一个文件,将提供给第三方作为识别你的方式。id_rsa文件是你的私钥,不应与任何人共享。
现在需要将公钥配置为 服务器中的授权主机,在自己的计算机上打开终端,将公钥打印到屏幕上:
Administrator@Cchen-PC MINGW64 /
$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQD5HPx4k0SOz9/q/bnlYINvjPBy7O13hDiAy1PDArqSmHCO6/ZGDSQb+151NsVyzoqnMNyemNyYncCnE6iMmpQSVOi6VYbdHcaUfjbHsI8xHbtJokKfJbryNy+bPezgF8/A6fg3s5uSHPJJNDbMumKv8TdjW/Wcimi8xp4HZk4xXQ== Administrator@Cchen-PC
这是一个很长的字符序列,可能跨越多行。将此数据复制到剪贴板,然后切换回远程服务器上的终端(一开始的终端),用如下命令保存公钥:
ubuntu@VM-0-10-ubuntu:~$ echo ssh-rsa <paste-your-key-here> >> ~/.ssh/authorized_keys
ubuntu@VM-0-10-ubuntu:~$ chmod 600 ~/.ssh/authorized_keys
无密码登录现在应该正常工作。想法是你计算机上的ssh将通过执行需要密钥的加密操作来向服务器标识自己。然后,服务器使用你的公钥验证操作是否有效。
现在可退出ubuntu会话(如 exit命令 或直接关闭终端窗口后重新打开),然后尝试使用下方命令直接登录ubuntu
账户:
$ ssh ubuntu@<腾讯云-公网IP>
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-130-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
New release '18.04.1 LTS' available.
Run 'do-release-upgrade' to upgrade to it.
Last login: Thu Sep 6 21:51:59 2018 from 183.14.134.229
ubuntu@VM-0-10-ubuntu:~$
这次不必输入密码!
第一个改变:通过SSH禁用root登录。
现在可以无密码访问ubuntu
账户,并可以通过此账户运行管理员命令 sudo
,因此实际上不需要公开root账户。要禁用root登录,需编辑服务器上的/etc/ssh/sshd_config
文件。在git上登录服务器
后,输入如下命令,回车:
ubuntu@VM-0-10-ubuntu:~$ sudo vi /etc/ssh/sshd_config
更改此文件中的一行:
/etc/ssh/sshd_config:禁用root登录
PermitRootLogin no
第二个改变:禁用所有账户的密码登录。更改还是在同一个文件中。
我有 无密码登录设置,因此根本不需要允许密码。如果对完全禁用密码感到紧张,可跳过此更改,但对于生产服务器来说,这是个好主意,因为攻击者不断尝试在所有希望幸运的服务器上使用随机账户名和密码。
/etc/ssh/sshd_config:禁用root登录
PasswordAuthentication no
完成SSH配置编辑后在底部输入 :wq
(Linux命令,意为 保存并退出vi),需要重新启动服务才能使更改生效:
ubuntu@VM-0-10-ubuntu:~$ sudo service ssh restart
第三个改变:安装防火墙。(暂未在腾讯云 webshell上操作)
这是一个阻止未明确启用的任何端口上对服务器的访问的软件:
ubuntu@VM-0-10-ubuntu:~$ sudo apt-get install -y ufw Reading package lists... Done Building dependency tree Reading state information... Done ufw is already the newest version (0.35-0ubuntu2). 0 upgraded, 0 newly installed, 0 to remove and 197 not upgraded. ubuntu@VM-0-10-ubuntu:~$ sudo ufw allow ssh Rules updated Rules updated (v6) ubuntu@VM-0-10-ubuntu:~$ sudo ufw allow http Rules updated Rules updated (v6) ubuntu@VM-0-10-ubuntu:~$ sudo ufw allow 443/tcp Rules updated Rules updated (v6) ubuntu@VM-0-10-ubuntu:~$ sudo ufw --force enable Firewall is active and enabled on system startup ubuntu@VM-0-10-ubuntu:~$ sudo ufw status Status: active To Action From -- ------ ---- 22 ALLOW Anywhere 80 ALLOW Anywhere 443/tcp ALLOW Anywhere 22 (v6) ALLOW Anywhere (v6) 80 (v6) ALLOW Anywhere (v6) 443/tcp (v6) ALLOW Anywhere (v6)
这些命令安装ufw(简单防火墙,版本0.35-0ubuntu2),并将其配置为仅允许端口22(ssh),80(http)和443(https)上的外部流量。不允许任何其他端口。
基本的Python解释器可能已预先安装在腾讯云服务器上,但是有一些额外的软件包可能没有,而且还有一些其他Python外的软件包(用于创建健壮的生产就绪部署)。对于数据库服务器,我将从SQLite切换到MySQL。postfix包是一个邮件传输代理,我将它发送电子邮件。supervisor工具将监视Flask服务器进程,并在崩溃时自动重启它,或如果服务器重新启动也会自动重启。nginx服务器将接受来自外部世界的所有请求,并将它们转发给应用程序。最后,我将使用git作为直接从git仓库下载应用程序的工具。
在git上登录服务器后(或腾讯云 WebShell中)输入如下命令:
$ sudo apt-get -y update
$ sudo apt-get -y install python3 python3-venv python3-dev
$ sudo apt-get -y install mysql-server postfix supervisor nginx git
其中,各自版本如下:
名称 | 版本号 |
---|---|
MySQL | 5.7.23 |
postfix | 3.1.0 |
supervisor | 3.2.0 |
nginx | 1.10.3 |
git | 1:2.7.4 |
上述安装软件包 是“无人值守”的,在运行第三个安装语句的某个时刻时,系统会提示选择输入MySQL服务器的root密码(输入你想设置的密码),并且还会询问有关安装 postfix软件包的几个问题,可接受它们默认答案。
注意,上述部署,不安装Elasticsearch。这个服务需要大量RAM,因此得拥有大于2GB RAM的大型服务器才能实现。。为了避免服务器内存不足的问题,将保留搜索功能。如果你是土豪,服务器足够大,可以从Elasticsearch网站下载官方.deb
软件包,并按照其安装说明将其添加到我们的服务器。不过注意,在Ubuntu 16.04软件包仓库中提供的Elasticsearch软件包太老而无法使用,需要安装6.x或更高版本。
还应该注意,postfix的默认安装可能不足以在生产环境中发送电子邮件。为了避免垃圾邮件和恶意电子邮件,许多服务器要求发件人服务器通过安全扩展来识别自己,这意味着至少必须拥有与我们服务器关联的域名。如果想了解如何完全配置电子邮件服务器以使其通过标准安全测试,可参阅下方Digital Ocean 指南:
接着,输入touch .gitignore
命令,此时microblog文件夹下就生成一个 .gitignore
文件。
最后 git bash中输入 vi .gitignore
命令编辑.gitignore
文件。输入我要忽略的文件夹、文件。见我的github查看具体的编辑内容。
具体可参考大牛博客1
博客2
上传代码至github的步骤:
Git Bash Here
进入命令行,从而进入项目所在目录;①git init
②git add .
③git commit -m "部署到腾讯云 Ubuntu上的microblog应用程序代码(截止到教程第17章 )"
④git remote add origin https://github.com/czy0905/microblog.git
⑤git push -u origin master
在上述输入最后一个命令时,会提示输入github用户名和密码。
git bash登录腾讯云
$ ssh ubuntu@134.175.205.116 Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-130-generic x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/advantage New release '18.04.1 LTS' available. Run 'do-release-upgrade' to upgrade to it. Last login: Fri Sep 7 19:54:43 2018 from 183.14.134.229 ubuntu@VM-0-10-ubuntu:~$ ls -l total 8 drwxrwxr-x 5 ubuntu ubuntu 4096 Sep 7 19:55 microblog drwxrwxr-x 6 ubuntu ubuntu 4096 Sep 7 20:01 venv ubuntu@VM-0-10-ubuntu:~$ ~ #代表[目前用户身份]所在的家目录 -bash: /home/ubuntu: Is a directory ubuntu@VM-0-10-ubuntu:~$ cd microblog #进入microblog目录 ubuntu@VM-0-10-ubuntu:~/microblog$ ls -l #以长格式显示目录下的内容列表 total 28 drwxrwxr-x 8 ubuntu ubuntu 4096 Sep 7 19:55 app -rw-rw-r-- 1 ubuntu ubuntu 101 Sep 7 19:55 babel.cfg -rw-rw-r-- 1 ubuntu ubuntu 898 Sep 7 19:55 config.py -rw-rw-r-- 1 ubuntu ubuntu 209 Sep 7 19:55 microblog.py drwxrwxr-x 3 ubuntu ubuntu 4096 Sep 7 19:55 migrations -rw-rw-r-- 1 ubuntu ubuntu 600 Sep 7 19:55 requirements.txt -rw-rw-r-- 1 ubuntu ubuntu 2940 Sep 7 19:55 tests.py ubuntu@VM-0-10-ubuntu:~/microblog$
现在将使用 git
从我的GitHub仓库下载 Microblog源代码。要将应用程序下载到服务器,请确保目前位于ubuntu
用户的主目录中,然后运行如下命令:
ubuntu@VM-0-10-ubuntu:~$ git clone https://github.com/czy0905/microblog.git
Cloning into 'microblog'...
remote: Counting objects: 62, done.
remote: Compressing objects: 100% (52/52), done.
remote: Total 62 (delta 5), reused 62 (delta 5), pack-reused 0
Unpacking objects: 100% (62/62), done.
Checking connectivity... done.
ubuntu@VM-0-10-ubuntu:~$ cd microblog
ubuntu@VM-0-10-ubuntu:~$ git checkout v0.17
上述将在我的服务器上安装代码,并将其与本章同步。如果将本教程的代码版本保存在自己的git仓库中,则可以将存储仓库URL更改为自个的URL,在这种情况下可跳过 git checkout
命令。
现在需要创建一个虚拟环境,并使用所有包依赖项填充它,在第15章已方便地保存到requirements.txt
文件中了:
ubuntu@VM-0-10-ubuntu:~$ ls -l #列出当前主目录下的文件夹/文件 total 4 drwxrwxr-x 5 ubuntu ubuntu 4096 Sep 7 19:55 microblog ubuntu@VM-0-10-ubuntu:~$ cd microblog #进入microblog目录 ubuntu@VM-0-10-ubuntu:~/microblog$ python3 -m venv venv #在microblog目录下建立虚拟环境 ubuntu@VM-0-10-ubuntu:~/microblog$ ls -l #列出此目录所有文件夹/文件 total 32 drwxrwxr-x 8 ubuntu ubuntu 4096 Sep 7 19:55 app -rw-rw-r-- 1 ubuntu ubuntu 101 Sep 7 19:55 babel.cfg -rw-rw-r-- 1 ubuntu ubuntu 898 Sep 7 19:55 config.py -rw-rw-r-- 1 ubuntu ubuntu 209 Sep 7 19:55 microblog.py drwxrwxr-x 3 ubuntu ubuntu 4096 Sep 7 19:55 migrations -rw-rw-r-- 1 ubuntu ubuntu 600 Sep 7 19:55 requirements.txt -rw-rw-r-- 1 ubuntu ubuntu 2940 Sep 7 19:55 tests.py drwxrwxr-x 6 ubuntu ubuntu 4096 Sep 7 20:36 venv ubuntu@VM-0-10-ubuntu:~/microblog$ cd venv ubuntu@VM-0-10-ubuntu:~/microblog/venv$ ls -l total 20 drwxrwxr-x 2 ubuntu ubuntu 4096 Sep 7 20:36 bin drwxrwxr-x 2 ubuntu ubuntu 4096 Sep 7 20:36 include drwxrwxr-x 3 ubuntu ubuntu 4096 Sep 7 20:36 lib lrwxrwxrwx 1 ubuntu ubuntu 3 Sep 7 20:36 lib64 -> lib -rw-rw-r-- 1 ubuntu ubuntu 69 Sep 7 20:36 pyvenv.cfg drwxrwxr-x 3 ubuntu ubuntu 4096 Sep 7 20:36 share ubuntu@VM-0-10-ubuntu:~/microblog/venv$ cd .. #回到上一级目录(microblog目录) ubuntu@VM-0-10-ubuntu:~/microblog$ source venv/bin/activate #激活虚拟环境(进入虚拟环境) (venv) ubuntu@VM-0-10-ubuntu:~/microblog$ pip install -r requirements.txt #安装依赖文件 Collecting alembic==1.0.0 (from -r requirements.txt (line 1)) Downloading http://mirrors.tencentyun.com/pypi/packages/96/c7/a4129db460c3e0ea8fea0c9eb5de6680d38ea6b6dcffcb88898ae42e170a/alembic-1.0.0-py2.py3-none-any.whl (158kB) 100% |████████████████████████████████| 163kB 3.0MB/s ... ... Failed to build blinker dominate Flask-Bootstrap Flask-Login Flask-Mail guess-language-spirit itsdangerous Mako MarkupSafe python-editor SQLAlchemy visitor Installing collected packages: six, python-dateutil, python-editor, SQLAlchemy, MarkupSafe, Mako, alembic, pytz, Babel, blinker, certifi, chardet, click, dominate, urllib3, elasticsearch, Werkzeug, itsdangerous, Jinja2, Flask, Flask-Babel, visitor, Flask-Bootstrap, Flask-Login, Flask-Mail, Flask-SQLAlchemy, Flask-Migrate, Flask-Moment, WTForms, Flask-WTF, guess-language-spirit, idna, PyJWT, python-dotenv, requests Running setup.py install for python-editor ... done Running setup.py install for SQLAlchemy ... done Running setup.py install for MarkupSafe ... done Running setup.py install for Mako ... done Running setup.py install for blinker ... done Running setup.py install for dominate ... done Running setup.py install for itsdangerous ... done Running setup.py install for visitor ... done Running setup.py install for Flask-Bootstrap ... done Running setup.py install for Flask-Login ... done Running setup.py install for Flask-Mail ... done Running setup.py install for guess-language-spirit ... done Successfully installed Babel-2.6.0 Flask-1.0.2 Flask-Babel-0.11.2 Flask-Bootstrap-3.3.7.1 Flask-Login-0.4.1 Flask-Mail-0.9.1 Flask-Migrate-2.2.1 Flask-Moment-0.6.0 Flask-SQLAlchemy-2.3.2 Flask-WTF-0.14.2 Jinja2-2.10 Mako-1.0.7 MarkupSafe-1.0 PyJWT-1.6.4 SQLAlchemy-1.2.10 WTForms-2.2.1 Werkzeug-0.14.1 alembic-1.0.0 blinker-1.4 certifi-2018.8.24 chardet-3.0.4 click-6.7 dominate-2.3.1 elasticsearch-6.3.1 guess-language-spirit-0.5.3 idna-2.7 itsdangerous-0.24 python-dateutil-2.7.3 python-dotenv-0.9.1 python-editor-1.0.3 pytz-2018.5 requests-2.19.1 six-1.11.0 urllib3-1.23 visitor-0.1.3 You are using pip version 8.1.1, however version 18.0 is available. You should consider upgrading via the 'pip install --upgrade pip' command.
PS:退出虚拟环境 deactivate
;删除虚拟环境 rm -r venv
除了在requirements.txt
中常见的依赖,我还将使用两个包 特定于我们的生产部署,因此它们不包含在requirements.txt
文件中。一个是gunicorn
包,它是Python应用程序的生产Web服务器。另一个是pymysql
软件包,它包含MySQL驱动程序,使SQLAlchemy能使用MySQL数据库:
(venv) ubuntu@VM-0-10-ubuntu:~/microblog$ pip install gunicorn pymysql Looking in indexes: http://mirrors.tencentyun.com/pypi/simple Requirement already satisfied: gunicorn in ./venv/lib/python3.5/site-packages (19.9.0) Collecting pymysql Downloading http://mirrors.tencentyun.com/pypi/packages/a7/7d/682c4a7da195a678047c8f1c51bb7682aaedee1dca7547883c3993ca9282/PyMySQL-0.9.2-py2.py3-none-any.whl (47kB) 100% |████████████████████████████████| 51kB 2.0MB/s Collecting cryptography (from pymysql) Downloading http://mirrors.tencentyun.com/pypi/packages/59/32/92cade62c645756a83598edf56289e9b19aae5370642a7ce690cd06bc72f/cryptography-2.3.1-cp34-abi3-manylinux1_x86_64.whl (2.1MB) 100% |████████████████████████████████| 2.1MB 4.5MB/s Requirement already satisfied: idna>=2.1 in ./venv/lib/python3.5/site-packages (from cryptography->pymysql) (2.7) Requirement already satisfied: cffi!=1.11.3,>=1.7 in ./venv/lib/python3.5/site-packages (from cryptography->pymysql) (1.11.5) Requirement already satisfied: six>=1.4.1 in ./venv/lib/python3.5/site-packages (from cryptography->pymysql) (1.11.0) Requirement already satisfied: asn1crypto>=0.21.0 in ./venv/lib/python3.5/site-packages (from cryptography->pymysql) (0.24.0) Requirement already satisfied: pycparser in ./venv/lib/python3.5/site-packages (from cffi!=1.11.3,>=1.7->cryptography->pymysql) (2.18) Installing collected packages: cryptography, pymysql Successfully installed cryptography-2.3.1 pymysql-0.9.2
还需要创建一个.env
文件,其中包含所有必需的环境变量:
/home/ubuntu/microblog/.env:环境配置。
(venv) ubuntu@VM-0-10-ubuntu:~/microblog$ touch .env #新建文件
(venv) ubuntu@VM-0-10-ubuntu:~/microblog$ vi .env 编辑文件
接着编辑(输入如下内容。#符号内容请输入自己真实的)
SECRET=0b0299d9bc0c4e5db6196c20d6948a82
MAIL_SERVER=smtp.qq.com
MAIL_PORT=465
MAIL_USE_SSL=True
MAIL_USERNAME=##@qq.com
MAIL_PASSWORD=##
DATABASE_URL=mysql+pymysql://microblog:<密码>@localhost:3306/microblog
APPID=##
BD_TRANSLATOR_KEY=##
上述.env
文件大致类似于在第15章中展示的示例,但这SECRET_KEY
使用了随机字符串。为了生成此随机字符串,使用如下命令:
(venv) ubuntu@VM-0-10-ubuntu:~/microblog$ python3 -c "import uuid; print(uuid.uuid4().hex)"
0b0299d9bc0c4e5db6196c20d6948a82
对于DATABASE_URL
变量,定义了一个MySQL URL。将在下一小节中展示如何配置数据库。
还需要将FLASK_APP
环境变量设置为应用程序的入口点 以使flask
命令起作用,但在解析.env
文件之前需要此变量,因此需要手动设置。为了避免每次都设置它,将其添加到账户的~/.profile
文件的底部ubuntu,以便每次登陆时自动设置它:
(venv) ubuntu@VM-0-10-ubuntu:~/microblog$ echo "export FLASK_APP=microblog.py" >> ~/.profile (venv) ubuntu@VM-0-10-ubuntu:~/microblog$ flask --help [2018-09-07 21:58:12,845] INFO in __init__: Microblog startup Usage: flask [OPTIONS] COMMAND [ARGS]... A general utility script for Flask applications. Provides commands from Flask, extensions, and the application. Loads the application defined in the FLASK_APP environment variable, or from a wsgi.py file. Setting the FLASK_ENV environment variable to 'development' will enable debug mode. $ export FLASK_APP=hello.py $ export FLASK_ENV=development $ flask run Options: --version Show the flask version --help Show this message and exit. Commands: db Perform database migrations. routes Show the routes for the app. run Runs a development server. shell Runs a shell in the app context.
如果我退出,并重新登陆,现在FLASK_APP
将为我设置。可以通过运行flask --help
确认它已设置。如果帮助显示应用程序添加的translate
命令,则表示已找到应用程序。
PS:上述并没有translate
选项。未成功。待解决!!
解决:在腾讯云 Ubuntu,应该 set
不是export
。
(venv) ubuntu@VM-0-10-ubuntu:~/microblog$ echo "set FLASK_APP=microblog.py" >> ~/.profile (venv) ubuntu@VM-0-10-ubuntu:~/microblog$ flask --help [2018-09-07 22:26:41,190] INFO in __init__: Microblog startup Usage: flask [OPTIONS] COMMAND [ARGS]... A general utility script for Flask applications. Provides commands from Flask, extensions, and the application. Loads the application defined in the FLASK_APP environment variable, or from a wsgi.py file. Setting the FLASK_ENV environment variable to 'development' will enable debug mode. $ export FLASK_APP=hello.py $ export FLASK_ENV=development $ flask run Options: --version Show the flask version --help Show this message and exit. Commands: db Perform database migrations. routes Show the routes for the app. run Runs a development server. shell Runs a shell in the app context. translate
可看到 translate
命令。
现在flask
命令功能正常,我们可以编译语言翻译:
(venv) ubuntu@VM-0-10-ubuntu:~/microblog$ flask translate compile
[2018-09-07 22:29:30,065] INFO in __init__: Microblog startup
compiling catalog app/translations/zh/LC_MESSAGES/messages.po to app/translations/zh/LC_MESSAGES/messages.mo
要管理数据库服务器,我将使用mysql命令,该命令已经安装在我的服务器上:
(venv) ubuntu@VM-0-10-ubuntu:~/microblog$ mysql -u root -p Enter password:#输入密码 Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 4 Server version: 5.7.23-0ubuntu0.16.04.1 (Ubuntu) Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>
请注意,需键入在安装MySQL时选择的MySQL root密码才能访问MySQL命令提示符。
下方命令用于 创建一个新的名为microblog
的数据库,以及具有完全访问权限的同名用户:
mysql> create database microblog character set utf8 collate utf8_bin; Query OK, 1 row affected (0.00 sec) mysql> create user 'microblog'@'localhost' identified by '<db-password>'; Query OK, 0 rows affected (0.00 sec) mysql> grant all privileges on microblog.* to 'microblog'@'localhost'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.01 sec) mysql> quit; Bye (venv) ubuntu@VM-0-10-ubuntu:~/microblog$
你将需要用一个你自己选择的密码去替换<db-password>
。这将是microblog
数据库用户的密码,因此,最好不要跟root
用户选择相同的密码(我个人为了方便记忆,是使用相同的。哈哈!)。当然,对于microblog
用户的密码,需要匹配之前在.env
文件中包含的DATABASE_URL
变量。
如果数据库配置正确,现在可运行 创建所有表的数据库迁移:
(venv) ubuntu@VM-0-10-ubuntu:~/microblog$ flask db upgrade
[2018-09-07 22:40:24,100] INFO in __init__: Microblog startup
INFO [alembic.runtime.migration] Context impl SQLiteImpl.
INFO [alembic.runtime.migration] Will assume non-transactional DDL.
INFO [alembic.runtime.migration] Running upgrade -> 1f1d69541c8c, users table
INFO [alembic.runtime.migration] Running upgrade 1f1d69541c8c -> c0139b2ef594, posts table
INFO [alembic.runtime.migration] Running upgrade c0139b2ef594 -> 00cd8a8ea68a, new fields in user model
INFO [alembic.runtime.migration] Running upgrade 00cd8a8ea68a -> 65b4b5c357fa, followers
INFO [alembic.runtime.migration] Running upgrade 65b4b5c357fa -> 2c59449fbf9a, add language to posts
(venv) ubuntu@VM-0-10-ubuntu:~/microblog$
在继续之前,请确保上述命令完成,而不会产生任何错误。
要在gunicorn下启动Microblog,可使用下方命令:
(venv) ubuntu@VM-0-10-ubuntu:~/microblog$ gunicorn -b localhost:8000 -w 4 microblog:app
[2018-09-07 22:55:23 +0800] [23967] [INFO] Starting gunicorn 19.9.0
[2018-09-07 22:55:23 +0800] [23967] [INFO] Listening at: http://127.0.0.1:8000 (23967)
[2018-09-07 22:55:23 +0800] [23967] [INFO] Using worker: sync
[2018-09-07 22:55:23 +0800] [23970] [INFO] Booting worker with pid: 23970
[2018-09-07 22:55:23 +0800] [23971] [INFO] Booting worker with pid: 23971
[2018-09-07 22:55:23 +0800] [23972] [INFO] Booting worker with pid: 23972
[2018-09-07 22:55:23 +0800] [23973] [INFO] Booting worker with pid: 23973
[2018-09-07 22:55:25,030] INFO in __init__: Microblog startup
[2018-09-07 22:55:25,091] INFO in __init__: Microblog startup
[2018-09-07 22:55:25,097] INFO in __init__: Microblog startup
[2018-09-07 22:55:25,111] INFO in __init__: Microblog startup
上述命令中 -b
选项 告知gunicorn在哪里监听请求,命令中设置为端口8000
的内部网络接口。在没有外部访问的情况下运行Python Web应用程序,这通常是一个好主意;然后有一个非常快速的Web服务器,该服务器经过优化以便提供服务器静态文件 接受来自客户端的所有请求。此快速Web服务器将直接提供静态文件,并将针对应用程序的任何请求转发到内部服务器。下一小节将展示如何将nginx设置为面向公众的服务器。
-w
选项 配置gunicorn将运行的worker数量。拥有4个worker将允许应用程序同时处理多达4个客户端,对于Web应用程序而言通常足以处理大量客户端,因为并非所有客户端都在不断地请求内容。根据服务器的RAM大小,可能需要调整worker数量,以免内存不足。
microblog:app
参数告诉gunicorn如何加载应用程序实例。冒号前的名称是 包含应用程序的模块;冒号后的名称是这个应用程序的名称。
虽然gunicorn设置非常简单,但从命令行运行服务器 实际上并不是生产服务器的好解决方案。我想要的是 让服务器在后台运行,并让它在持续监控下,因为如果由于任何原因服务器崩溃并退出,我想确保自动启动新服务器以取代它。而且我还想确保 如果重新启动计算机,服务器会在启动时自动运行,而无需我自己登录和启动。要做到以上几点,就可以使用上方安装的supervisor包来完成这些操作。
supervisor
效用 使用配置文件来告诉它要监视哪些程序、以及在必要时如何重启启动它们。配置文件必须存储在/etc/supervisor/conf.d
中。这是Microblog的配置文件,将其称为 microblog.conf
:
/etc/supervisor/conf.d/microblog.conf:supervisor配置
ubuntu@VM-0-10-ubuntu:~$ cd /etc/supervisor/conf.d
ubuntu@VM-0-10-ubuntu:/etc/supervisor/conf.d$ sudo touch microblog.conf #要加上sudo。新建这个.conf文件
ubuntu@VM-0-10-ubuntu:/etc/supervisor/conf.d$ ls -l
total 0
-rw-r--r-- 1 root root 0 Sep 8 16:23 microblog.conf
ubuntu@VM-0-10-ubuntu:/etc/supervisor/conf.d$ sudo vi microblog.conf #要加上sudo。编辑文件
sudo vi microblog.conf
编辑内容如下:
[program:microblog]
command=/home/ubuntu/microblog/venv/bin/gunicorn -b localhost:8000 -w 4 microblog:app
directory=/home/ubuntu/microblog
user=ubuntu
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
command
、directory
、user
设置告诉supervisor如何运行应用程序。当计算机开机或崩溃时,autostart
和autorestart
设定了自动重启。stopasgroup
和killasgroup
用来确保当supervisor需要去停止应用程序去重新启动它,它也达到了gunicorn进程的子进程。
在编写完这个配置文件后,必须重新加载supervisor服务 用于导入它:
ubuntu@VM-0-10-ubuntu:/etc/supervisor/conf.d$ sudo supervisorctl reload
Restarted supervisord
ubuntu@VM-0-10-ubuntu:/etc/supervisor/conf.d$
就这样,gunicorn Web服务器应该会启动 并运行和监控了。
我希望这是一个安全的部署,因此我将配置端口80
以将所有流量转到将要加密的端口443
。所以我首先将创建一个SSL证书。现在要创建一个自签名SSL证书,可以测试所有单不适合实际部署,因为Web浏览器会警告用户证书不是由受信任的证书颁发机构颁发的。给Microblog创建SSL证书的命令是:
ubuntu@VM-0-10-ubuntu:~/microblog$ openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 -keyout certs/key.pem -out certs/cert.pem Generating a 4096 bit RSA private key ..................................................................++ ...............++ writing new private key to 'certs/key.pem' ----- You are about to be asked to enter information that will be incorporated into your certificate request. What you are about to enter is what is called a Distinguished Name or a DN. There are quite a few fields but you can leave some blank For some fields there will be a default value, If you enter '.', the field will be left blank. ----- Country Name (2 letter code) [AU]:CH State or Province Name (full name) [Some-State]:GuangDong Locality Name (eg, city) []:ShenZhen Organization Name (eg, company) [Internet Widgits Pty Ltd]:CYG Organizational Unit Name (eg, section) []:Test Common Name (e.g. server FQDN or YOUR name) []:Yankeen Email Address []:<填写你自己的>@qq.com ubuntu@VM-0-10-ubuntu:~/microblog$ cd certs ubuntu@VM-0-10-ubuntu:~/microblog/certs$ ls -l total 8 -rw-rw-r-- 1 ubuntu ubuntu 2098 Sep 8 17:00 cert.pem -rw-rw-r-- 1 ubuntu ubuntu 3272 Sep 8 17:00 key.pem ubuntu@VM-0-10-ubuntu:~/microblog/certs$
这个命令将询问有关你的应用程序和自己的一些信息(国家、省份、城市、公司名称、姓名等)。这些将是包含在SSL证书中的信息,如果用户请求查看,则会向用户显示这些信息。上述命令的结果是 生成两个名为 cert.pem
和key.pem
的文件,它放在Microblog根目录
的certs子目录
中。
要使网站由nginx提供服务,需要为其编写配置文件。在大多数nginx安装中,此文件需要位于/etc/nginx/sites-enabled
目录中。Nginx在这个位置安装了一个我不需要的测试站点,所以我将首先删除它:
ubuntu@VM-0-10-ubuntu:~/microblog/certs$ cd /etc/nginx/sites-enabled
ubuntu@VM-0-10-ubuntu:/etc/nginx/sites-enabled$ sudo rm /etc/nginx/sites-enabled/default
ubuntu@VM-0-10-ubuntu:/etc/nginx/sites-enabled$ ls -l
total 0
下方将看到Microblog的nginx配置文件,它位于/etc/nginx/sites-enabled/microblog中:
/etc/nginx/sites-enabled/microblog:Nginx配置
ubuntu@VM-0-10-ubuntu:/etc/nginx/sites-enabled$ sudo touch microblog #新建文件
ubuntu@VM-0-10-ubuntu:/etc/nginx/sites-enabled$ ls -l
total 4
-rw-r--r-- 1 root root 0 Sep 8 17:16 microblog
ubuntu@VM-0-10-ubuntu:/etc/nginx/sites-enabled$ sudo vi microblog #编辑文件
ubuntu@VM-0-10-ubuntu:/etc/nginx/sites-enabled$
文件内容如下:
server { # listen on port 80 (http) listen 80; server_name _; location / { # redirect any requests to the same URL but on https return 301 https://$host$request_uri; } } server { # listen on port 443 (https) listen 443 ssl; server_name _; # location of the self-signed SSL certificate ssl_certificate /home/ubuntu/microblog/certs/cert.pem; ssl_certificate_key /home/ubuntu/microblog/certs/key.pem; # write access and error logs to /var/log access_log /var/log/microblog_access.log; error_log /var/log/microblog_error.log; location / { # forward application requests to the gunicorn server proxy_pass http://localhost:8000; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } location /static { # handle static files directly, without forwarding to the application alias /home/ubuntu/microblog/app/static; expires 30d; } }
nginx配置 远远不是微不足道,上述添加了一些注释,以便知道每个部分的作用。如果想获得有关特定指令的信息,可参阅nginx官方文档。
添加这个文件后,需要告诉nginx重新加载配置以激活它:
ubuntu@VM-0-10-ubuntu:/etc/nginx/sites-enabled$ sudo service nginx reload
现在应用程序应该已成功部署。在Web浏览器中,键入服务器IP地址(公网IP。如果使用的是Vagrant VM,则输入192.168.33.10)并将连接到应用程序。由于使用的是自签名证书,因此将从Web浏览器收到警告,你可以忽略它。
在完成部署后,请按照自己项目的上述说明进行操作,强烈建议将自签名证书替换为 真实证书,以便浏览器不会警告你的用户的站点。为此,首先需要购买域名,并将其配置为指向服务器的IP地址。拥有域名后,可申请免费的Let’s Encrypt SSL证书。在作者博客有一篇关于如果通过HTTPS运行Flask应用程序的详细文章。
效果:
但是,当然,仅是下载新版本的代码并不会促使升级。当前正在运行的服务器进程将继续使用旧代码运行,旧代码已经读取并保存在内存中。要触发升级,必须停止当前服务器,并启动一个新服务器,以强制在此读取所有代码。
运行升级通常比重新启动服务器更复杂。可能需要运用数据库迁移或编译新的语言翻译,因此实际上,执行升级的过程涉及一系列命令:
(venv) $ git pull # download the new version
(venv) $ sudo supervisorctl stop microblog # stop the current server
(venv) $ flask db upgrade # upgrade the database
(venv) $ flask translate compile # upgrade the translations
(venv) $ sudo supervisorctl start microblog # start a new server
为了准备 树莓派,安装一个新的 Raspbian版本。使用2017年9月版的Raspbian Stretch Lite,现在可能有更新的版本,可查看官方下载页面获取最新版本。
Raspbian映像需要安装在SD卡上,然后将其插入Raspberry Pi,以便它可以随机启动。Raspberry Pi网站上提供了将Raspbian映像从Windows,Mac OS X和Linux复制到SD卡的说明。
第一次启动Raspberry Pi时,请在连接到键盘和显示器时执行此操作,以便可以进行设置。至少应启用SSH,以便可以从计算机登录以更舒适地执行部署任务。
像Ubuntu一样,Raspbian是Debian的衍生产品,因此上面针对Ubuntu Linux的说明大部分都适用于Raspberry Pi。但是,如果计划在家庭网络上运行小型应用程序而无需外部访问,则可以决定跳过某些步骤。例如,可能不需要防火墙或无密码登录。可能想在这么小的计算机上使用SQLite而不是MySQL。可以选择不使用nginx,只需让gunicorn服务器直接监听来自客户端的请求即可。可能只想要一个gunicorn worker。supervisor服务 在确保应用程序始终处于运行状态时非常有用,因此建议也在Raspberry Pi上使用它。
如需转载请注明出处。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。