简体   繁体   English

使用Traefik时如何使用Nginx和Django Gunicorn提供静态内容

[英]How to serve static content with Nginx and Django Gunicorn when using Traefik

I have a web application (Django based) that is utilising multiple containers: 我有一个使用多个容器的Web应用程序(基于Django):

  1. Web Application (Django + Gunicorn) Web应用程序(Django + Gunicorn)
  2. Traefik (acting as the reverse proxy and SSL termination) Traefik(充当反向代理和SSL终止)
  3. Database which is used with the Web application 与Web应用程序一起使用的数据库
  4. Redis which is used with the Web application 与Web应用程序一起使用的Redis

According to some of the documentation I have read, I should be serving my static content using something like NGINX. 根据我读过的一些文档,我应该使用像NGINX这样的东西来提供我的静态内容。 But I don't have any idea on how I would do that. 但我对如何做到这一点并不知情。 Would I install NGINX on my Web Application container or as a seperate NGINX container. 我会在我的Web应用程序容器上安装NGINX还是作为单独的NGINX容器安装。 How do I pass the request from Traefik? 我如何传递Traefik的请求? As far as I am aware you cannot server static content with Traefik. 据我所知,你无法使用Traefik服务静态内容。

This is what my docker-compose.yml looks like: 这就是我的docker-compose.yml的样子:

 traefik:
    image: traefik
    ports:
      - 80:80
      - 8080:8080
      - 443:443
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./traefik/traefik.toml:/etc/traefik/traefik.toml:ro
      - ./traefik/acme:/etc/traefik/acme

  web:
    build: .
    restart: always
    depends_on:
        - db
        - redis
        - traefik
    command: python3 /var/www/html/applications/py-saleor/manage.py makemigrations --noinput
    command: python3 /var/www/html/applications/py-saleor/manage.py migrate --noinput
    command: python3 /var/www/html/applications/py-saleor/manage.py collectstatic --noinput
    command: bash -c "cd /var/www/html/applications/py-saleor/ && gunicorn saleor.wsgi -w 2 -b 0.0.0.0:8000"
    volumes:
      - .:/app
    ports:
      - 127.0.0.1:8000:8000
    labels:
      - "traefik.enable=true"
      - "traefik.backend=web"
      - "traefik.frontend.rule=${TRAEFIK_FRONTEND_RULE}"
    environment:
      - SECRET_KEY=changemeinprod

  redis:
    image: redis

  db:
    image: postgres:latest
    restart: always
    environment:
      POSTGRES_USER: saleoradmin
      POSTGRES_PASSWORD: **
      POSTGRES_DB: **
      PGDATA: /var/lib/postgresql/data/pgdata
    volumes:
      - ~/py-saleor/database:/app

If anybody else needs an answer to this, the answer lies in creating a seperate NGINX service and then directing the front end rules to the static location (xyz.com/static), eg see below (part of docker-compose.yml): 如果有其他人需要答案,答案在于创建一个单独的NGINX服务,然后将前端规则指向静态位置(xyz.com/static),例如见下文(docker-compose.yml的一部分):

  nginx:
       image: nginx:alpine
       container_name: nginx_static_files
       restart: always
       volumes:
           - ./default.conf:/etc/nginx/conf.d/default.conf
           - ./saleor/static/:/static
       labels:
           - "traefik.enable=true"
           - "traefik.backend=nginx"
           - "traefik.frontend.rule=Host:xyz.co;PathPrefix:/static"
           - "traefik.port=80"

You also need to ensure that your Nginx config file (default.conf) is appropriately configured: 您还需要确保正确配置了Nginx配置文件(default.conf):

server {
   listen                      80;
   server_name                 _;
   client_max_body_size        200M;
   set                         $cache_uri $request_uri;

   location                    = /favicon.ico { log_not_found off; access_log off; }
   location                    = /robots.txt  { log_not_found off; access_log off; }
   ignore_invalid_headers      on;
   add_header                  Access-Control-Allow_Origin *;

   location /static {
       autoindex on;
       alias /static;
   }

   location /media {
       autoindex on;
       alias /media;
   }

   access_log                  /var/log/nginx/access.log;
   error_log                   /var/log/nginx/error.log;
}

All credit goes to Pedro Rigotti on the Traefik slack channel for helping me arrive at the solution. 所有功劳都归功于Traefik slack频道上的Pedro Rigotti,帮助我找到解决方案。

I don't have much idea about Traefik and Docker. 我对Traefik和Docker一无所知。

But I can tell you how you can install nginx and use it to serve static files(which is always recommended in order to not choke the django server by serving static files) 但我可以告诉你如何安装nginx并使用它来提供静态文件(为了不通过提供静态文件来阻止django服务器,总是建议使用它)

Install nginx and follow the steps mentioned to setup nginx . 安装nginx并按照提到的步骤设置nginx

sudo apt-get install nginx

The site-available file should look something like this: 站点可用文件应如下所示:

server {
        listen 80;
        listen [::]:80;

        server_name xyz.com;
        client_max_body_size 20M;

        # xyz.com/media/any_static_asset_file.jpg 
        # when anyone hits the above url then the request comes to this part.
        location /media/ {

                # do make sure that the autoindex is off so that your assets are only accessed when you have proper path

                autoindex off; 

                # this is the folder where your asset files are present.

                alias /var/www/services/media/; 
        }

        # whenever any request comes to xyz.com then this part would handle the request
        location / {
                proxy_pass http://unix:/var/www/services/xyz/django_server.sock;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
        }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM