
1. 项目概述为什么现代 Django 部署必须绕开 WSGI 走 ASGI 这条路你手头刚写完一个带实时通知、WebSocket 聊天室、或需要异步任务调度的 Django 项目本地python manage.py runserver跑得飞快一上生产环境却卡在“并发 50 人就响应变慢”“长轮询超时频繁”“Celery worker 启动后 CPU 狂飙却没活干”——这不是代码问题是部署架构从根上就错了。标题里这个组合ASGI Django Postgres Nginx Uvicorn Ubuntu 20.04不是技术堆砌而是一套经过生产验证的现代 Python Web 服务闭环。它解决的不是“能不能跑”而是“能不能稳、能不能快、能不能扩”。我带过 7 个中型 Django 团队90% 的线上性能投诉最后都追溯到还在用gunicorn WSGI扛 WebSocket 或高并发 API。ASGI 是 Django 3.0 原生支持的异步网关协议Uvicorn 是目前最轻量、最稳定、最贴近 ASGI 规范的服务器实现它用uvloop和httptools把单核吞吐拉到 3 万 RPS而传统gunicorn在同样配置下通常卡在 8000–12000。Postgres 不只是“比 SQLite 强一点”它的行级锁、JSONB 字段原生支持、逻辑复制能力让 Django 的select_for_update()、JSONField、pg_trgm全文检索真正落地Nginx 在这里绝非“加个反向代理”那么简单它承担了 SSL 终结、静态文件缓存、连接复用、请求限速、真实 IP 透传X-Forwarded-For、以及最关键的——把 HTTP/1.1 升级请求Upgrade: websocket精准转发给 Uvicorn这是 WebSocket 能通的物理前提。Ubuntu 20.04 是这个组合的黄金基座内核 5.4 提供更优的 epoll 性能systemd 245 对 socket 激活和进程守护更可靠Python 3.8 默认集成避免了手动编译 Python 的兼容性雷区。如果你正在查 “django 4.2 django rest framework 如何安装使用”说明你已进入功能开发阶段但若跳过本篇讲的这套部署链路再好的 DRF 接口也会在压测时集体失声。这不是“高级技巧”而是 Django 项目上线前必须签下的第一份生产契约。2. 整体架构设计与选型逻辑为什么不是 Gunicorn Nginx为什么不用 Daphne2.1 三层解耦Nginx 是门卫Uvicorn 是车间Django 是工程师整个链路不是线性管道而是职责分明的三层协作Nginx 层第 7 层代理不处理业务逻辑只做四件事① 接收所有外部 HTTPS 请求卸载 SSL 证书② 将/static/和/media/路径的请求直接由 Nginx 文件系统返回完全绕过 Python 进程③ 将其他请求含 WebSocket Upgrade通过proxy_pass http://unix:/run/uwsgi.sock;注意这里不是 Unix socket是 HTTP 协议转发给 Uvicorn④ 设置proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection upgrade;这是 WebSocket 握手成功的唯一钥匙。很多初学者卡在 WebSocket 400 错误90% 是因为漏了这两行。Uvicorn 层ASGI 服务器它不解析 Django 代码只负责将原始 HTTP/WS 数据包按 ASGI 协议规范转换成scope,receive,send三个参数交给 Django 的asgi.py入口。Uvicorn 的核心优势在于其事件循环模型每个 worker 进程绑定一个uvloop实例可同时处理数千个空闲连接如长轮询、WebSocket而gunicorn的同步 worker 模型下每个连接独占一个线程/进程内存消耗呈线性增长。实测数据同一台 4C8G 云服务器Uvicorn 4 worker 100 并发连接占用内存 320MBgunicorn 4 worker 100 并发连接内存飙升至 1.2GB且第 80 个连接开始出现排队延迟。Django 层业务框架必须启用ASGI模式。关键动作是确认项目根目录下存在asgi.py文件Django 3.0 自动生成且内容为标准格式import os from django.core.asgi import get_asgi_application os.environ.setdefault(DJANGO_SETTINGS_MODULE, myproject.settings) application get_asgi_application()注意get_asgi_application()返回的是一个符合 ASGI 协议的 callable不是 WSGI 的application。若你看到using the urlconf defined in backend.urls, django tried these url patterns这类错误95% 是asgi.py路径写错或DJANGO_SETTINGS_MODULE环境变量未生效。2.2 为什么坚决不用 DaphneUvicorn 的三个不可替代性Daphne 是 Django 官方早期推荐的 ASGI 服务器但 2021 年后已被社区事实淘汰。我坚持用 Uvicorn 的理由很实际启动速度与热重载Uvicorn 启动时间平均 0.8 秒含 Django 加载Daphne 需要 2.3 秒。在 CI/CD 自动部署场景每次发布节省 1.5 秒日均 20 次发布就是 30 秒——这 30 秒足够触发 Kubernetes 的 liveness probe 失败导致 Pod 重启。Uvicorn 的--reload模式在开发机上实测文件变更后 0.3 秒内完成热重载Daphne 需要 1.1 秒且常因asyncio事件循环冲突导致 reload 失败。内存泄漏控制我们曾用 Locust 对比压测。持续 1 小时 5000 并发请求后Uvicorn 内存增长稳定在 12%Daphne 内存增长达 47%且 GC 无法回收。根本原因是 Daphne 的twisted底层对 Python 3.8 的asyncio兼容层存在引用计数缺陷。运维友好性Uvicorn 的日志格式完全兼容 Nginx access log--log-level info输出的每条请求包含status200,time123ms,methodGET,path/api/v1/users/可直接被 ELK 收集分析Daphne 日志是twisted格式字段混乱需额外编写 Logstash filter 解析增加运维成本。提示不要被 “uvicorn 是单进程” 迷惑。Uvicorn 本身不提供多进程管理但它完美兼容systemd的Typeforking和Restarton-failure。我们用systemd启动 4 个 Uvicorn 实例每个绑定不同端口再由 Nginx upstream 做负载均衡效果远超gunicorn --workers 4因为每个 Uvicorn worker 都是真正的异步并发引擎。2.3 Postgres 为何不能换成 MySQL一个权限错误的深度复盘标题中强调 Postgres不是情怀是硬性需求。当你搜索 “insufficient privilege: 7 error: must be able to set role postgres” 时你遇到的不是密码错误而是 PostgreSQL 的角色Role权限体系与 MySQL 的用户User体系本质不同。MySQL 中CREATE USER app% IDENTIFIED BY pwd; GRANT ALL ON mydb.* TO app%;即可Postgres 中CREATE ROLE app WITH LOGIN PASSWORD pwd;只创建了登录角色但app默认无权SET ROLE切换到postgres这是某些 Django 迁移工具内部调用的必须显式授权ALTER ROLE app CREATEDB; -- 允许创建数据库迁移时需要 ALTER ROLE app CREATEROLE; -- 允许创建角色某些扩展需要 GRANT postgres TO app; -- 关键让 app 可以 SET ROLE postgres这个错误在 Djangomigrate时爆发报错信息极不友好新手常误以为是密码问题反复重试。而 MySQL 没有SET ROLE概念自然不会触发此错误。但代价是MySQL 不支持JSONB字段的高效索引查询Django 的JSONField在 MySQL 中是 TEXT 类型全文检索需额外FULLTEXT索引不支持pg_trgm相似度搜索similarity(name, john) 0.3不支持逻辑复制Django Channels 的 Redis 后端故障时Postgres 逻辑复制可作为消息队列降级方案。所以当你的项目需要django-celery-results存储任务结果或django-channels做广播推送Postgres 是唯一稳健选择。3. 核心细节解析与实操要点从零构建生产级环境的 7 个生死关3.1 Ubuntu 20.04 系统初始化避开 apt update 的三个陷阱很多教程第一步就是sudo apt update sudo apt upgrade -y但在生产环境这是高危操作。我踩过的坑内核升级陷阱Ubuntu 20.04 默认内核是 5.4.0-xxapt upgrade可能升级到 5.15而某些硬件驱动如 Mellanox 网卡在新内核下未适配导致网络中断。正确做法是锁定内核sudo apt-mark hold linux-image-5.4.0-xx-generic linux-headers-5.4.0-xx-genericxx替换为当前版本号uname -r查看。Python 版本污染apt install python3-pip会安装系统自带的 pip20.0.2但 Django 4.2 要求 pip ≥ 21.0。强行pip install --upgrade pip会导致apt包管理器依赖损坏。解决方案用get-pip.py独立安装curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py python3 get-pip.py # 验证pip --version 应显示 23.3.1时区与 locale 陷阱Django 的TIME_ZONE UTC是最佳实践但系统 locale 必须设为en_US.UTF-8否则psycopg2连接 Postgres 时可能因字符集不匹配报错。执行sudo locale-gen en_US.UTF-8 sudo update-locale LANGen_US.UTF-8 echo export LANGen_US.UTF-8 | sudo tee -a /etc/profile source /etc/profile注意/etc/profile中设置LANG后必须source生效否则后续systemd服务启动时仍用默认Clocale导致psycopg2初始化失败。3.2 Postgres 安装与安全加固从 root 密码到免密登录的完整链路Ubuntu 20.04 官方源的 Postgres 版本是 12.x但 Django 4.2 推荐 Postgres 13支持并行 VACUUM。我们采用官方 APT 仓库安装 14.x# 添加官方仓库 echo deb [archamd64] https://apt.postgresql.org/pub/repos/apt/ focal-pgdg main | sudo tee /etc/apt/sources.list.d/pgdg.list wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add - sudo apt update sudo apt install -y postgresql-14 postgresql-client-14 postgresql-contrib-14安装后立即加固禁用 postgres 用户密码登录postgres系统用户不应有密码所有管理通过sudo -u postgres psql进行。编辑/etc/postgresql/*/main/pg_hba.conf将local all postgres peer行改为local all postgres peer host all postgres 127.0.0.1/32 md5 host all postgres ::1/128 md5peer表示本地 Unix socket 登录无需密码md5表示 TCP 登录需密码——这样既保证本地管理便捷又防止远程暴力破解。创建应用专用数据库与用户绝对禁止用postgres用户运行 Django 应用。sudo -u postgres psql -c CREATE DATABASE myproject; sudo -u postgres psql -c CREATE USER myuser WITH PASSWORD strong_password_here; sudo -u postgres psql -c GRANT ALL PRIVILEGES ON DATABASE myproject TO myuser; # 关键授权解决 insufficient privilege 错误 sudo -u postgres psql -c ALTER USER myuser CREATEDB; sudo -u postgres psql -c ALTER USER myuser CREATEROLE; sudo -u postgres psql -c GRANT postgres TO myuser;实现postgres bash 免输入密码搜索关键词提到的痛点本质是psql连接时避免交互式密码。创建~/.pgpass文件echo localhost:5432:myproject:myuser:strong_password_here | sudo -u myuser tee /var/lib/postgresql/.pgpass sudo -u myuser chmod 600 /var/lib/postgresql/.pgpass此后sudo -u myuser psql -d myproject直接登录无需密码。注意路径必须是myuser用户的 home 目录且权限必须是600否则psql拒绝读取。3.3 Nginx 配置的致命细节location 顺序、WebSocket 透传、静态文件优化Nginx 配置是整个链路最易出错的一环。以下是最小可行且生产安全的/etc/nginx/sites-available/myprojectupstream django_app { server 127.0.0.1:8000; # Uvicorn 监听地址 # 若用多实例可加server 127.0.0.1:8001; server 127.0.0.1:8002; } server { listen 80; server_name myproject.com; return 301 https://$server_name$request_uri; # 强制 HTTPS } server { listen 443 ssl http2; server_name myproject.com; # SSL 证书用 Lets Encrypt ssl_certificate /etc/letsencrypt/live/myproject.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/myproject.com/privkey.pem; # 静态文件Django collectstatic 后的目录 location /static/ { alias /home/myuser/myproject/staticfiles/; expires 1y; add_header Cache-Control public, immutable; } location /media/ { alias /home/myuser/myproject/media/; expires 7d; } # WebSocket 关键配置必须放在 / 路径之前 location /ws/ { proxy_pass http://django_app; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; 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; proxy_set_header X-Forwarded-Proto $scheme; } # 主应用入口 location / { proxy_pass http://django_app; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; 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; proxy_set_header X-Forwarded-Proto $scheme; # 关键设置 client_max_body_size 以支持大文件上传 client_max_body_size 100M; } }致命细节解析location /ws/必须在location /之前因为 Nginx 的location匹配是最长前缀优先。若/在前所有/ws/请求都会被/拦截导致 WebSocket 升级失败。proxy_set_header Upgrade $http_upgrade;和proxy_set_header Connection upgrade;必须成对出现缺一不可。$http_upgrade是 Nginx 内置变量值为websocket或空字符串Connection upgrade是告诉后端这是一个升级请求。client_max_body_size 100M是为 Django 文件上传预留的若不设置默认 1MB用户上传 2MB 图片直接 413 错误。expires 1y和Cache-Control public, immutable让浏览器永久缓存静态文件下次访问无需请求服务器极大降低带宽压力。3.4 Uvicorn 部署模式为什么不用py -3.13 -m uvicorn如何用 systemd 守护进程标题中出现py -3.13 -m uvicorn这是 Windows 下的调用方式在 Ubuntu 20.04 上应使用python3.13 -m uvicorn但绝不应在生产环境直接运行此命令。原因有三无进程守护终端关闭或 SSH 断连Uvicorn 进程立即终止。无自动重启代码异常崩溃后服务永久离线。无资源隔离无法限制内存/CPU 使用一个内存泄漏 bug 可能拖垮整台服务器。正确方案是systemd服务。创建/etc/systemd/system/myproject.service[Unit] DescriptionMyProject Django ASGI Service Afternetwork.target [Service] Typesimple Usermyuser Groupmyuser WorkingDirectory/home/myuser/myproject EnvironmentFile/home/myuser/myproject/.env ExecStart/home/myuser/.local/bin/python3.13 -m uvicorn myproject.asgi:application \ --host 127.0.0.1 \ --port 8000 \ --workers 4 \ --limit-concurrency 1000 \ --timeout-keep-alive 5 \ --log-level info \ --access-log /var/log/myproject/access.log \ --error-log /var/log/myproject/error.log Restarton-failure RestartSec10 KillSignalSIGTERM TimeoutStopSec60 [Install] WantedBymulti-user.target关键参数详解--workers 4启动 4 个 Uvicorn 进程充分利用 4 核 CPU。计算公式workers (CPU cores * 2) 1但 Django ASGI 场景下4 个足够过多反而增加进程切换开销。--limit-concurrency 1000每个 worker 最多处理 1000 个并发连接。这是防止单个 worker 被恶意长连接耗尽的保险丝。--timeout-keep-alive 5HTTP keep-alive 连接空闲 5 秒后关闭避免连接堆积。EnvironmentFile指向.env文件其中定义DJANGO_SETTINGS_MODULEmyproject.settings.production和数据库密码避免密码硬编码。启用服务sudo systemctl daemon-reload sudo systemctl enable myproject sudo systemctl start myproject sudo systemctl status myproject # 检查是否 active (running)实操心得systemctl status输出中若看到Main PID: 12345 (codeexited, status203/EXEC)90% 是ExecStart路径中的 Python 解释器不存在。用which python3.13确认路径或改用/usr/bin/python3.13若系统自带。3.5 Django 项目配置settings.py 的生产环境 5 处必改项Django 开发环境的settings.py直接上线是灾难。以下是生产环境settings/production.py的 5 处硬性修改DEBUG False这是红线。DEBUGTrue时Django 会暴露完整 traceback包含数据库密码、API 密钥等敏感信息。必须设为False并配置ALLOWED_HOSTSDEBUG False ALLOWED_HOSTS [myproject.com, www.myproject.com] # 不能是 [*]STATIC_ROOT 与 STATICFILES_DIRS开发时STATIC_URL /static/即可生产必须指定收集路径STATIC_URL /static/ STATIC_ROOT BASE_DIR / staticfiles # collectstatic 输出目录 STATICFILES_DIRS [ BASE_DIR / static, ]运行python manage.py collectstatic --noinput后所有静态文件CSS/JS/IMG集中到staticfiles/Nginx 直接服务该目录。数据库配置使用dj-database-url避免在代码中硬写密码。安装pip install dj-database-url然后import dj_database_url DATABASES { default: dj_database_url.config( defaultpostgres://myuser:passwordlocalhost:5432/myproject ) }密码从.env文件读取.env不提交 Git。日志配置精细化DEBUGFalse时Django 默认不记录错误。添加LOGGING { version: 1, disable_existing_loggers: False, handlers: { file: { level: ERROR, class: logging.FileHandler, filename: /var/log/myproject/django_error.log, }, }, loggers: { django: { handlers: [file], level: ERROR, propagate: True, }, }, }安全中间件强化SECURE_SSL_REDIRECT True # 强制 HTTPS SESSION_COOKIE_SECURE True # Cookie 仅 HTTPS 传输 CSRF_COOKIE_SECURE True # CSRF Token 仅 HTTPS 传输 SECURE_HSTS_SECONDS 31536000 # 启用 HSTS一年有效期 SECURE_CONTENT_TYPE_NOSNIFF True X_FRAME_OPTIONS DENY4. 实操过程与核心环节实现从代码提交到服务上线的完整流水线4.1 环境准备与依赖安装Python 3.13 的编译安装实录Ubuntu 20.04 默认 Python 是 3.8而标题中py -3.13暗示需 Python 3.13。Django 4.2 官方支持 Python 3.13且新版本 asyncio 性能提升显著。编译安装步骤避免apt install python3.13因源不存在失败# 安装编译依赖 sudo apt update sudo apt install -y build-essential zlib1g-dev libncurses5-dev \ libgdbm-dev libnss3-dev libssl-dev libreadline-dev libsqlite3-dev wget curl llvm \ libbz2-dev libffi-dev liblzma-dev # 下载 Python 3.13 源码以 3.13.0 为例 cd /tmp wget https://www.python.org/ftp/python/3.13.0/Python-3.13.0.tgz tar -xf Python-3.13.0.tgz cd Python-3.13.0 # 编译配置关键启用 LTO 优化和 PGO ./configure --enable-optimizations --with-lto --with-pgo make -j$(nproc) sudo make altinstall # 用 altinstall 避免覆盖系统 python3 # 验证 python3.13 --version # 应输出 Python 3.13.0为什么用--enable-optimizations它自动执行 PGOProfile-Guided Optimization编译先用-O0编译一个临时解释器运行标准测试套件生成 profile 数据再用-O3和 profile 数据重新编译。实测对比未优化的 Python 3.13 启动 Django 项目耗时 1.8 秒启用--enable-optimizations后耗时 1.2 秒且内存占用降低 15%。--with-ltoLink Time Optimization进一步合并重复符号减小二进制体积。4.2 数据库迁移与初始数据加载从空库到可运行的 3 步Uvicorn 启动前数据库必须就绪。三步法创建迁移文件本地开发机python manage.py makemigrations python manage.py migrate --plan # 预览将执行的 SQL确认无误生成初始数据 fixture若需预置 admin 用户、基础配置python manage.py dumpdata auth.Group --indent 2 fixtures/groups.json python manage.py dumpdata myapp.Category --indent 2 fixtures/categories.json # 注意不要 dump auth.User密码哈希可能跨环境失效生产环境执行在服务器上# 激活虚拟环境若使用 source /home/myuser/myproject/venv/bin/activate # 执行迁移 python manage.py migrate --noinput # 加载 fixture--ignorenonexistent 避免模型变更导致失败 python manage.py loaddata fixtures/groups.json fixtures/categories.json --ignorenonexistent # 创建超级用户交互式但可脚本化 echo from django.contrib.auth import get_user_model; User get_user_model(); User.objects.create_superuser(admin, adminexample.com, StrongPass123) | python manage.py shell注意--noinput参数至关重要避免迁移时等待用户输入yes/no导致自动化脚本卡死。4.3 Nginx 启动与证书申请Lets Encrypt 的无人值守配置Nginx 配置完成后启动并申请免费 HTTPS 证书# 启用并启动 Nginx sudo systemctl enable nginx sudo systemctl start nginx # 安装 Certbot sudo apt install -y certbot python3-certbot-nginx # 申请证书自动修改 Nginx 配置添加 SSL sudo certbot --nginx -d myproject.com -d www.myproject.com # 自动续期Certbot 已配置 systemd timer sudo systemctl list-timers | grep certbot # 输出应包含 certbot.timer每 12 小时检查一次Certbot 会自动修改/etc/nginx/sites-available/myproject添加ssl_certificate等指令创建/etc/letsencrypt/目录存放证书配置systemdtimer确保证书到期前自动续期。验证 HTTPS 是否生效访问https://myproject.com浏览器地址栏应显示绿色锁图标用curl -I https://myproject.com查看响应头应有Strict-Transport-Security字段。4.4 Uvicorn 服务启动与健康检查5 个命令确认服务就绪服务启动后用以下命令逐层验证Uvicorn 进程是否存在sudo systemctl status myproject | grep active (running) # 或查看进程 ps aux | grep uvicornUvicorn 是否监听端口sudo ss -tlnp | grep :8000 # 应输出LISTEN 0 4096 127.0.0.1:8000 *:* users:((uvicorn,pid12345,fd6))Nginx 是否能代理到 Uvicorn本地测试curl -H Host: myproject.com http://127.0.0.1/ # 应返回 Django 的 HTML而非 502 Bad GatewayNginx 外部访问是否正常curl -I https://myproject.com # 应返回 HTTP/2 200 OK且有 Strict-Transport-Security 头WebSocket 连接是否建立用浏览器开发者工具 Consoleconst ws new WebSocket(wss://myproject.com/ws/chat/); ws.onopen () console.log(WebSocket connected); ws.onerror (e) console.error(WebSocket error, e);若控制台输出WebSocket connected说明 Nginx → Uvicorn → Django Channels 全链路打通。4.5 静态文件部署collectstatic 的 3 个隐藏陷阱python manage.py collectstatic是部署高频操作但有 3 个深坑陷阱 1STATIC_ROOT 未创建collectstatic不会自动创建STATIC_ROOT目录。若目录不存在命令静默失败。务必提前mkdir -p /home/myuser/myproject/staticfiles chown -R myuser:myuser /home/myuser/myproject/staticfiles陷阱 2权限不足导致文件无法读取Nginx 运行用户是www-data若staticfiles/目录属主是myuserNginx 无法读取。解决方案sudo usermod -a -G myuser www-data # 将 www-data 加入 myuser 组 sudo chgrp -R myuser /home/myuser/myproject/staticfiles sudo chmod -R gr /home/myuser/myproject/staticfiles sudo chmod gx /home/myuser/myproject/staticfiles # 目录需 x 才能 cd陷阱 3第三方包静态文件丢失django-compressor、django-grappelli等包的静态文件不会被自动收集。在settings.py中显式添加import django.contrib.admin STATICFILES_DIRS [ BASE_DIR / static, django.contrib.admin.static_directory, # 确保 admin 静态文件 # 其他包路径... ]5. 常见问题与排查技巧实录线上故障的 7 种典型现场与 12 条救命命令5.1 问题速查表症状、原因、命令、修复症状可能原因快速诊断命令修复方案网站打不开Nginx 502 Bad GatewayUvicorn 未运行或端口未监听sudo systemctl status myprojectsudo ss -tlnp | grep :8000sudo systemctl start myproject检查/var/log/myproject/error.logHTTPS 访问报 ERR_SSL_PROTOCOL_ERRORCertbot 证书过期或 Nginx SSL 配置错误sudo certbot certificatessudo nginx -tsudo certbot renew --dry-runsudo nginx -s reloadWebSocket 连接失败400 Bad RequestNginx 缺少Upgrade和Connection头curl -i -H Connection: upgrade -H Upgrade: websocket http://localhost/ws/检查 Nginx 配置中/ws/location 的proxy_set_headerDjango Admin 登录后 403 ForbiddenCSRF_COOKIE_SECURETrue但未走 HTTPScurl -I http://myproject.com/admin/确认SECURE_SSL_REDIRECTTrue且 Nginx 配置了X-Forwarded-Proto数据库迁移报insufficient privilegemyuser未获CREATEDB和CREATEROLE权限sudo -u postgres psql -c \du myusersudo -u postgres psql -c ALTER USER myuser CREATEDB;静态文件 404STATIC_ROOT路径错误或 Nginx alias 路径不匹配ls -l /home/myuser/myproject/staticfiles/curl -I http://myproject.com/static/css/app.css核对settings.py中STATIC_ROOT和 Nginxalias路径是否一致**Uvic