NGINX reverse proxy with SSL for Jupyter and TapChat
# update apt list
sudo apt-get update
# install essential packages
sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
# add gpg keys for the docker repository
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
# add the AMD64 docker repository
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
# update apt list
sudo apt-get update
# install docker
sudo apt-get install docker-ce
# verify that docker works
sudo docker run hello-world
apt install nginx
# Add certbot PPA
sudo add-apt-repository ppa:certbot/certbot
# Update package list
sudo apt-get update
# Install certbot
sudo apt-get install python-certbot-nginx
sudo nano /etc/nginx/sites-available/default
server_name domain.tld subdomain1.domain.tld subdomain2.domain.tld;
sudo systemctl reload nginx
sudo certbot --nginx -d domain.tld -d subdomain1.domain.tld -d subdomain2.domain.tld
sudo certbot renew --dry-run
root@kvm:~# systemctl list-timers
NEXT LEFT LAST PASSED UNIT ACTIVATES
Sun 2017-12-03 09:08:15 PST 1h 40min left Sun 2017-12-03 03:01:58 PST 4h 25min ago snapd.refresh.timer snapd.refresh.service
Sun 2017-12-03 09:12:01 PST 1h 44min left Sun 2017-12-03 03:01:58 PST 4h 25min ago apt-daily.timer apt-daily.service
Sun 2017-12-03 12:41:34 PST 5h 13min left n/a n/a certbot.timer certbot.service
Sun 2017-12-03 19:48:58 PST 12h left Sat 2017-12-02 19:48:58 PST 11h ago systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.service
4 timers listed.
Pass --all to see loaded but inactive timers, too.
# Default server configuration
#
server {
listen 80 default_server;
listen [::]:80 default_server;
# SSL configuration
#
# listen 443 ssl default_server;
# listen [::]:443 ssl default_server;
#
# Note: You should disable gzip for SSL traffic.
# See: https://bugs.debian.org/773332
#
# Read up on ssl_ciphers to ensure a secure configuration.
# See: https://bugs.debian.org/765782
#
# Self signed certs generated by the ssl-cert package
# Don't use them in a production server!
#
# include snippets/snakeoil.conf;
root /var/www/html;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name ipython.domain.tld subdomain1.domain.tld subdomain2.domain.tld;
location / {
# First attempt to serve request as file, then
# as directory, then fall back to displaying a 404.
try_files $uri $uri/ =404;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# include snippets/fastcgi-php.conf;
#
# # With php7.0-cgi alone:
# fastcgi_pass 127.0.0.1:9000;
# # With php7.0-fpm:
# fastcgi_pass unix:/run/php/php7.0-fpm.sock;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/ipython.domain.tld/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/ipython.domain.tld/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
# Redirect non-https traffic to https
# if ($scheme != "https") {
# return 301 https://$host$request_uri;
# } # managed by Certbot
}
server {
listen 80;
listen [::]:80;
server_name ipython.domain.tld;
error_log /var/log/nginx/jupyter_error.log;
access_log /var/log/nginx/jupyter_access.log;
location / {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location ~* /(api/kernels/[^/]+/(channels|iopub|shell|stdin)|terminals/websocket)/? {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/ipython.domain.tld/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/ipython.domain.tld/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
}
The location /
block forwards all incoming connections on the ipython.domain.tld domain to 127.0.0.1:8888 and adjusts the headers so that jupyter sees the packets as originating from the client instead of 127.0.0.1. The location ~* /(api/kernels/[^/]+/(channels|iopub|shell|stdin)|terminals/websocket)/?
block ensures that the websockets created by jupyter to communicate with the client browser get forwarded to the container.
sudo systemctl reload nginx
docker run --name jupyter -it -p 8888:8888 gcr.io/tensorflow/tensorflow
jupyter notebook password
Kill the docker container by pressing CTRL-C
. Launch it again in the background.
docker start jupyter
Open https://ipython.domain.tld and enter the password to access the workspace.
docker volume create --name tapchat-data
docker pull csmith/tapchat:latest
docker exec -i -t tapchat /bin/bash
cd .tapchat
cat tapchat.pem
exit
openssl x509 -noout -hash -in /etc/ssl/certs/tapchat.pem
# use the hash from the previous command in place of "deadbeef" below
ln -s /etc/ssl/certs/tapchat.pem /etc/ssl/certs/deadbeef.0
server {
listen 80;
listen [::]:80;
server_name irc.domain.tld;
error_log /var/log/nginx/tapchat_error.log;
access_log /var/log/nginx/tapchat_access.log;
location / {
proxy_pass https://127.0.0.1:8067;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# SSL upstream
proxy_ssl_trusted_certificate /etc/ssl/certs/tapchat.pem;
proxy_ssl_verify off;
# WebSocket support
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/irc.domain.tld/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/irc.domain.tld/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
if ($scheme != "https") {
return 301 https://$host$request_uri;
} # managed by Certbot
}