I’M SO CLOSE! (deployment)

I’m so proud to be as close as I am to have a stable and secure web app. I am a student studying Finance and Economics so I’m not well versed in full stack development. I found out about streamlit about a month ago and fell in LOVE. I’ll keep this short.

I’m using nginx in a docker container as a reverse proxy to my streamlit app in another container. I’m hosting the server through linode and setup a rDNS through their Domain manager. Once I get letsencrypt working I will post all my code and make a few videos.

http://www.joeysapps.com

Ps. If the link isn’t working then I’m probably working on it or I forgot to pay my bills

1 Like

I got it working! https://joeysapps.com
I will write out the workflow soon.

1 Like

Hello @joeychrys, nice to see you got it working, I’ll be waiting for your breakdown post :slight_smile: !

(Firefox is angry at me for trusting your letsencrypt certificate but it is working indeed :wink: )

Fanilo :balloon:

1 Like

I will create a breakdown soon! Yeah I think the problem is that I don’t have www.joeysapps.com setup with a cert. I only have joeysapps.com setup. Firefox gives me the same problem :frowning:

Hi, I went to your app (congratulations btw, I’m very excited to have mine up and running as well), and found your code. I was wondering how you got it to work using https.

Hey there. I would love to help. I’ve been procrastinating on creating a full tutorial on how to get https working. Are you using Docker with streamlit and nginx?

Hi! yes sir. But with all honesty, although I have a fair understanding on what a single Docker container is doing and how you can deploy it, having two containers is something I attempted for the first time on my own, and I did use docker-compose to get things up and running. Here is my app btw.

My understanding is that nginx is something like a proxy that does the https trick but how?

So Nginx is a load balancer/web-server. Requests are first sent to nginx and then those requests are served to streamlit via a reverse proxy. Nginx handles the “three way handshake” that happens when a user makes a request to your server. I use letsencrpyt for the SSL certs that are needed for https. I then have a certbot container which handles auto renewal of the SSL certs. I followed this guide on how to get the certs running on the server.

Here is my current app.conf that is being used to configure nginx

server {

	listen 80;
	server_name example.com;

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

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

}
# I use upstream but its not needed.
# If you want to use it you can just change 
# "upstream {name_of_streamlit_container}"
upstream streamlit_app {
    server streamlit_app:8501;
}

server {

	listen 443 ssl;
	server_name example.com;

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

	# streamlit config
	location / {
		proxy_pass http://streamlit_app/;
	}

	location ^~ /static {
		proxy_pass http://streamlit_app/static/;
	}

	location ^~ /healthz {
		proxy_pass http://streamlit_app/healthz;
	}

	location ^~ /vendor {
		proxy_pass http://streamlit_app/vendor;
	}

	location /stream {
		proxy_pass http://streamlit_app/stream;
		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;
	}

}

Here is my docker-compose.yml

version: '3.8'

services:
  streamlit:
    container_name: streamlit_app
    restart: always
    expose:
      - "8501"
    build: ./streamlit_app
    command: streamlit run app_6.py

  nginx:
    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
    command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"

  certbot:
    container_name: certbot
    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;'"


Wow! Thank you so much. I’ll try it out and let you know how it worked out :slight_smile:

Alright sounds good. I’ve helped a few people get this working via the streamlit discord. I’m always happy to ssh into a sever and get this working. I know how confusing this can be (it took me months to understand all this) as you just want to be able to share a streamlit app and not worry about full stack development. If you need more hands on help, just hit me up through discord. My username is yoyojoe#5510.

2 Likes

Honestly, I was shocked I was able to put a web app of my own up and running in about a month. But now I want it to be perfect. And I spent hours searching online for this so thank you again!

P.S: I sent you a friend request on discord!

1 Like

I know the feeling oh too well. I’m in school right now so I don’t have as much time as I would like but I’m in the process of developing a template that someone can just clone and have everything they need for certs/nginx/streamlit. I’m trying to use cookiecutter for it.

1 Like

But you are defining a service - web which is not defined in your compose file.

Oh my bad. So I forgot to take that out. Web is a container that has a django application in it. I’ll take that out real quick. You can just remove that.

I did, but I still have no luck setting this up. But I would be completely hopeless without your hints so no worries :slight_smile:

Were you able to get dummy SSL certificates with letsencrypt? And who is your cloud provider(ex: Linode, AWS)?

I think I got the certificates yes. I’m not running on a cloud provider. I have a web server (Virtual Machine). And I’m out of my depth in general :frowning:

The containers seem to be running fine though. Anyway, I’ll be back to this tomorrow morning (its past midnight here). And I’ll mention what I did for others :slight_smile: