在Elasticbeanstalk Docker环境中提供Django静态文件

时间:2018-05-01 08:49:51

标签: docker amazon-elastic-beanstalk

使用docker环境将Django应用程序部署到EB时,静态文件将返回404。

我在docker容器上使用gunicorn,因为不推荐/不可能(?)通过gunicorn提供静态文件,我想配置EB nginx使用主机文件系统为它们提供服务。

Dockerfile

FROM python:3
....
....
# Expose listen ports
EXPOSE 8002

RUN chmod +x ./docker/container_start.sh

CMD ["sh", "./docker/container_start.sh"]

Dockerrun.aws.json

{
  "AWSEBDockerrunVersion": "1",
  "Ports": [
    {
      "ContainerPort": "8002"
    }
  ],
  "Volumes": [
    {
      "ContainerDirectory": "/app/assets",
      "HostDirectory": "/var/app/current/assets"
    }
  ]
}

我如何告诉EB nginx从/assets/提供/var/app/current/assets *并将其余部分代理到docker容器?

由于docker环境,下面的内容无效。

option_settings:
  "aws:elasticbeanstalk:container:python:staticfiles":
    "/static/": "www/static/"

3 个答案:

答案 0 :(得分:1)

我遇到了完全相同的问题!解决方案是在服务器上的/etc/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf中自定义nginx配置。

基本上,我将该文件的内容复制到了.ebextension配置文件中,并为静态文件夹添加了位置指令。

因此,使用您的Dockerrun.aws.json

{
  "AWSEBDockerrunVersion": "1",
  "Ports": [
    {
      "ContainerPort": "8002"
    }
  ],
  "Volumes": [
    {
      "ContainerDirectory": "/app/assets",
      "HostDirectory": "/var/app/current/assets"
    }
  ]
}

您将创建.ebextension / 01_nginx.config

files:
  "/etc/nginx/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf":
  mode: 000644
  owner: root
  group: root
  content: |
    map $http_upgrade $connection_upgrade {
        default        "upgrade";
        ""            "";
    }

    server {
        listen 80;

        gzip on;
        gzip_comp_level 4;
        gzip_types text/html text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

        if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
            set $year $1;
            set $month $2;
            set $day $3;
            set $hour $4;
        }
        access_log /var/log/nginx/healthd/application.log.$year-$month-$day-$hour healthd;

        access_log    /var/log/nginx/access.log;

        location /assets/ {
          root /var/current;
        }

        location / {
            proxy_pass            http://docker;
            proxy_http_version    1.1;

            proxy_set_header    Connection          $connection_upgrade;
            proxy_set_header    Upgrade             $http_upgrade;
            proxy_set_header    Host                $host;
            proxy_set_header    X-Real-IP           $remote_addr;
            proxy_set_header    X-Forwarded-For     $proxy_add_x_forwarded_for;
        }
    }

对我有用!

答案 1 :(得分:0)

您无法做的事。

您无法将/host-dir挂载到/container-dir上,并期望主机读取挂载前已存在的/container-dir的内容。 (/container-dir的内容被隐藏。)请参见this question/answer

您可能希望将静态资产包括在Elastic Beanstalk捆绑软件中,而不是在docker映像中。如果这样做,这些资产将显示在/var/app/current中,然后可以告诉Elastic Beanstalk的内置nginx将其用作per the other answer in this thread

答案 2 :(得分:0)

总结一下我们的解决方案,该解决方案用于使用nameserver 208.67.222.222 nameserver 208.67.220.220 在Elasticbeanstalk docker容器中运行django中的静态文件:

  1. 在容器准备就绪之前,我们不希望运行SolutionStackName: 64bit Amazon Linux 2 v3.2.0 running Docker。为此,我们在entrypoint.sh中启动了该程序,之后不久也启动了gunicorn。
  2. 我们让collectstatic将静态文件放入“ static”(通过我们的设置):
collectstatic
  1. 我们在STATIC_ROOT = "static" STATIC_URL = "/static/" 中配置了一个部署后脚本,该脚本将静态文件从容器中复制到.platform/hooks/postdeploy中的ec2 vm上(脚本在其中运行):
/var/app/current
  1. 我们通过在#! /bin/bash docker cp $(docker ps --no-trunc -q | head -n 1):/home/app/static . 中放置自定义配置文件来告诉nginx在哪里找到静态文件:
.platform/nginx/conf.d/elasticbeanstalk/custom.conf

就是这样。它对我们有用。