UFW + Nginx + Let's Encrypt + Streamlit 的正确使用流程是什么

What is the correct process of using UFW + Nginx + Lets Encrpyt + Streamlit

我是服务器配置的新手,所以如果我没有正确解释某些内容,请原谅。

我当前的堆栈是 Ubuntu 18.04,Certbot、Nginx 和 Streamlit 应用程序都在单独的 Docker 容器中。 Certbot 正在处理端口 443 的 Letsencrypt ssl 证书,Nginx 在端口 80 上使用反向代理到端口 8501 上的我的 Streamlit 应用程序。Streamlit 本机使用端口 8501。

我想配置所有内容,这样我就无法访问端口 8501。所以我当前的站点是 https://joeysapps.com but someone could easily go to http://198.58.107.80:8501/ .

我的 docker-compose.yml 看起来像这样:

services:
  app:
    container_name: app
    restart: always
    build: ./app
    ports:
      - "8501:8501"
    command: streamlit run app.py
  nginx:
    container_name: nginx_app
    restart: always
    image: nginx:1.15-alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./data/nginx:/etc/nginx/conf.d
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    depends_on:
      - app
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
  certbot:
    container_name: certbot_app
    image: certbot/certbot
    volumes:
      - ./data/certbot/conf:/etc/letsencrypt
      - ./data/certbot/www:/var/www/certbot
    entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"

我的 Streamlit 应用程序的 Docker文件如下所示:

# base image
FROM python:3.7

# streamlit-specific commands
RUN mkdir -p /root/.streamlit
RUN bash -c 'echo -e "\
[general]\n\
email = \"\"\n\
" > /root/.streamlit/credentials.toml'
RUN bash -c 'echo -e "\
[server]\n\
enableCORS = false\n\
" > /root/.streamlit/config.toml'

# copy over and install packages
COPY requirements.txt ./requirements.txt
RUN pip3 install cython
RUN pip3 install -r requirements.txt
COPY main.cae71b2a.chunk.js /usr/local/lib/python3.7/site-packages/streamlit/static/static/js/

# copying everything over
COPY . .

我的 Nginx 配置文件如下所示:

server {

    listen 80;
    server_name joeysapps.com;

    location / {
        return 301 https://$host$request_uri;
    }

    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }   

}

server {
    listen 443 ssl;
    server_name joeysapps.com;

    ssl_certificate /etc/letsencrypt/live/joeysapps.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/joeysapps.com/privkey.pem;
    include /etc/letsencrypt/options-ssl-nginx.conf;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;

    location / {
        proxy_pass http://172.17.0.1:8501/;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $host;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;
    }

}

当我使用 Docker 命令时:Docker ps 我得到这个:

PORTS
0.0.0.0:8501->8501/tcp, :::8501->8501/tcp
0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp
80/tcp, 443/tcp 

如果您不想公开访问端口,请从 docker-compose.yml:

中删除此行
    ports:
      - "8501:8501"

执行此操作时,docker 将主机的端口 8501 绑定到 app 容器的 8501。 See more info about ports directive.

由于您在同一个项目中启动所有服务,它们将(默认情况下)创建一个所有容器都可以在其上进行通信的专用网络。

然后您还想修改 nginx.conf 中的以下内容:

    location / {
        # proxy_pass http://172.17.0.1:8501/;
        
        # Use the name of the container. 
        # The docker network will perform DNS resolution for you.
        proxy_pass http://app:8501/;

这应该让你开始。