Django 无缝部署到单服务器

发布于 2024-11-16 09:57:33 字数 1049 浏览 5 评论 0原文

我有一个基于 Django 和 Python 2.6 构建的新网站,已将其部署到云中(符合流行语并且 Amazon micro EC2 实例是免费的!)。
以下是我的详细注释:https://docs.google.com/document/d/1qcZ_SqxNcFlGKNyp-CXqcFxXXsKs26Avv3mytXGCedA/edit?hl=en_US

由于这是一个新网站(并且想尝试最新最好的),所以我使用了 Nginx和 Gunicorn 在 Supervisor 之上。
使用 YUM / easy_install 从主干安装的所有软件。
我的数据库是 Sqlite (目前 - 不确定下一步该去哪里,但这不是问题)。待办事项列表中还有:virtualenv + pip。
到目前为止一切顺利。
我的代码在 SVN 中。我编写了一个简单的 fabfile 来部署 - 检查最新代码并通过 Supervisor 重新启动 Gunicorn。我将我的 DNS 名称连接到弹性 IP。
它有效。

我的问题是,如何在不中断服务的情况下更新网站?当我运行我的小更新脚本时,该网站的用户收到 404s / 500s。

有没有办法在不添加其他服务器的情况下做到这一点(价格是关键)?

我希望拥有一个登台系统(在不同的端口上?)以及登台和生产之间的无缝切换。在同一台(免费)服务器上。通过结构。
我该怎么做?两个站点运行的是同一个 Nginx 吗?我可以在不影响生产的情况下升级暂存吗? fabfile 会是什么样子?目录树会是什么样子?

谢谢!

塔尔。

相关:

I have a new website built on Django and Python 2.6 which I've deployed to the cloud (buzzword compliant AND the Amazon micro EC2 instance is free!).
Here are my detailed notes: https://docs.google.com/document/d/1qcZ_SqxNcFlGKNyp-CXqcFxXXsKs26Avv3mytXGCedA/edit?hl=en_US

As this is a new site (and wanting to play with the latest and greatest) I used Nginx and Gunicorn on top of Supervisor.
All software installed from trunk using YUM / easy_install.
My database is Sqlite (for now - not sure of where to go next, but that is not the question). Also on the todo list: virtualenv + pip.
So far so good.
My code in in SVN. I wrote a simple fabfile to deploy - checks out the latest code and restarts Gunicorn via Supervisor. I hooked my DNS name to an Elastic IP.
It works.

My question is, how do I update the site without a disruption of service? Users of the site get 404s / 500s when I run my little update script.

Is there a way to do this without adding another server (price is key)?

I would love to have a staging system (on a different port?) and a seamless switch between Staging and Production. On the same (free) server. Via Fabric.
How do I do that? Is it the same Nginx running both sites? Can I upgrade Staging without hurting Production? What would the fabfile look like? What would the directory tree look like?

Thanks!

Tal.

Related:

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

海螺姑娘 2024-11-23 09:57:33

Nginx 允许您为反向代理设置故障转移,您可以将一个 Gunicorn 实例作为主实例,只要该版本正在运行,它就永远不会查看故障转移。

如果您配置站点以使新版本位于故障转移实例中,则只需编写 fab 文件以使用站点的新版本更新故障实例,然后在准备就绪时关闭主实例。 Nginx 将无缝故障转移到第二个实例,然后您就可以在新版本上运行,无需停机。

然后,您可以更新主要版本,然后将其重新打开,您的主要版本现已上线。此时,您可以保持故障转移实例运行以防万一,或者将其关闭。

有些事情需要考虑。您必须小心数据库,如果您使用 sqllite,请确保两个 Gunicorn 实例都可以访问 sqllite 文件。

如果您有一个普通的数据库,这不是一个问题,您只需确保在切换到新版本之前应用新版本所需的任何数据库迁移即可。

如果它们是向后兼容的更改,那么这没什么大不了的。如果它们不向后兼容,那么请小心,您可能会在切换到新版本之前破坏旧版本的网站。

为了让事情变得更容易,我会在不同的虚拟环境上运行这些版本。

如果您使用supervisord来控制gunicorn,那么您可以使用supervisorctl命令来重新加载/重新启动您想要部署的实例,而不会影响另一个实例。

希望有帮助

这是 nginx 配置的示例(不是完整的配置文件,删除了不重要的部分)

这假设主 Gunicorn 实例在端口 9005 上运行,另一个在端口 9006 上运行

upstream service-backend {
    server localhost:9005;        # primary
    server localhost:9006 backup; # only used when primary is down
}

server {
    listen 80;
    root /opt/htdocs;
    server_name localhost;

    access_log /var/logs/nginx/access.log;
    error_log  /var/logs/nginx/error.log;

    location / {
        proxy_pass http://service-backend;
    }
}

Nginx allows you to setup failover for your reverse proxies you can put one gunicorn instance as the primary and as long as that version is running it will never look at the failover.

If you configure your site so that your new version is in the failover instance you just need to write your fab file to update the failure instance with the new version of the site and then when ready, turn off primary instance. Nginx will seamlessly failover to second instance and bam you are running on new version with no downtime.

You can then update the primary version and then turn it back on and your primary is now live. At this point you can keep the failover instance running just in case, or turn it off.

Some things to consider. You have to be careful with databases, if you are using sqllite make sure both gunicorn instances can accesss the sqllite file.

If you have a normal database this is less of a problem, you just need to make sure you apply any database migrations that the new version needs before you switch to it.

If they are backwards compatible changes then it isn't a big deal. If they aren't backwards compatible then be careful, you could break the old version of the site before you switch over to new version.

To make things easier I would run the versions on different virtual environments.

If you use supervisord to control gunicorn, then you can use the supervisorctl commands to reload/restart which ever instance you want to deploy without affecting the other one.

Hope that helps

Here is an example of and nginx config (not a full config file, removed the unimportant parts)

This assumes the primary gunicorn instance is running on port 9005 and the other is running on port 9006

upstream service-backend {
    server localhost:9005;        # primary
    server localhost:9006 backup; # only used when primary is down
}

server {
    listen 80;
    root /opt/htdocs;
    server_name localhost;

    access_log /var/logs/nginx/access.log;
    error_log  /var/logs/nginx/error.log;

    location / {
        proxy_pass http://service-backend;
    }
}
熟人话多 2024-11-23 09:57:33

听起来你需要弄清楚如何告诉gunicorn 优雅地重新启动。似乎您所要做的就是在通知重新加载应用程序时向 Gunicorn 进程发出 HUP。正如链接中所述,gunicorn 文档解释了如何执行此操作。

Sounds like you need to figure out how to tell gunicorn to gracefully restart. It seems like all you have to do is issue a HUP to the gunicorn process when to notify to reload the app. As describe in the link about, the gunicorn docs explain how to do it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文