申请到了公司服务器的资源,就不用跑在windows下边,用Django来强制提供静态文件服务,换成Linux正式部署,效率就高很多了,整体网站的速度也快多了。
记录一下折腾的过程以便以后用。
01 安装PgSQL
先安装Postgresql :
apt install postgresql之后设置默认的pgsql密码:
sudo -u postgres psql进入psql的命令行,然后输入:
ALTER USER postgres WITH password '123456';别忘记最后的分号,之后显示ALTER ROLE就可以了。使用\q 退出。
然后修改PgSQL的远程连接,目录在/etc/postgresql/16/main 下。
修改postgresql.conf中的
listen_address = '*' 修改pg_hba.conf,增加一行
host all all 0.0.0.0/0 md5重新启动服务:systemctl restart postgresql,然后使用pgAdmin能远程连接上数据库就成功了。之后在数据库中创建应用所需的用户和对应的数据库。
02 安装Python虚拟环境和相关包
自带的Python是3.12.3,也足够用了。
到/home/sysadmin/下边,执行
apt install python3.12-venv安装完成之后,启动一个虚拟环境目录:
python3 -m venv FMS_VENV之后上传requirements.txt,内容如下:
asgiref==3.11.0
Django==6.0
et_xmlfile==2.0.0
gunicorn==23.0.0
openpyxl==3.1.5
packaging==25.0
psycopg2-binary==2.9.11
python-dateutil==2.9.0.post0
six==1.17.0
sqlparse==0.5.4
tzdata==2025.2先激活虚拟环境,然后安装:
source /home/sysadmin/FMS_VENV/bin/activate
pip install -r requirements.txt这样Python环境就配好了。
03 上传Django项目文件
把项目的settings.py中的Debug改成False,urls.py中删除windows下强制提供静态文件的代码,然后就可以上传到服务器上了。我放在/home/sysadmin/FMS目录下。还要把ALLOWED_HOSTS设置为服务器的IP地址和本地回环地址。
之后更新的时候注意备份一下这两个修改后的文件即可。
然后就可以执行迁移了,这里迁移的时候注意,迁移版本和开发版本一致,这样将来上传到服务器的时候可以迅速的同步开发数据库和生产数据库的表状态。顺便再创建一个管理员账号。
04 配置Gunicorn服务
创建/etc/systemd/system/gunicorn.service,内容如下:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=root
Group=www-data
WorkingDirectory=/home/sysadmin/FMS
ExecStart=/home/sysadmin/FMS_VENV/bin/gunicorn --access-logfile - --workers 3 --bind 127.0.0.1:8000 FMS2026.wsgi
[Install]
WantedBy=multi-user.target用户要配置成root以获取足够的权限。WorkingDirectory就是项目目录,下边的启动是虚拟环境下的gunicorn包所在位置,绑定端口可以自己设置,在nginx中要进行相同的配置。最后的FMS2026.wsgi是指的项目目录下的FMS2026目录下的wsgs.py 入口文件。
之后激活为系统服务,并启动:
sudo systemctl start gunicorn
sudo systemctl enable gunicorn正常情况下系统就启动了,由于我这个没有图形界面,就没法通过8000端口访问没有静态文件的页面先测试一下了。但只要服务正常启动,就没问题。
05 配置nginx
先安装:
apt install nginx之后到/etc/nginx/sites-avaiable中修改default文件,这个文件是默认的站点,并通过软链接到/sites-enable中的default来进行激活。将其中的内容全部删除,换成如下内容:
server {
listen 80;
server_name fms.highly.cc;
location /static {
alias /home/sysadmin/FMS/static/; # 静态文件路径
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}由于直接根据IP提供服务,所以域名其实没有什么用。
/static路径的引用改写到项目的静态文件地址,也就是Django收集静态文件的地址,这样静态文件就通过nginx来提供服务了。
还有一点很关键,编辑nginx.conf,将其中的第一行改成:
user root;否则访问静态文件会报403错误。之后测试一下配置文件,然后重启服务或者直接加载:
nginx -t
nginx -s reload之后再直接访问对应的IP地址,就能看到自己编写的Web服务正常运行啦。
06 解决上传大文件错误
测试的时候发现上传大文件的时候总是出错。然后发现错误日志后端无记录,Nginx也无记录,配置了Nginx的请求体大小之后依然出现错误。之后想到整个数据流是Nginx-Gunicorn-Django,于是逐步排查。先用纯Django启动,发现没问题,Gunicorn启动发现问题,搜了之后,应该是要设置worker的存活时间,而且之前没有配置日志,于是给Gunicorn也配置上日志。
为了简便,把Nginx的default软链接去掉,直接写在nginx.conf里。
最后完整的几个配置文件放出来,也给自己留个可以查的地方。
nginx.conf
nginx里主要配置了最大请求体为1G,所有和后端代理的过期时间以及请求的过期时间都设置成了20分钟,肯定足够了,缓冲区20M并配置了超过缓冲区时候的路径。
user root;
worker_processes auto;
pid /run/nginx.pid;
error_log /var/log/nginx/error.log;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
##
# Link Time
#
client_max_body_size 1024m;
client_body_buffer_size 20m;
client_body_temp_path /home/sysadmin/nginx;
client_header_timeout 20m;
client_body_timeout 20m;
proxy_connect_timeout 20m;
proxy_read_timeout 20m;
proxy_send_timeout 20m;
##
# Basic Settings
##
sendfile on;
tcp_nopush on;
types_hash_max_size 2048;
# server_tokens off;
# server_names_hash_bucket_size 64;
# server_name_in_redirect off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
##
# SSL Settings
##
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
##
# Logging Settings
##
access_log /var/log/nginx/access.log;
##
# Gzip Settings
##
gzip on;
# gzip_vary on;
# gzip_proxied any;
# gzip_comp_level 6;
# gzip_buffers 16 8k;
# gzip_http_version 1.1;
# gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
##
# Virtual Host Configs
##
server {
listen 80;
server_name fms.conyli.cc;
location /static {
alias /home/sysadmin/FMS/static; # 静态文件路径
}
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}settings.py
这里的配置主要是重新修改了日志的位置,把日志和Gunicorn的日志都放到默认用户文件夹下边,方便查看。
DEBUG = False
ALLOWED_HOSTS = ['172.18.99.49']
if not DEBUG:
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"filters": {
"require_debug_false": {
"()": "django.utils.log.RequireDebugFalse",
},
"require_debug_true": {
"()": "django.utils.log.RequireDebugTrue",
},
},
"formatters": {
"django.server": {
"()": "django.utils.log.ServerFormatter",
"format": "[{server_time}] {message}",
"style": "{",
}
},
"handlers": {
'file': {
'level': 'WARNING',
'class': 'logging.FileHandler',
'filename': '/home/sysadmin/log/django/FMS_LOG.log',
},
},
"loggers": {
"django": {
"handlers": ["file"],
"level": "WARNING",
},
},
}Gunicorn.service
Gunicorn 的设置彻底修改了一下:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=root
Group=root
WorkingDirectory=/home/sysadmin/FMS
ExecStart=/home/sysadmin/FMS_VENV/bin/gunicorn --access-logfile /home/sysadmin/log/gunicorn/access.log --error-logfile /home/sysadmin/log/gunicorn/error.log --log-level warning --workers=3 --timeout 1200 --keep-alive 500 --limit-request-line 8190 --bind 127.0.0.1:8000 FMS2026.wsgi
[Install]
WantedBy=multi-user.target
这其中设置了access.log和error.log的位置,关键是设置了--timeout 1200,20分钟的过期时间,这样就能保证重型计算也不会过期。
Gunicorn的很多设置将来慢慢研究了。
上边全部配置好之后,终于跑通了,测试了一个15兆的大文件也没有什么问题,对于我这种小型应用来说,肯定足够了。