资讯动态

公司项目第一次上线全指南:从环境搭建、发布回滚到运维监控

发布时间:2026/10/14 15:22:47 来源:尧图企业网站定制
第一次做公司项目上线我原以为只是把代码传到服务器而已。结果从申请服务器开始一路被现实捶打不知道要选多大配置不知道环境变量怎么管不知道数据库怎么迁更不知道原来还有“回滚”这种东西。事情做完之后回头看整个过程其实有迹可循很多坑其实可以靠事前准备避开。我负责的只是公司内部一个业务系统的首次公网部署十几个人用的小系统。正是因为小反而什么环节都没人兜着领导说“你看着弄”我才被迫把上线相关的每个环节都碰了一遍。这一篇就把完整过程写下来从准备工作到环境搭建、发布、回滚、故障排查全是实际操作过的经验不是纸面教程。如果你也正在准备第一次公司项目上线可以先按我这套思路走至少能少走很多弯路。1. 上线前的准备工作别急着敲命令第一次上线最容易犯的错是满怀热情登录服务器就开始安装东西结果装到一半发现系统版本不对、磁盘不够、域名没解析停下来重新弄。我那次就是因为没查项目对操作系统的要求默认选了和本地一样的版本结果某个底层库编不过去白白折腾了一天。所以不管项目多小先把底细摸清楚。1.1 先理清项目底细技术栈、依赖与运行条件要准备一张表格把项目的基本信息列出来。项目用什么语言和框架运行需要哪个版本的运行时有哪些第三方服务数据库、消息队列、缓存有没有定时任务静态文件在哪上传文件存在哪等等。我当时这个项目是 Python Django PostgreSQL Redis前端是 Nginx 直接托管静态文件进程用 Gunicorn 跑。看起来不算复杂但到了生产环境就出现差异。比如本地用的 SQLite生产换成了 PostgreSQLORM 模型没问题可数据库迁移脚本里的某些自定义字段就需要额外处理再比如本地静态文件由 Django 开发服务器处理生产必须交给 Nginx 或者 CDN否则请求量稍微大一点就会卡。建议把项目的依赖文件requirements.txt / package.json / go.mod实际看一遍把启动命令、配置项、环境变量都找齐最好还在一个干净环境里从头部署一次确认每一步都是可复现的。这个“干净环境演练”特别重要能提前暴露准备阶段漏掉的东西。别拿生产环境当试验场。1.2 服务器配置怎么选不拍脑袋也不铺张第一次选服务器没有流量数据参考按“当前规模 一定余量”估算即可。我的做法是先算并发业务系统一般是内部使用峰值可能就几十人同时在线那么 2 核 4GB 内存、40GB 系统盘 40GB 数据盘足够。但考虑到系统需要跑数据库、Redis、文件存储以及线上日志会慢慢累积1 核 2GB 很容易被 build 过程吃满所以我最终选了 4 核 8GB内存充裕之后编译和重启都快很多排查问题也能多开几个工具。操作系统我选了 Ubuntu 22.04 LTS。对我这种第一次上线的新手来说Ubuntu 的资料多、软件源更新及时遇到问题一套就搜到答案。CentOS 也完全可以关键是和你自己的操作习惯匹配别为了“大家都用哪个”去赌自己不熟悉的环境。带宽方面纯粹的公司内部小系统5M 带宽已经够用如果面向外部用户按平均页面大小和并发人数估算公式大约是“并发数 × 页面大小 ÷ 期望响应时间”。比如峰值 50 人页面平均 500KB期望 2 秒加载完粗略就是 50×0.5MB/2s 12.5MB/s换算下来需要约 100Mbps 带宽。这只是估算实际情况还要看静态资源是否可以走 CDN。1.3 域名、接入审核与 HTTPS 证书越早弄越好域名和证书看上去和应用部署无关实际上却卡进度。我在项目快上线前一天去申请免费证书结果域名解析因为注册商的信息更新问题过了好几个小时才生效差点导致验证失败。这事的教训是域名要提前购买并完成实名认证解析记录提前配好如果目标服务器部署在需要域名接入审核的机房公网域名的审核周期可能以周计这部分要提前确认别把它留到上线当天。HTTPS 证书现在基本是标配了我用的是 Lets Encrypt 的免费证书配合自动续期脚本不需要额外成本。需要注意证书申请过程依赖域名解析能正常指向服务器所以顺序必须是“先解析后申请证书再配置 Nginx”。提示就算只是公司内部系统也建议直接上 HTTPS。浏览器对 HTTP 的警告越来越多内部账号密码也不该明文传输。早配置早省心。1.4 把上线 Checklist 写进文档光靠脑子记上线那天一定会漏项。我第一次就是上线前以为万事俱备结果忘了收集备份路径导数据时找不到原数据库 dump 文件。后来我列了一份简单清单包含服务器信息、环境变量、依赖清单、数据库迁移脚本、静态文件收集命令、域名解析状态、HTTPS 证书状态、健康检查方式、回滚方案、联系人。这份清单不需要你一开始就写得完美但可以从项目启动时就持续更新上线前再逐项打钩。我后来的做法是把它放进公司内部知识库每次新同事上线项目前都按这个清单走一遍所有人都能少踩坑。2. 环境搭建与基础配置能跑通只是第一步服务器拿到手很多人第一件事是直接装软件。但我建议先做基础加固因为生产环境不是本地虚拟机它直接暴露在外网被扫描爆破是常态。2.1 系统初始化从 root 到专用用户服务器默认只有 root日常操作不应该一直用 root。我创建了一个 deploy 用户加到 sudo 组日常部署和运维都用这个账号。同时把 SSH 登录改为密钥方式关闭密码登录修改默认端口。第一次操作时我犹豫过改端口会不会太麻烦后来看到日志里满是来自外网的密码爆破尝试才庆幸自己提前做了。具体步骤是先用 root 登录创建用户然后把公钥写入 ~/.ssh/authorized_keys测试能用密钥登录后再把 /etc/ssh/sshd_config 里的 PasswordAuthentication 改为 no重启 sshd。这里要特别注意在确认密钥能登录之前千万别断开当前连接否则容易把自己锁在外面。我第一次操作时先开了一个备用终端测试通了才关闭原连接。2.2 安全组和防火墙只开该开的端口如果服务器在云平台安全组就是第一道防线。我只开放了 22、80、443 三个端口数据库和 Redis 端口没有开放到公网应用和数据库在同一台机器上时通过回环地址 127.0.0.1 访问这样即便服务配置有误也不会把数据库直接暴露出去。云服务器安全组和服务器内部防火墙ufw都可能拦截流量排查网络问题时两个地方都要看。我第一次配置 Nginx 后一直访问不了最后发现是云安全组没放行 80 端口而 Nginx 配置文件本身是没问题的。2.3 安装运行环境与中间件安装过程本身不复杂但版本要锁定。比如 Python 项目我通过 pyenv 管理 Python 版本再用 virtualenv 创建独立虚拟环境避免和系统自带的 Python 环境混淆。数据库和 Redis 直接用系统包安装启动后修改监听地址为 127.0.0.1并设置合理的密码。Nginx 的配置我放在 /etc/nginx/sites-available/通过软链接到 sites-enabled 启用。这里建议大家学习一下如何用 nginx -t 检查配置修改配置后先测试再 reload。因为 Nginx 的配置语法错误不会自动报错直接执行 reload 有时不会生效或者把站点搞挂。我最早改配置时就是改完直接 reload结果发现页面 502排查了半天才发现是 upstream 地址写错了。2.4 数据库迁移比想象中容易出问题小项目的数据库迁移通常就是从旧环境导出再导入新环境。但“导入新环境”这四个字背后有很多坑。首先导出之前要确认源数据库版本和目标数据库版本尽量一致避免字符集和排序规则差异。其次迁移之前先创建业务专用账号并分配最小的权限比如只给某个数据库的增删改查权限不要把 root 或超级用户给应用连接最后生产环境的数据库要做一次全量备份导入完成后还要校验行数、关键表记录数是否一致。我用的是 PostgreSQL操作大概是sudo -u postgres pg_dump -Fc dbname backup.dump # 目标服务器 sudo -u postgres createdb -O djangouser newdb sudo -u postgres pg_restore -d newdb /path/to/backup.dump如果是 MySQL用 mysqldump 导出再在目标库导入。导出时建议加 --single-transaction 和 --quick避免影响线上业务。校验阶段先查表数量再抽查核心业务表行数确认无误后再切换应用配置。2.5 环境变量和配置文件把密钥和代码分离第一次部署时最容易把开发环境配置直接搬到生产环境。正确的做法是代码库里放配置模板真实的环境变量放在服务器上的 .env 文件里并且将它加入 .gitignore 或发布排除列表。比如数据库密码、Redis 连接串、Secret Key、第三方 API Key都不应该出现在代码仓库里。我用 systemd 管理应用进程在 service 文件里通过 EnvironmentFile 指定环境变量文件。这样启动服务时自动加载变量既不需要把密钥写进脚本也不用手动 export。需要注意环境变量文件权限要设为 600否则同服务器上的其他账号也能读到。这个点看起来小但真实发生的安全问题不少。3. 代码发布与回滚机制不要只考虑“怎么发”第一次上线你可能只用一条命令把代码拉下来。但发布流程能不能支撑后续更新、出问题能不能回滚这在一开始就要想清楚。3.1 发布方式怎么选先手动再自动化发布方式大概有几类直接把本地打包文件传到服务器、服务器上 git pull、通过 CI/CD 自动构建发布。第一次上线建议从“半自动”开始代码推送到一个专门的发布分支在服务器上用 git pull 拉取然后手动执行依赖安装、数据库迁移、重启服务。这样每一步都看得见方便学习和排错等流程稳定后再接入 CI/CD由流水线自动完成构建和部署。为什么不建议一上来就上 CI/CD因为一旦构建脚本里有错误第一次触发的流水线可能就把生产环境搞崩了而且排查问题时要同时看代码、构建脚本、部署脚本三层对新人很不友好。先把这层复杂度往后放等手动流程跑顺了再写自动化脚本会容易得多。3.2 首次发布实操步骤记录我这边的发布目录结构是/var/www/myapp ├── releases/ │ ├── 20250101_v1.0.0/ │ └── current - 20250101_v1.0.0 ├── shared/ │ ├── .env │ └── media/ └── logs/每次发布新建一个带日期的目录软链接 current 指向当前版本。这样回滚时只需要把软链接指回上一版本同时重启服务即可。应用代码里读取动态文件时路径用 current 下的真实路径媒体文件等写到 shared 里避免切换软链接时丢文件。第一次发布的具体命令记录如下cd /var/www/myapp/releases git clone -b release/1.0.0 git地址 20250101_v1.0.0 ln -snf /var/www/myapp/releases/20250101_v1.0.0 /var/www/myapp/current cd /var/www/myapp/current python -m venv venv source venv/bin/activate pip install -r requirements.txt python manage.py migrate python manage.py collectstatic --noinput sudo systemctl restart myapp sudo nginx -t sudo systemctl reload nginx在 clone 前我已经把 .env 放到了 shared 目录并通过软链接 .env 到 current 里所以代码里没有真实密钥。每执行一步我都会 echo 或者开另一个终端确认。比如 migrate 后查一遍数据库表collectstatic 后确认静态文件目录有内容。发布完成的验证我首先在服务器本机执行 curl http://127.0.0.1:8000/healthz确认服务本身正常然后在另一台机器上用域名访问确认 Nginx 转发没有问题最后检查应用日志和 Nginx 访问日志看到正常的状态码 200 和内部错误日志为空才放心。3.3 回滚预案别赌“这次一定没问题”第一次上线我其实没准备回滚方案后来在一次后续发布出问题时才意识到没有回滚意味着一旦新版本有问题就会面临“线上无法访问、现场改代码、改完还要重新发布”的灾难。从那以后每次发布前都做三件事把当前版本的目录打个标记记录当前软链接指向把数据库迁移前备份一次把依赖锁定文件也留一份。如果需要回滚操作极其简单rm /var/www/myapp/current # 删除软链接 ln -s /var/www/myapp/releases/前一个版本目录 /var/www/myapp/current sudo systemctl restart myapp注意如果本次发布包含了数据库结构变更回滚代码的同时要考虑数据库是否需要回退。如果迁移脚本是向前兼容的可以保留新库结构只回滚代码如果字段删除等不兼容变更已经发生就要用发布前备份恢复数据库。这种情况最好提前和团队约定好到底代码先行还是数据库先行。我的经验是业务系统第一次上线阶段结构变动频繁发布前一定做数据库备份宁可多备份也不要事后找后悔药。注意不要把“回滚”当成最后才补的流程它应该和发布流程一起写进上线文档。出问题时人容易慌张照着写好的步骤执行能避免临时决策带来的二次事故。4. 常见问题与排查实录第一次上线最容易踩的坑就算准备充分第一次上线还是会遇到各种意外。我把自己遇到的以及其他同事遇到过的典型问题整理在一起按现象、原因、解决方法列出来希望你能少走这些弯路。4.1 服务访问不通先看端口、再看监听地址、再看安全组现象Nginx 启动了应用也启动了但浏览器访问域名一直转圈或显示无法连接。我第一次遇到的真实原因是应用进程只监听了 127.0.0.1:8000Nginx 的 upstream 也指向 127.0.0.1:8000看起来没问题但云安全组没放行 80 端口所以外部请求根本进不来。检查顺序建议是先在服务器本机 curl 127.0.0.1:端口确认应用正常再用 curl 服务器的公网IP:端口确认安全组最后用域名访问确认 DNS 解析和 Nginx 配置。有时候域名解析已经生效但本地网络有缓存也容易误以为是服务器问题。可以在另外一台没有访问过该域名的机器上 ping 或使用在线工具检查解析结果避免被本地缓存误导。4.2 依赖版本不一致开发环境跑得好生产环境起不来现象代码在本机能跑生产环境启动时报某个模块不存在或版本不兼容。原因大多是依赖没有锁定版本或者pip install -r requirements.txt拉到了新版本。解决方法是把 requirements.txt 里的版本完全锁定比如Django4.2.10、psycopg2-binary2.9.9重新生成依赖文件时用pip freeze。前端项目则锁定 package-lock.json这样能避免同样的“昨天还好好的”问题。我第一次上线时就是 requirements.txt 里只写了依赖名结果安装到了新版本和已有代码不兼容。后来我把依赖文件锁定并提交重新构建虚拟环境才正常。4.3 数据库权限不足或连接串错误现象应用能启动但页面报数据库连接失败或者迁移时提示无权限。原因通常是两类一类是环境变量里数据库连接串写错比如密码包含特殊字符没有转义另一类是应用账号权限不足。前者可以通过在服务器上使用同样的连接串手动连接数据库来验证后者需要到数据库里给应用账号分配对应库的权限。生产环境建议用最小权限原则但如果权限给得太小比如连建表权限都没有迁移脚本就跑不了。至少区分“迁移账号”和“运行账号”迁移时用临时高权限账号运行用低权限账号。4.4 磁盘被日志和构建产物占满现象系统跑着跑着突然磁盘满告警服务频繁报错。原因大多是应用日志没有轮转logrotate或者每次发布产生的旧版本目录没有清理。我第一次上线没注意几个月后磁盘占用超过 90%数据库和日志写入都变慢。后来我配置了 logrotate 每天切割日志并保留 7 天发布脚本里规定只保留最近 3 个版本目录其他自动清理。磁盘容量是最容易被忽视的资源建议上线第一天就把日志轮转和备份清理策略做好。4.5 常见问题速查表现象可能原因排查方法快速解决外网无法访问本机正常安全组/防火墙未放行curl 公网IP:端口云安全组放行端口Nginx 502 Bad Gatewayupstream 地址错/应用未启动查看 Nginx error.log修正 upstream 并重启应用页面能开接口 500数据库连接或代码配置问题查看应用日志和数据库日志检查连接串、账号权限服务启动后立刻退出环境变量缺失/依赖错误systemctl status 查看报错补充环境变量、重装依赖定时任务不执行crontab 环境变量缺失/脚本路径错手动执行脚本脚本内使用绝对路径并加载环境上传文件无法访问媒体文件路径不对/权限不足检查目录权限和 Nginx location将媒体目录加入 shared 并手动授权5. 上线首日的验证与后续运维这才算真正“发布完成”很多人以为服务能访问就算上线完成其实上线完成的标准应该是“有监控、有备份、有回归验证”。这几点要是没做后续出现问题只能靠用户反馈才发现。5.1 用一次完整回归验证所有功能上线后不要直接告诉使用者“可以用了”而是自己先按核心流程走一遍。我当时把系统里几个最重要的操作做成了一份验收单登录、列表查询、新增数据、编辑数据、上传文件、导出报表、定时任务跑一次。每一项都在生产环境实测通过后再通知大家使用。这样做还有一个好处如果验收过程发现数据异常因为刚上线人员还没开始使用可以立刻处理影响面很小。回归验证时注意账号安全生产环境的验收数据最好用测试账号和测试数据不要拿正式数据乱试。如果系统有初始化数据和默认管理员上线后要立即修改默认密码并关闭默认注册入口。5.2 基础监控从一行命令到自动告警第一次做监控不需要很重的方案我用了三件事云平台自带的监控看 CPU、内存、磁盘应用日志配置了错误级别输出写了一个简单的健康检查脚本每分钟 curl 一次健康接口连续失败 3 次就给群里发消息。后面随着项目变复杂才逐步接入更完整的监控系统。健康检查脚本不一定用复杂工具一个 shell 脚本加 crontab 就能实现比如#!/bin/bash CODE$(curl -s -o /dev/null -w %{http_code} http://127.0.0.1:8000/healthz) if [ $CODE ! 200 ]; then echo service down: $CODE | mail -s ALERT opsexample.com fi我的经验是先有能用的告警再考虑是否换更专业的监控产品。当时如果连“服务挂了”的感知都要靠访问才发现那上线后的运气成分就太大了。5.3 定时备份与安全更新数据库备份我做了每日全量备份保留最近 7 份备份文件放在独立的数据盘上有条件的话再同步到另一台机器。备份脚本的执行时间和业务低峰期对齐并且在备份完成后自动校验备份文件大小避免备份失败还不知道。系统安全更新方面我设置了每周一次自动安全更新同时关注应用依赖的安全公告。这里有个小坑装安全更新后可能发生系统重启如果业务是单机部署重启会导致短暂不可用。所以自动更新最好安排在凌晨并且在监控里加上“开机时间”指标方便第二天发现机器是否重启过。5.4 把第一次上线的经验固化成可复用流程上线稳定之后我还做了一件事把这次从准备到发布的全过程整理成一份部署文档内容包括服务器信息、目录结构、常用命令、发布步骤、回滚步骤、备份策略、问题排查。之后再做其他项目上线基本就是按文档跑一遍再针对新项目调整差异部分即可。这次亲身经历让我最大的体会是第一次上线最值钱的不是“成功上线”这个结果而是过程中暴露出来的所有问题。你越是提前做演练、把每一步都变成检查项上线当天就越从容。许多第一次上线的问题本质上都是因为“我以为没问题”。把“我以为”换成“我确认”是运维这行最重要的一课。我个人现在每次发布前都会列一个最小检查单代码分支对不对、依赖锁没锁、数据库备份做没做、回滚软链指向哪里、健康检查接口通不通。看起来简单但每一条都是靠踩坑换来的。你也别怕第一次做不好项目上线本身就是一个不断演练、不断复盘的过程只要每次都能把问题变成文档和流程第二次就不会再手忙脚乱了。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑