阿里云部署踩坑记录¶
相关文档:阿里云部署前后端项目全过程记录
一、分离 setting.py¶
在线上环境中,为了安全起见,我们将 debug 改为了 False,但在开发环境中又需要改为 True。
同时,django 的 SECRET_KEY 是很私密的配置,django 的很多安全机制都依赖它,如果不慎泄露,网站将面临巨大安全风险。
最好是将这个值写入环境变量,从环境变量中取值。
1.1 settings 目录结构¶
为了解决以上问题,我们可以拆分 settings.py 文件,不同环境对应不同的 settings 文件。
django 在启动时会从环境变量中读取 DJANGO_SETTINGS_MODULE 的值,以这个值指定的文件作为应用的最终配置。
Security\ (项目应用名)
settings\
__init__.py (将文件夹识别为 python 包)
common.py (用于存放通用配置)
local.py (存放开发环境的配置)
production.py (存放线上环境的配置)
settings.py (配置好了直接删了)
1.2 settings 文件详细配置¶
1.2.1 配置 common.py
¶
将原先的 settings.py 文件中的内容全部复制到 common.py 里。并将 SECRET_KEY、DEBUG、ALLOWED_HOSTS 这些配置删除。
1.2.2 配置 local.py
¶
from .common import *
SECRET_KEY = '本地开发环境的秘钥'
DEBUG = True
ALLOWED_HOSTS = ['*']
1.2.3 配置 production.py
¶
from .common import *
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']
DEBUG = False
ALLOWED_HOSTS = ['127.0.0.1','服务器 IP 地址','域名']
注:这里的 IP 地址一定要填对!
1.3 项目相关配置调整¶
1.3.1 修改 manage.py 配置¶
Security.settings.local
- 开发环境中使用 manage.py 启动 Django 项目时,使用 local.py 配置。
def main():
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Security.settings.local')
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
1.3.2 修改 wsgi.py 配置¶
Security.settings.production
- 生产环境中使用 gunicorn 启动 Django 项目时,使用 production.py 配置。
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'Security.settings.production')
application = get_wsgi_application()
1.3.3 修改 BASE_DIR
配置项¶
此时,在 common.py
中存在 BASE_DIR
指向项目根目录,其获取方式为根据所在的配置文件向上回溯,找到项目根目录。
之前的目录结构为 Django/Security/settings.py,向上 2 层就能到达项目根目录。而现在目录结构变为 Django/Security/settings/common.py,需向上 3 层才能到达项目根目录。
因此需将 BASE_DIR 进行修改,修改前后内容如下:
修改前
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
修改后
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
即再在原有的外面再包一层 os.path.dirname,再向上回退一层,到达项目根目录。
1.4 设置 Supervisor 环境变量¶
由于在之前我们在线上环境中配置 secret_key 从环境变量获取, 因此需要再次修改 supervisor 的配置,将环境变量导入。
打开 supervisor 的配置文件
vim ~/etc/supervisor/conf.d/gunicorn.ini
添加环境变量的配置语句
environment=DJANGO_SECRET_KEY=项目的秘钥
保存并更新配置
supervisorctl -c ~/etc/supervisord.conf update
二、Ubuntu 的用户权限问题¶
2.1 sudo 命令¶
在 Ubuntu 中,不提倡直接使用最高权限的 root 用户进行实际操作。通常都是通过普通用户 + sudo 命令来实现对应的命令。
2.2 文件夹权限¶
2.2.1 文件所属¶
在 Ubuntu 中,拥有最高权限的 root 用户可以对其他用户的文件进行任何操作。而我们在连接远程服务器时,如果直接登录 root 并修改相关文件后,该文件的所属会发生改变,会变成 root 所有。
2.2.2 权限冲突¶
由于我们之前在部署项目时,项目的启动均设置为 cveo 用户启动,所以此时会出现权限冲突。此时我们发现再次访问页面时,出现了以下错误。
接下来,我们需要先查出 supervisord 和 gunicorn的进程序号,然后根据进程号逐个杀死,最后再次查看是否完全关闭。
查看进程序号
ps gx|grep 进程名称
杀死进程
kill -9 对应进程号
注:除恶务尽,一定要查看相关进程是否全部杀死!
2.2.3 查看日志¶
在之前的部署中,我们配置了 supervisor 的日志存放位置,也可以去查看错误日志发现问题。
转到日志目录
cd ~/etc/supervisor/var/log/
查看错误日志
cat gunicorn-stderr.err
注:输入部分字母后按 Tab 键可以自动补全。
2.2.4 修改文件夹所有者¶
转到目标上方目录 (必须)
cd ~/dat
修改 backend 目录下所有文件的所有者
sudo chown -R cveo:cveo backend
2.2.5 重启启动项目¶
在杀死进程后的首次启动 supervisor,可能会出现错误,按如下步骤操作即可。
启动 supervisord
supervisord -c ~/etc/supervisor/supervisord.conf
重新连接
unlink /home/cveo/etc/supervisor/var/supervisor.sock
杀死当前的 supervisord 进程
ps gx|grep supervisord
kill -9 进程号
重新启动 supervisord 进程
supervisord -c ~/etc/supervisor/supervisord.conf