【问题标题】:CloudFoundry: How to use multiple buildpacks? (NGINX + Django/Gunicorn)CloudFoundry:如何使用多个构建包? (NGINX + Django/Gunicorn)
【发布时间】:2020-06-19 21:49:09
【问题描述】:

我在 Cloud Foundry 中使用以下 manifest.yml 文件将 Django/Gunicorn + whitenoise(用于静态文件服务)作为单个应用程序工作:

---
applications:
- name: mydjango
  instances: 1
  command: src/tvpv_portal/bin/start_gunicorn_django.sh
  memory: 2048M
  disk_quota: 1024M
  buildpacks:
    - https://github.com/cloudfoundry/python-buildpack.git
  stack: cflinuxfs3
  env:
    DJANGO_MODE: Production

为了学习/实验,我想删除白噪声并使用 nginx_buildpack 设置 Nginx 以与 Django/Gunicorn 一起使用。但是,我不确定如何在单个应用程序上使用多个构建包。我按照https://docs.cloudfoundry.org/buildpacks/nginx/index.html 的指示在我的项目目录中创建了nginx.confmime.typesbuildpack.yml

nginx.conf

daemon off;

error_log /home/vcap/app/nginx-error.log;
events { worker_connections 1024; }

http {
    log_format cloudfoundry '$http_x_forwarded_for - $http_referer - [$time_local] "$request" $status $body_bytes_sent';
    access_log /home/vcap/app/nginx-access.log cloudfoundry;

    default_type application/octet-stream;
    include mime.types;

    sendfile on;
    gzip on;

    tcp_nopush on;
    keepalive_timeout 30;
    port_in_redirect off; # Ensure that redirects don't include the internal container PORT - 8080

    server {
        listen {{port}};
        server_name localhost;

        # Serve static files.
        location /static/ {
            alias /home/vcap/app/src/tvpv_portal/static/;
        }

        # Serve media files.
        location /media/ {
            alias /home/vcap/app/src/tvpv_portal/media/;
        }

        # Reverse proxy to forward to main app.
        location / {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://127.0.0.1:8000;
        }
    }
}

我试着做cf push mydjango -b nginx_buildpack -b python_buildpack。但是从查看文档看来,只有最后一个 buildpack 能够启动该命令。前面的 buildpack 中的命令将被忽略。因此,我无法启动 nginx 服务器。如何正确设置多个 buildpack?

我确实阅读了CloudFoundry: nginx for serving static content on top of Gunicorn (Docker),但回复是关于拥有两个具有不同路线的独立应用程序。由于这更多地用于使用 CF 进行学习/实验,我想知道是否可以使用单个应用程序来完成它而不分离静态内容。感谢您的帮助。

【问题讨论】:

  • 我将尝试使用两个应用程序进行试验。一个用于 nginx。一个用于 Django/Gunicorn,让它们通过自己的域地址相互交谈。

标签: django nginx cloud-foundry


【解决方案1】:

对于生产工作负载(或任何重要的工作),您确实不希望将多个逻辑上独立的进程放入一个容器中。主要原因是这使您的应用程序难以扩展。假设您的应用程序变得流行,并且您需要更多的 Django 处理来处理负载,而 Nginx 和 Django 在同一个容器中,您必须一起扩展两者。如果它们是单独的应用程序,您可以根据每个逻辑流程的需要独立扩展它们。

还有其他痛点:

  • CPU 和内存管理比较棘手。您有多个进程竞争同一个资源池。这对于 Java 应用程序来说尤其棘手,因为 JVM 喜欢占用 all 内存。这意味着您必须更好地估计,以免耗尽内存导致应用崩溃。
  • 正确响应运行状况检查更加复杂。您的健康检查需要准确地表示您的应用程序正在“工作”。如果在同一个应用中有多个进程,那就更难了。
  • 当其中一个进程死亡时让应用程序退出是很棘手的。这类似于正确进行健康检查。如果应用程序没有完全退出,那么应用程序将不会重新启动,您可能会留下一半的应用程序,或者无法自动重新启动/修复的损坏的应用程序。
  • 您可以更灵活地使用两个独立的应用程序,特别是您可以独立更新应用程序。

无论如何,如果您仍然想将两者都放入同一个应用程序中,那么您有几个选择。

  1. 您可以简单地使用cf push -c 或通过将command: 添加到 manifest.yml 来控制启动命令。这将允许您覆盖最终 buildpack 设置的命令。请小心,因为它将完全覆盖 buildpack 设置的内容,因此您确实需要知道要调用的正确命令,否则您的应用程序将无法启动(这对于启动命令可能很复杂的 Java 应用程序尤其棘手)。

  2. 您可以将.profile 文件拖放到应用程序目录的根目录中(即设置cf push -p 的位置)。该脚本将在最终 buildpack 设置的命令之前执行,您可以使用它在后台启动其他进程。

如上所述,当您使用上述方法时,要让两个进程都正确退出是特别棘手的。这是我发现的一个有用的技巧:

#!/bin/bash
set -e

run_second_process() {
    # insert the command to run the second process here
    #   it should run and keep running (i.e. foreground)
    nginx -c nginx.conf
    # should never get to here, if it does the app crashed
    pkill python  # insert name of your primary process
    # now we are all dead and the container will restart
}

# runs the second process in the background
#   that is important otherwise the primary process will never run
run_updater &

您需要想办法解决其他缺点,或者改用多个应用程序。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-19
    • 2017-02-23
    • 2013-03-25
    • 2013-03-01
    • 1970-01-01
    • 2021-03-19
    • 1970-01-01
    相关资源
    最近更新 更多