由于是第一次在Linux
部署Python
应用,过程中遇到很多坑,也找了很多部署博客的分享。再一次体会到好文章带你上天堂,坏文章带你瞎逼忙的道理。索性就记录这次部署的全过程,供以后参考。
介绍
首先先介绍下各个技术的功能,以及他们组合的大致流程。部署的是一个web应用,从用户打开浏览器访问网页开始,到浏览到网页内容,这个过程就是各个技术实现功能的过程。
整体结构
- 用户浏览器(客户端)打开网页,向服务器发起请求;
- 请求传给Nginx服务器,Nginx将请求发给uWSGI;
- uWSGI服务器发来的请求翻译为应用程序理解的形式,发给应用;
- Flask应用接收请求并处理,将响应结果发给uWSGI;
- uWSGI与Nginx服务器通信,将结果传给他;
- Nginx服务器收到响应结果,将其传给客户端;
- 浏览器显示响应结果,并进行下一个请求。
安装Python环境
阿里云Ubuntu
服务器自带的Python2.7
和Python3.4
,所以尽管我的应用是Python3
程序,也不必重新装Python3
。
更新apt-get软件源
sudo apt-get update
获取应用源码
由于我的代码放在github仓库,直接通过git来安装。首先安装git:
sudo apt-get install git
安装完成后,在用户目录中新建project
目录mkdir project
,存放我们的应用程序。不知道是不是在用户目录可以输入指令pwd
查看。我们转到project
文件夹下,使用git
克隆项目源码:
git clone https://github.com/Blackyukun/YuBlog.git
转到项目目录cd YuBlog
安装pip和virtualenv
sudo apt-get install python-pip
sudo apt-get install python-virtualenv
创建虚拟环境
这里需要注意的是,如果直接virtualenv venv
命令,创建的将会是Python2
的虚拟环境。如果想要创建Python3
的环境,需要指定Python3
的目录:
virtualenv -p /usr/bin/python3 venv
如果成功,项目目录下会生成一个venv
目录,那里就是我们的python3
虚拟环境了。接下来激活虚拟环境:
source venv/bin/activate
退出虚拟环境命令是:deactivate
安装依赖包
如果项目实在虚拟环境中完成的,那么通常我们会使用pip freeze >requirements.txt
命令列出项目所有依赖。然后当我们安装这些依赖的时候只需要使用命令:
pip install -i http://pypi.douban.com/simple/ -r requirements.txt
如果全部安装完成,那么我们的程序依赖环境全都准备好了。
安装Mysql数据库
我的程序是使用Mysql
数据库做存储的,安装它也很简单,但是这里会有一个阿里云服务器的大坑。
sudo apt-get install mysql-server mysql-client
sudo apt-get install libmysqlclient-dev
安装过程中会需要你输入用户以及密码,暂且就使用root
和password
吧。
sudo netstat -tap | grep mysql
命令检查Mysql
是否安装成功,如果mysql
的socke
t处于listen
状态则表示安装成功。
登录mysql数据库命令:mysql -u root -p
这里的root
就是之前安装是设置的用户名,接着输入密码password
。在Linux
上,我们需要修改mysql
的默认编码为utf-8
,以便正确地处理中文。
这里需要编辑MySQL
的配置文件,把数据库默认的编码全部改为UTF-8
。MySQL
的配置文件默认存放在/etc/my.cnf
或者/etc/mysql/my.cnf
:
vim /etc/mysql/my.cnf
linux使用的是vim
编辑器,不了解vim
的可以自行了解。我们按i
进去插入模式,将下面的指令粘贴到对应位置:
[client]
default-character-set = utf8
[mysqld]
default-storage-engine = INNODB
character-set-server = utf8
collation-server = utf8_general_ci
把队应指令放在对应地方就好了。配置完成后,在vim
编辑器下,按ESC
进入普通模式,键入:wq
进行保存并退出。show variables like '%char%';
指令查看编码是否设置正确。如果看到utf8就表示正确。
接着重启数据库:
service mysql restart
重新登录mysql -u root -p
创建我们的数据库,使用:create database mydb;
创建名为mydb
的库名(注意后面封号)。
中文乱码
这里我们会遇到一个坑,就是在后面程序启动保存数据的时候会出现中文乱码,但是我们明明已经编辑过默认编码了呀。这里我发现是阿里云服务器本身没有安装中文包,我们需要进行安装。
安装中文语言包
sudo apt-get -y install language-pack-zh-hans
修改语言环境设置
echo "LC_ALL=zh_CN.utf8" >> /etc/profile
echo "export LC_ALL" >> /etc/profile
查看语言
source /etc/profile
locale
看到zh_CN.UTF-8
就成功了。接着需要重启服务器。
根本原因
虽然中文包安装成功了,但是这样就表示ok了吗?并没有,后来启动中网页中文显示依然乱码。我发现是保存数据库里的数据才会乱码,那么根本原因还是数据库编码问题。
我们需要在创建数据库时要同时定义他的默认编码:
删除数据库:mysql>delete database mydb;
创建数据库:mysql>create database mydb default character set utf8;
安装Nginx服务器
Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件IMAP/POP3
代理服务器。其特点是占有内存少,并发能力强。用于接收HTTP请求并返回响应。安装:
sudo apt-get install nginx
启动:sudo /etc/init.d/nginx start
看到OK表示成功。接着需要配置Nginx
。Nginx
的配置文件在/etc/nginx/sites-available
目录的default
文件中,将其删除rm default
。新的default
创建并打开vim default
,在里面写入:
server {
listen 80; # 80端口需要打开
server_name X.X.X.X; #阿里云公网ip
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:5000; # 指向uwsgi 所应用的内部地址
uwsgi_param UWSGI_PYHOME /home/root/project/YuBlog/venv; # 虚拟环境目录
uwsgi_param UWSGI_CHDIR /home/root/project/YuBlog; # 应用根目录
uwsgi_param UWSGI_SCRIPT manage:app; # 启动程序
uwsgi_read_timeout 100;
}
}
重启Nginx:sudo service nginx restart
看到OK表示成功。如果失败,可以输入指令sudo nginx -t
查找错误,进行处理。
安装uWSGI
uWSGI
虽然也可以起到Web服务器的作用,那么为什么有了uWSGI
还需要Nginx
呢。具体的优势大家自行了解。在Nginx+uWSGI
的结构中,它充当中间件的程序,是Web的通信协议。
安装:sudo pip install uwsgi
注意实在虚拟环境。安装成功后需要配置。我们在项目的根目录下也就是/home/root/project/YuBlog
下,创建配置文件config.ini
,添加内容:
[uwsgi]
master = true
home = venv
wsgi-file = manage.py
callable = app
socket = :5000
processes = 4
threads = 2
配置完成后,就可以启动uWSGI
了。但在这之前,我们先启动应用程序,并添加程序必须的环境变量。
添加linux
系统环境变量:export CONFIG=production
...
先创建迁移仓库:python manage.py db init
创建迁移脚本,migrate
子命令用来自动创建:python manage.py db migrate -m "v1.0"
更新数据库操作:python manage.py db upgrade
创建管理员信息:python manage.py addAdmin
ctrl+c
终止程序。
启动uWSGI
: uwsgi config.ini
会看到很多信息,只要没有报错,就表明启动成功。
部署成功
如果Nginx
和uWSGI
全部启动成功,就说明部署已经成功了。打开外部浏览器,访问公网ip
地址,就可以看到我们的程序已经跑起来了。
找到原因是我的文章URL写得是 ‘N/A’ 暂未找到解决办法
发布文章时,没有设置文章的url嘛
部署后发布文章,应该是缓存问题导致页面崩溃,能帮忙看下怎么回事么 pawned uWSGI worker 4 (pid: 23246, cores: 2) /home/yuxianz/project/YuBlog/venv/lib/python3.6/site-packages/pymysql/cursors.py:166: Warning: (1287, "'@@tx_isolation' is deprecated and will be removed in a future release. Please use '@@transaction_isolation' instead") result = self._query(query) Traceback (most recent call last): File "/home/yuxianz/project/YuBlog/venv/lib/python3.6/site-packages/flask/app.py", line 2309, in call return self.wsgi_app(environ, start_response) File "/home/yuxianz/project/YuBlog/venv/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app response = self.handle_exception(e) File "/home/yuxianz/project/YuBlog/venv/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception reraise(exc_type, exc_value, tb) File "/home/yuxianz/project/YuBlog/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise raise value File "/home/yuxianz/project/YuBlog/venv/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app response = self.full_dispatch_request() File "/home/yuxianz/project/YuBlog/venv/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request rv = self.handle_user_exception(e) File "/home/yuxianz/project/YuBlog/venv/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception reraise(exc_type, exc_value, tb) File "/home/yuxianz/project/YuBlog/venv/lib/python3.6/site-packages/flask/_compat.py", line 35, in reraise raise value File "/home/yuxianz/project/YuBlog/venv/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request rv = self.dispatch_request() File "/home/yuxianz/project/YuBlog/venv/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request return self.view_functionsrule.endpoint File "./app/main/views.py", line 93, in index post = get_post_cache(cache_key) File "./app/main/views.py", line 18, in get_post_cache return set_post_cache(items[1], items[2], items[3]) File "./app/main/views.py", line 28, in set_post_cache post = [i for i in posts if time in i.timestamp][0] IndexError: list index out of range [pid: 23245|app: 0|req: 1/1] 27.189.229.18 () {50 vars in 1305 bytes} [Wed Jul 15 13:18:47 2020] GET / => generated 0 bytes in 77 msecs (HTTP/1.1 500) 0 headers in 0 bytes (0 switches on core 0) ^CError in atexit._run_exitfuncs:
优秀
从虚拟机折腾到阿里云,一直都是这个错误,我检查了很多遍,不知道配置错在哪里,请博主指点,感谢!
SystemError: ../Objects/listobject.c:245: bad argument to internal function ModuleNotFoundError: No module named 'manage' unable to load app 0 (mountpoint='') (callable not found or import error) --- no python application found, check your startup logs for errors --- [pid: 22651|app: -1|req: -1/1] 42.231.179.104 () {48 vars in 886 bytes} [Sun Sep 15 02:57:52 2019] GET / => generated 21 bytes in 3 msecs (HTTP/1.1 500) 2 headers in 83 bytes (0 switches on core 0) SystemError: ../Objects/listobject.c:245: bad argument to internal function ModuleNotFoundError: No module named 'manage' unable to load app 0 (mountpoint='') (callable not found or import error) --- no python application found, check your startup logs for errors --- [pid: 22650|app: -1|req: -1/2] 42.231.179.104 () {46 vars in 800 bytes} [Sun Sep 15 02:57:52 2019] GET /favicon.ico => generated 21 bytes in 3 msecs (HTTP/1.1 500) 2 headers in 83 bytes (0 switches on core 0) ModuleNotFoundError: No module named 'manage' unable to load app 0 (mountpoint='') (callable not found or import error) --- no python application found, check your startup logs for errors --- [pid: 22651|app: -1|req: -1/3] 89.248.169.12 () {40 vars in 495 bytes} [Sun Sep 15 03:02:04 2019] GET / => generated 21 bytes in 0 msecs (HTTP/1.1 500) 2 headers in 83 bytes (0 switches on core 1)
config.ini 配置:
[uwsgi] master = true home = /home/project/YuBlog/venv chdir = /home/project/YuBlog wsgi-file = manage.py callable = app socket = 127.0.0.1:9002 processes = 4 threads = 2
nginx default 配置: server { listen 80; server_name 47...*; location / { include uwsgi_params; uwsgi_pass 127.0.0.1:9002; uwsgi_param UWSGI_PYHOME /home/project/YuBlog/venv; uwsgi_param UWSGI_CHDIR /home/project/YuBlog; uwsgi_param UWSGI_SCRIPT manage:app; uwsgi_read_timeout 100; } }
似乎是项目地址配置错了
确实是放错了目录,我把source目录的东西都拷到YuBlog根目录下面,运行,又出现了以下错误:
/home/project/YuBlog/env/lib/python3.7/site-packages/pymysql/cursors.py:170: Warning: (3719, "'utf8' is currently an alias for the character set UTF8MB3, but will be an alias for UTF8MB4 in a future release. Please consider using UTF8MB4 in order to be unambiguous.") result = self.query(query) Traceback (most recent call last): File "/home/project/YuBlog/env/lib/python3.7/site-packages/flask/app.py", line 2463, in call return self.wsgi_app(environ, start_response) File "/home/project/YuBlog/env/lib/python3.7/site-packages/flask/app.py", line 2449, in wsgi_app response = self.handle_exception(e) File "/home/project/YuBlog/env/lib/python3.7/site-packages/flask/app.py", line 1866, in handle_exception reraise(exc_type, exc_value, tb) File "/home/project/YuBlog/env/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise raise value File "/home/project/YuBlog/env/lib/python3.7/site-packages/flask/app.py", line 2446, in wsgi_app response = self.full_dispatch_request() File "/home/project/YuBlog/env/lib/python3.7/site-packages/flask/app.py", line 1951, in full_dispatch_request rv = self.handle_user_exception(e) File "/home/project/YuBlog/env/lib/python3.7/site-packages/flask/app.py", line 1820, in handle_user_exception reraise(exc_type, exc_value, tb) File "/home/project/YuBlog/env/lib/python3.7/site-packages/flask/_compat.py", line 39, in reraise raise value File "/home/project/YuBlog/env/lib/python3.7/site-packages/flask/app.py", line 1949, in full_dispatch_request rv = self.dispatch_request() File "/home/project/YuBlog/env/lib/python3.7/site-packages/flask/app.py", line 1935, in dispatch_request return self.view_functionsrule.endpoint File "./app/main/views.py", line 92, in index cache_key = ''.join(map(str, ['post', post.year, post.month, post.url_name])) File "./app/models.py", line 110, in year return int([i for i in self.timestamp.split('-')][0]) ValueError: invalid literal for int() with base 10: '连接年月日' [pid: 31477|app: 0|req: 1/1] 115.52.251.160 () {50 vars in 1040 bytes} [Sat Sep 21 12:43:18 2019] GET / => generated 0 bytes in 86 msecs (HTTP/1.1 500) 0 headers in 0 bytes (0 switches on core 0)
请问,我部署完uwsgi,放项目时一直提示我warning:you are running uwsgi as rooting ..等等一大段其他的话,这是什么原因,感觉有哪里配置有问题
意思是你使用了root运行了uwsgu,带来了一些安全隐患,解决方式是配置用户 组,在给uwsgi增加uid个gid的配置
以上是 启动 uwsgi 之后提示的信息,搞了两天了,求大佬帮忙。万分感谢!
你需要看下app目录下是否有
__init__.py
文件,没有就需要新建。而且manage.py
文件所在目录下不应该有__init__.py
文件。jinja2.exceptions.UndefinedError: 'admin' is undefined [pid: 1925|app: 0|req: 1/1] 101.45.58.236 () {50 vars in 1266 bytes} [Mon Nov 19 14:36:07 2018] GET / => generated 0 bytes in 123 msecs (HTTP/1.1 500) 0 headers in 0 bytes (0 switches on core 0)
这个报错是哪里出错了?
在启动程序前,要先在
config.py
中配置管理员信息,在创建管理员:python manage.py addAdmin
卡在迁移仓库这 (
) (venv) # python manage.py db init /root/project/YuBlog/venv/lib/python3.5/site-packages/flask/exthook.py:71: ExtDeprecationWarning: Importing flask.ext.cache is deprecated, use flask_cache instead. .format(x=modname), ExtDeprecationWarning Traceback (most recent call last): File "manage.py", line 51, in <module> manager.run() File "/root/project/YuBlog/venv/lib/python3.5/site-packages/flask_script/__init__.py", line 412, in run result = self.handle(sys.argv[0], sys.argv[1:]) File "/root/project/YuBlog/venv/lib/python3.5/site-packages/flask_script/__init__.py", line 383, in handle res = handle(*args, **config) File "/root/project/YuBlog/venv/lib/python3.5/site-packages/flask_script/commands.py", line 216, in __call__ return self.run(*args, **kwargs) File "/root/project/YuBlog/venv/lib/python3.5/site-packages/flask_migrate/__init__.py", line 106, in init command.init(config, directory, 'flask') File "/root/project/YuBlog/venv/lib/python3.5/site-packages/alembic/command.py", line 42, in init raise util.CommandError("Directory %s already exists" % directory) alembic.util.exc.CommandError: Directory migrations already exists (
)卡在这里 (venv) ➜ YuBlog git:(master) ✗ python manage.py db init /root/project/YuBlog/venv/lib/python3.5/site-packages/flask/exthook.py:71: ExtDeprecationWarning: Importing flask.ext.cache is deprecated, use flask_cache instead. .format(x=modname), ExtDeprecationWarning Creating directory /root/project/YuBlog/migrations ... done Creating directory /root/project/YuBlog/migrations/versions ... done Generating /root/project/YuBlog/migrations/script.py.mako ... done Generating /root/project/YuBlog/migrations/alembic.ini ... done Generating /root/project/YuBlog/migrations/env.py ... done Generating /root/project/YuBlog/migrations/README ... done Please edit configuration/connection/logging settings in '/root/project/YuBlog/migrations/alembic.ini' before proceeding.
博主,我按照您的方式部署好 flask 程序之后,一段时间内是没有问题的,但是可能过了几个小时或几天后,就会出现一个蓝图下的路由都无法访问的问题,这可能是哪些原因造成的?
你本地测试有问题吗,蓝本有注册到应用程序中去吗
本地是没有任何问题的,蓝本注册了
可以给我看看你的相关代码吗