在 Elasticbeanstalk Docker 环境中提供 Django 静态文件
Posted
技术标签:
【中文标题】在 Elasticbeanstalk Docker 环境中提供 Django 静态文件【英文标题】:Serving Django static files in Elasticbeanstalk Docker environment 【发布时间】:2018-10-11 07:50:06 【问题描述】:使用 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 从 /var/app/current/assets
提供 /assets/
* 并将其余部分代理到 docker 容器?
由于 docker 环境,下面的内容不起作用。
option_settings:
"aws:elasticbeanstalk:container:python:staticfiles":
"/static/": "www/static/"
【问题讨论】:
您找到解决方案了吗? 【参考方案1】:总结一下我们在使用SolutionStackName: 64bit Amazon Linux 2 v3.2.0 running Docker
的 elasticbeanstalk docker 容器中运行的 django 提供静态文件的解决方案:
-
在容器真正准备就绪之前,我们不想运行
collectstatic
。为此,我们在 entrypoint.sh 中启动它,不久之后它也会启动 gunicorn。
我们让collectstatic
将静态文件从我们的设置中拖放到“static”中:
STATIC_ROOT = "static"
STATIC_URL = "/static/"
-
我们在
.platform/hooks/postdeploy
中配置一个部署后脚本,将静态文件从容器中复制到/var/app/current
中的ec2 vm(脚本运行的地方):
#! /bin/bash
docker cp $(docker ps --no-trunc -q | head -n 1):/home/app/static .
-
我们通过在
.platform/nginx/conf.d/elasticbeanstalk/custom.conf
中放置自定义配置文件来告诉 nginx 在哪里可以找到静态文件:
location /static/
root /var/app/current/;
就是这样。它对我们有用。
【讨论】:
只需要更改/home/app/static
否则就像一个魅力【参考方案2】:
我也遇到了同样的问题!解决方案是在服务器上的 /etc/sites-enabled/elasticbeanstalk-nginx-docker-proxy.conf 中自定义 nginx 配置。
基本上,我将该文件的内容复制到 .ebextension 配置文件中,并为静态文件夹添加了 location 指令。
所以你的 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 ~ "^(\d4)-(\d2)-(\d2)T(\d2)")
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/app/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;
这对我有用!
【讨论】:
这个答案不对! 当宿主卷被挂载时,它会挂载到容器中指定目录的内容之上。然后该目录的内容将不可用于主机。看到这个问题:***.com/questions/42848279/… 嗯......你知道它对我有用,这不仅仅是我说的。你试过了吗? 是的,我自己尝试过,当它不起作用时需要重新设计一些东西。您确定系统的行为方式与您描述的方式相同吗?例如,我在您的 EB Dockerrun 配置中看到主机上的静态目录是/var/app/current/assets
,但在您的 nginx 配置中,静态目录是 /var/current
。
也许您在 docker 中运行的 webapp 实际上是在为静态资产提供服务?
你是对的。这是一个错误,我已将实际路径更改为通用路径,显然是错误的。应该是/var/app/current/
。我会马上修改编辑【参考方案3】:
你想做的事情是不可能的。
您不能将/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。
【讨论】:
可以使用现有容器内容填充卷:docs.docker.com/storage/volumes/… 如果您启动一个创建新卷的容器,如上所述,并且容器在目录中有文件或目录要挂载(如上面的/app/),目录的内容被复制到卷中。 @SuneKjærgård 在您链接到的文档中,它解释说容器将使用目录的内容填充 新卷 - 然后可以在其他 容器。但是,它不会替换您已作为“共享”挂载到容器上的主机上的目录的内容。 @SuneKjærgård 这是我的终端的输出,我试图明确地证明我的观点:gist.github.com/topher515/e56430e7e0c12c2aa8b5aa30eb24bc97以上是关于在 Elasticbeanstalk Docker 环境中提供 Django 静态文件的主要内容,如果未能解决你的问题,请参考以下文章
无法将多容器 docker 部署到 ElasticBeanstalk
Docker 容器在本地工作,但在上传到 elasticbeanstalk 时不工作
如何在 Elasticbeanstalk 环境中运行的 docker 容器中承担 AWS 角色?
ElasticBeanstalk - 无法从私有 Docker Hub 存储库中提取 docker 映像
502 Bad Gateway nginx/1.14.1 elasticbeanstalk .net core app 在 docker 上运行