CloudFoundry:如何使用多个buildpack? (NGINX + Django / Gunicorn)

问题描述 投票:0回答:1

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

---
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一起使用。但是,我不确定如何在单个应用程序上使用多个buildpack。我已按照nginx.conf的指示在项目目录中创建了mime.typesbuildpack.ymlhttps://docs.cloudfoundry.org/buildpacks/nginx/index.html

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才能启动命令。前面的buildpacks中的命令将被忽略。因此,我无法启动Nginx服务器。如何正确设置多个构建包?

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

django nginx cloudfoundry pivotal-cloud-foundry
1个回答
0
投票

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

还有其他痛点:

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

无论如何,如果您仍然想将两者都塞进同一个应用程序中,则有两种选择。

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

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

  3. 如上所述,在使用上述方法时,要使两个进程都正确退出是特别棘手的。这是我发现的一种可帮助您的黑客:

#!/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 &

您需要找出解决其他缺点的方法,或者只是切换到使用多个应用程序。希望能有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.