簡體   English   中英

如何在 Docker 容器中設置 SSL

[英]How to set up SSL in Docker container

恢復

我有一個Apache服務器在生產中運行兩個應用程序。 我想在 Docker 容器內實現由Nginx提供的 Django 中的其他應用程序。 架構如下:

User request --> Apache --> Nginx inside Docker --> Gunicorn inside Docker --> Django app inside Docker

在此處輸入圖像描述

我想要的是

我想實現SSL certbot certificate ,但我不知道應該如何使用 HTTPS 設置主機(Apache)和容器(Nginx)之間的通信。

  1. 我必須為 Apache 安裝 Certbot 證書,並且我可以為 Nginx 使用相同的證書?
  2. 主機中的 Apache 和容器中的 Nginx 之間的 HTTPS 重定向應該如何? .

我參考這篇文章,其中實現了類似的架構,不同之處在於 Apache 安裝在主機和 Docker 容器中,並且使用Certbot為兩台服務器創建的相同證書,但我不知道這是否相同的邏輯適用於不同的服務器,如 Apache 和 Nginx。

我有的

Apache 主機服務器配置文件

<VirtualHost *:80>
        ServerName app.com.co
        ServerAdmin webmaster@app.com.co

        ErrorLog /var/log/app_com_co/error.log
        CustomLog /var/log/app_com_co/access.log combined

        ProxyPreserveHost On
        ProxyPass        "/" "http://127.0.0.1:1300/"
        ProxyPassReverse "/" "http://127.0.0.1:1300/"
</VirtualHost>
 
# Apache SSL Relate things in host

<VirtualHost *:443>
       ServerName app.com.co
       ServerAdmin webmaster@app.com.co

       ErrorLog /var/log/app_com_co/error.log
       CustomLog /var/log/app_com_co/access.log combined

       # Enable/Disable SSL for this virtual host.
       SSLEngine on

       # Activate SSL for proxy
       SSLProxyEngine On

       # Disable certificate verification in communication between host and container
       SSLProxyVerify none
       SSLProxyCheckPeerCN off
       SSLProxyCheckPeerName off
       SSLProxyCheckPeerExpire off

       # Defines that The host will pass the Host: line from the incoming request to
       # the container instead of the hostname specified in the ProxyPass line.
       ProxyPreserveHost On
       ProxyPass        "/" "https://127.0.0.1:14443/"
       ProxyPassReverse "/" "https://127.0.0.1:14443/"

       # Self signed SSL Certificate file
       SSLCertificateFile /etc/letsencrypt/live/app.com.co/fullchain.pem
       SSLCertificateKeyFile /etc/letsencrypt/live/app.com.co/privkey.pem
       Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>

docker-compose.yml

version: '3.8'

services:
  nginx:
    build: ./nginx
    ports:
      - 1300:80
      - 14443:443
    depends_on:
      - backend
    networks:
      - backend-tier

  backend:
    expose:
      - 8000
    build:
      context: .
      dockerfile: ./Dockerfile
    restart: unless-stopped
    networks:
      - backend-tier
    depends_on:
      - db
      - redis
    volumes:
      - ./app_com_co/:/app/app_com_co:Z
      - ./app_com_co/templates/:/app/app_com_co/templates:Z
      # shared volume between worker, beat and backend for media
      - app-media:/app/app_com_co/media
    env_file: common.env

  db:
    image: library/postgres:11.1-alpine
    ports:
      - 5439:5432
    restart: unless-stopped
    networks:
      - backend-tier
    volumes:
      - app-db:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=myuser
      - POSTGRES_PASSWORD=mypassword
      - POSTGRES_DB=mydb

  redis:
    image: library/redis:5.0-alpine
    ports:
      - 6379:6379
    restart: unless-stopped
    networks:
      - backend-tier
    volumes:
      - app-redis:/data

  worker:
    build:
      context: .
      dockerfile: ./Dockerfile
    command: celery -A config --app=config.celery_app:app worker --loglevel=info
    restart: unless-stopped
    networks:
      - backend-tier
    env_file: common.env
    depends_on:
      - redis
    volumes:
      - ./app_com_co/:/app/app_com_co:Z,cached
      - ./app_com_co/templates/:/app/app_com_co/templates:Z,cached
      # shared volume between worker, beat and backend for media
      - app-media:/app/app_com_co/media

  beat:
    build:
      context: .
      dockerfile: ./Dockerfile
    command: celery -A config --app=config.celery_app:app beat --loglevel=info
    restart: unless-stopped
    networks:
      - backend-tier
    env_file: common.env
    depends_on:
      - redis
    volumes:
      - ./app_com_co/:/app/app_com_co:Z,cached
      - ./app_com_co/templates/:/app/app_com_co/templates:Z,cached
      # shared volume between worker, beat and backend for media
      - app-media:/app/app_com_co/media

volumes:
  app-db:
    driver: local
  app-redis:
    driver: local
  app-media:

networks:
  backend-tier:
    driver: bridge

Docker 容器內的 Nginx 配置

I'm not sure how to configure HTTPS connection in Nginx inside Docker container to receive https requests from Apache and then redirect to the DJango app.

upstream django {
    server backend:8000;
}

server {
    listen 80;

    location / {
        proxy_pass http://django;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_redirect off;
        client_max_body_size 4G;
    }
}

盡量讓你的容器保持無狀態,所以不要在容器內使用 certbot。 而是將 certbot 用於 Apache 或您在應用程序容器之外擁有的任何 web 服務器。

可以讓 Apache 在普通的 HTTP 中與您的應用程序容器對話,因為您的容器沒有公開 web (確保它只接受本地主機連接)。 許多人采取了更簡單的方法並將 Cloudflare 用於 SSL,這意味着從 http 到 https 的切換發生在離最終用戶更近的地方。

注意:這種使用反向代理處理 SSL 而不是您的應用程序的方法稱為“SSL 終止”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM