我目前正在我的实时生产服务器上编辑我的 Python 代码(Flask Web Server)。我刚刚开始建立一个网站,并且知道这不是一个可行的长期解决方案。我知道许多人有许多不同的方法来管理开发、测试和生产环境(可能还有更多),但有人能告诉我一个地方,我可以在哪里开始学习更多关于管理这种流程流的知识吗?我不知道从哪里开始。谢谢。
答案1
让我们停下来回忆一下为什么我们首先将开发环境和生产环境分开。
简而言之,这是因为我们是人,都会犯错拥有独立环境的目的是为了尽早发现并纠正错误,以免对用户造成影响。
设置方法的数量几乎和要部署的应用程序数量一样多。无论您在做什么,最好的办法是使用一种足够简单易懂和使用的方法,这样您就不会想绕过它,并且足够正确,可以帮助您在问题进入生产之前发现它们。
现在,如果你想要有进取心,并建立一个几乎没人能完全理解、几乎没人能真正理解的东西喜欢那么一定要遵循 ITIL。里面有足够多的流程,足以让你在职业生涯的一半时间里埋头于文书工作中。不过,如果你在某些行业或为某些客户开发软件,你可能不得不这样做。
不过,从你的问题来看,你似乎是一个单独的开发人员或一个小团队,正在从事一个需要更多灵活性和速度的项目。
本质上,您需要两种类型的工具:测试工具和部署工具。
至少,你们真的需要两台服务器:生产服务器和测试(暂存)服务器。首先,您需要在本地工作站上测试更改。如果一切正常,则将代码推送到暂存服务器,然后再次测试。如果一切正常,则将其推送到生产服务器并等待火警响起。
测试软件最有效的方法之一是持续集成使用此方法,每当您将代码签入共享存储库时,服务器都会签出代码并运行整个测试套件。(您确实为一切,对吧?)它还可以进行集成测试。如果所有测试都通过,您可以配置此类工具来推动将代码投入生产并自动部署。例如,Github 就是这样做的。目前两种常见的 CI 工具是 Jenkins 和 Travis。
最后是部署。这似乎很明显:您将新代码复制到(暂存或生产)服务器,然后告诉 Web 服务器在新代码上启动新的工作程序。Capistrano、Commando 或 Deployer 等工具有助于自动化此过程。如果出现问题,它们通常还可以回滚到以前的部署。(并且您的语言或框架应该有方法来处理回滚数据库架构更改,例如 Rails 中的迁移。对于 Flask,您可以使用 SQLAlchemy 和 Alembic 之类的东西。)
您可能希望达到的最终状态是拥有 100% 的测试覆盖率,对所有内容进行单元、功能和集成测试,以便您可以利用持续集成来尽快部署更改或发现错误。从单个“测试”服务器开始,然后逐步提高,直到达到目标。
答案2
为什么不应该在生产环境中进行开发
任何人都可以通过可用的调试实用程序在您的服务器上运行任意代码(如果您处于调试模式,如果您正在开发您的网站,您就会处于调试模式。)
如何设置你的环境
- 设置一个简单的 NGINX 反向代理。
- 设置
staging.yourwebsite.com
具有自己文件夹的站点 - 设置具有自己文件夹的生产站点
- 将临时站点限制为你的家庭 IP 地址
一个简单的 NGINX 配置示例:
upstream production {
server 127.0.0.1:5000; # Default Flask address
}
upstream staging {
server 127.0.0.1:5001;
}
server {
server_name yourwebsite.com default_server;
access_log /var/log/nginx/yourwebsite_access.log;
error_log /var/log/nginx/yourwebsite_error.log;
location / {
proxy_pass http://app;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering 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;
}
}
server {
server_name staging.yourwebsite.com;
access_log /var/log/nginx/staging_access.log;
error_log /var/log/nginx/staging_error.log;
allow YOUR_IP_ADDRESS;
deny all;
location / {
proxy_pass http://staging;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_buffering 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;
}
}