PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Thursday, September 1, 2022

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

 September 01, 2022     docker, docker-compose, lets-encrypt, nginx-reverse-proxy, streamlit     No comments   

Issue

I'm very new to server config so please excuse me if I don't explain something properly.

My current stack is Ubuntu 18.04 with Certbot, Nginx, and a Streamlit application all in separate Docker containers. Certbot is handling Letsencrypt ssl certificates for port 443, Nginx is using a reverse proxy on port 80 to my Streamlit application on port 8501. Streamlit natively uses port 8501.

I want to config everything so that I don't have port 8501 accessible. So my current site is https://joeysapps.com but someone could easily go to http://198.58.107.80:8501/ .

My docker-compose.yml looks like this:

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;'"

My Streamlit App's DockerFile looks like this:

# 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 . .

My Nginx conf looks like this:

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;
    }

}

When I use the Docker command: Docker ps I get this:

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 

Solution

If you do not want the port publicly accessible then remove this line from your docker-compose.yml:

    ports:
      - "8501:8501"

When you do this, docker binds port 8501 of the host to 8501 of the app container. See more info about ports directive.

Since you are starting all services inside the same project, they will (be default) create a private network all the containers can communicate on.

You then want to also modify the following from your 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/;

That should get you started.



Answered By - im_baby
Answer Checked By - David Marino (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing