【问题标题】:Serving static files with nginx located in another docker container使用位于另一个 docker 容器中的 nginx 提供静态文件
【发布时间】:2017-07-18 14:14:31
【问题描述】:

刚开始,我见过this。但是他/她使用build,而我使用image

我有一个 docker-compose 文件,它将我之前制作的图像拉到我的服务器上。

app:
  restart: always
  image: some-app-image:latest

nginx 配置

location /static/ {
    root /data/app/web_interface;  <--- this exists in some-app-image container
}

通常,我会在包含静态文件的应用映像上安装一个卷。

但是,这变得多余,因为应用程序容器本身就有静态文件。

所有 nginx 容器需要做的就是“对等”到应用程序容器并提供这些静态文件。喜欢:

location /static/ {
    root http://app:8000/web_interface;
}

location /static/ {
    root app/web_interface;
}

有没有办法从 nginx 容器中提供位于另一个容器中的静态文件?

【问题讨论】:

  • 您的容器设置有点不清楚。您有一个 nginx 容器作为反向代理,已经从您的 app 容器(虚拟主机)提供数据?为什么app 容器不能提供自己的静态文件?
  • 我让 nginx 提供静态文件,因为我不希望 gunicorn 服务器处理它们。 stackoverflow.com/a/13947418/5779280
  • 要明确一点:应用程序容器运行 gunicorn,而您的 nginx 容器通过 uwsgi_pass 提供服务?
  • 或多或少,具体来说是proxy_pass

标签: nginx docker static


【解决方案1】:

我过去的所有想法:

从应用程序到 nginx 共享 docker 卷

您可以在应用程序的Dockefile 中创建一个卷,并在容器运行时复制到静态文件中。然后使用volumes_from 与 nginx 容器共享卷。如果您的应用程序depends_on nginx,这有点难看并且根本不起作用。我会说这是绝对不行,因为它在扩展您的应用容器时非常有效。

将静态文件从主机映射到 nginx 容器的想法也不是最佳的。你将有一个额外的奇怪步骤来处理它们。

单独的静态容器

构建另一个仅服务于不同虚拟主机上的静态文件的 nginx 容器。 static.foo.bar.

使用 CDN

那里有大量的 CDN,您可以放置​​您的静态文件,并且大多数框架都有用于处理这些的插件。我有一些项目这样做。效果很好。

使用 uWSGI

您可以使用--static-map 为 uWSGI 提供静态文件。见docs。这就是我最终所做的,因为它既便宜又简单……而且在扩展方面很友好。那么你可能还需要使用http-socket 所以uWSGI 会使用http。

【讨论】:

  • 您好,感谢您的回答。我喜欢 CDN 选项,但是我们需要快速行动,而且我觉得这需要比 uWSGI 解决方案更长的时间来设置。我一直认为从应用程序服务器提供静态文件是不行的。我猜这个方法已经进化了。
  • 我会说从应用服务器提供静态文件不是最佳选择,但不一定是坏事。如果您需要快速移动,这是一种安全且简单的方法。它只是工作。 php 已经这样做了很多年了。
  • 不是很清楚,但是您提到的选项之一(您不推荐的选项)似乎描述了my solution。你能详细说明吗?在什么情况下我会遇到问题?究竟是什么问题?
  • 我同意——为什么应用程序和 nginx 之间的 docker 卷在这里不好?
  • 在我看来,在集群环境中运行时会变得过于混乱,但对于 docker,我可能是个纯粹主义者。
【解决方案2】:

这是一个很晚的答案,但添加它以防其他人发现。

也许您可以利用服务器缓存,以便 NGINX 在第一次请求被代理的应用程序后有效地从其文件系统提供静态文件。

Here is a good guide to caching with NGINX

您可以将 inactive 标志设置为很长时间,因为资产是静态的。


基于上述指南的基本示例:

proxy_cache_path /path/to/cache levels=1:2 keys_zone=my_cache:10m max_size=10g inactive=30d use_temp_path=off;

server {
  ...

  location /static {
    proxy_cache my_cache;
    proxy_pass http://app:8000/static; # <--- wherever static files are on app server
  }

  ...
}

【讨论】:

    【解决方案3】:

    其中一种解决方案是在app 服务启动时将资产复制到共享卷:

    docker-stack.yml:

    volumes:
      docroot:
    services:
      site:
        volumes:
          - docroot:/docroot
      nginx:
        volumes:
          - docroot:/docroot
    

    app 服务的entrypoint.sh:

    #!/usr/bin/env sh
    rsync -a --delete --exclude /uploads public/ /docroot
    # start the site
    

    WORKDIR 位于/app。 docroot /app/public。这里我另外让它不复制uploads dir。

    更多信息here

    【讨论】:

      【解决方案4】:

      我做了类似但不同的事情:

      我让 docker-compose 运行两个容器:nginx 和 flaskapp。我让 nginx 容器提供静态请求并将其余请求转发到烧瓶应用程序。这是我的 nginx 配置(flaskapp.conf):

      server {
      listen 80;
      server_name $SERVER_NAME;
      
      location ^~ /static/  {
          include  /etc/nginx/mime.types;
          root /;
      }
      
      location / {
          proxy_set_header Host $host;
          proxy_pass http://frontend:8000;
      }
      }
      

      以及我的 nginx 容器的 dockerfile:

      FROM nginx
      
      RUN rm /etc/nginx/conf.d/default.conf
      RUN mkdir static
      COPY /static/ /static/
      COPY flaskapp.conf /etc/nginx/conf.d/
      

      我复制了一个包含我需要的资产的静态文件夹,现在我可以将它们加载到前端。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-17
        • 2019-02-22
        • 2018-12-05
        • 2023-03-05
        • 1970-01-01
        • 1970-01-01
        • 2016-05-23
        • 2014-07-25
        相关资源
        最近更新 更多