Scale up as you grow — whether you're running one virtual machine or ten thousand.

From GPU-powered inference and Kubernetes to managed databases and storage, get everything you need to build, scale, and deploy intelligent applications.

This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Let’s Encrypt now supports wildcard certificates. It would be great if you add a section to this tutorial about obtaining a wildcard certificate.
http://schalk.net pointed to my Nginx reverse proxy server that interfaced with my WebSockets server at ws://localhost:3055 inside my droplet. It ran smoothly in Firefox and Chrome, but I wanted more security; so I followed your excellent tutorial.
I was thrilled to see https://schalk.net running smoothly in my Chrome browser, but when I tried to load it in Firefox I got nothing. I pressed F12 and looked at the console. The first screenshot (below) shows an astonishing message that left me momentarily flabbergasted. By encrypting my site, I made it such a tremendous security risk - according to Firefox - that it was too dangerous to load in the browser.
I clicked the message and it took me to line 24 of my sources.js file, a file that Firefox apparently ignored on grounds that everything in the file must be a security risk. Line 24 read, " var socket = new WebSocket(‘ws://localhost:3055/’);". If I change that to “var socket = new WebSocket(‘wws://localhost:3055/’);” Firefox sees no security risk but WebSocket messaging becomes impossible since neither my Haskell backend server nor my Cycle.js front end is set up for WebSocket Secure messaging. I let the Nginx reverse proxy server take care of encryption.
My Bugzilla Mozilla report is at https://bugzilla.mozilla.org/show_bug.cgi?id=1468944. This bug is in versions 62 nightly builds, 61, 60 and I don’t know how far before that. I’m not holding my breath waiting for Firefox to do something, and it won’t help me with web surfers using pre-62 versions.
So, can you suggest any workarounds short of encrypting traffic between my Haskell server and Cycle.js front end? I took a stab at doing that and got frustrated. That’s why I was so overjoyed by your wonderful tutorial - so clear, so thorough, with magic results. Alternatively, can you steer me toward information about using Letsencrypt to secure my WebSocket server and Cycle.js front end?
Any help that you or the community can give me will be much appreciated. Thanks.
Wow! The procedure you presented was easy to follow and worked like a charm. Very impressive.
I do have a problem, though. Firefox, which loaded my page before I secured the Nginx reverse proxy server, now refuses to load it because of security concerns. Firefox found the file where I define my unencrypted WebSocket server running on localhost and concluded that it is a security threat. This is absurd, of course, but it might be a widespread problem. Every website with a non-secured WebSocket server secured by an encrypted reverse proxy server might be unavailable to people using Firefox browsers. The problem exists in Firefox version 62-daily-builds, 61, and 60. I don’t know about earlier versions.
Do you have any suggestions for a workaround? My application uses a Haskell server behind a Cycle.js front end bundled into the executable file by a Haskell compiler and uploaded to my droplet where it runs on localhost. The thought of transforming it into a WebSocket Secure application is daunting. I shouldn’t have to do that. My secure site loads and functions perfectly in Chrome.
I wrote a comment with specific details, including the URL for my site, but it was deleted by some amateurish spam detection system. Instead of flagging my comment for review, the system deleted it and gave me an email address where I could register an appeal. Treating customers with such disrespect is bad for business. I like Digitalocean and hate to see it messing up like that.
My comment has three screenshots that I dare not attach now lest I upset the automatic comment eraser. Maybe you can retrieve my detailed comment from wherever it went.
Any help from you or the community will be much appreciated. Thanks.
Make sure you get A Record for both versions of your site www.example.com and example.com!
I’m replying to bboucheron. Pressing “Re;ply” didn’t do anything.
I changed proxy_pass http://localhost.:3055; to proxy_pass http://schalk.net:3055; “socket” is defined as:
socket = "MozWebSocket" in window ? new MozWebSocket('ws://localhost:3055/') : new*
WebSocket('ws://localhost:3055/');
MDN’s “Writing WebSocket client applications” states: “In the above examples ws has replaced http, similarly wss replaces https. Establishing a WebSocket relies on the HTTP Upgrade mechanism, so the request for the protocol upgrade is implicit when we address the HTTP server as ws://www.example.com or wss://www.example.com.” – https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications". In context, it is clear that they mean “ws” suffices even for WebSocket Secure sites.
https://schalk.net functions perfectly in Chrome. Firefox has a new concern. In the Webpack bundle;js file, String.prototype.split is defined as native JavaScript String.prototype.split unless Regex is used in calling it. In that case, it appears that MIT licensed “Cross Browser Split 1.1.1” by Steven Levithan is used. Well, you guessed it, my application doesn’t finish loading in Firefox and the console explains “SecurityError: The operation is insecure”, as shown in the screenshot I will attempt to upload. Clicking the error line causes page 1818 of Bundle.js to be displayed. This is shown in another screenshot and also, in more detail, in the text file that I will try to upload.
I write “try to upload” because when I first left my two redundant messages they were immediately deleted by the spam robot. Digital Ocean was very good about republishing them, but I doubt that they have had sufficient time to substantially improve their spam software.
I am very grateful to you for helping me. I guess I should tell Webpack that Firefox thinks that altering String.prototype can be an “insecure” operation. I’m feeling a little insecure about developing websites that have to work in Firefox browsers. Do you or anyone else reading this think a hacker could make use of Webpack’s modified version of String.protocol.split?
I edited the bundle.js file produced by Webpack so String.prototype.split is no longer modified. Now loading of my app in Firefox stops when the definition of “socket” is reached. It is ordinary “ws”, not WebSocket Secure. My bundled Haskell server and Cycle.js front-end exchange unencrypted WebSocket messages inside my droplet. Users reach the app with the URL https://schalk.net, the address of my secure reverse-proxy Nginx server.
Chrome runs smoothly, but Firefox won’t finish loading. Here is the definition of “socket”: socket = “MozWebSocket” in window ? new MozWebSocket(‘ws://127.0.0.1:3055/’) : new WebSocket(‘ws://127.0.0.1:3055/’);
I’m not the only one having this problem, as is evident from:
https://www.google.com/search?ei=lysvW6efB6WLjwT4uYfICQ&q=mixed+content+blocking+https+“ws”&oq=mixed+content+blocking+https+“ws”&gs_l=psy-ab.12...21871.23660.0.24677.2.2.0.0.0.0.103.182.1j1.2.0....0...1.1.64.psy-ab..0.0.0....0.DopyQx_CZug
CAUTION
If have - like me - your domains (and associated dns, nameservers) sit behind a service like cloudflare, the above setup might need one more little tweak to avoid the headache of a redirect loop.
Basically I have the non-httpS endpoint redirect to httpS, and it got stuck in a redirect loop. But when I commented out the certbot and ssl stuff from my nginx server block, all was good. The root cause - at least for me - was that cloudflare provides its own ssl cert…so as Joe Fleming stated on his recent blog post: within cloudflare you need to “…switch the crypto config to Full SSL or Full SSL (Strict)…” (by default it usually is configured as “Flexible” (or something similar).
Reference: https://joefleming.net/posts/nginx-ssl-and-cloudflare/
Once I did that tweak in cloudflare all was good, and I was able to stop pulling my hair out, and live a happier day.
Big props to Joe Fleming for posting this solution on his blog (I’m surprised google didn’t bring up any other hits on this topic except for Joe’s)…and as always props to the digital ocean folks for posting these instructions!
Good news. My site ( https://schalk.net) works flawlessly in Chrome AND FIREFOX. Firefox was complaining about Webpack’s definition of String.prototype.split and secure Nginx reverse proxy server in front of unsecured WebSocket communication between my Haskell WebSockets server and Cycle.js. I thought this is what I originally had in /etc/nginx/sites-enabled/schalk.net but I don’t know what else I changed. I had a Warp server behind Index.html with scripts including the Webpack bundle.js file but that is currently stopped. Anyway, thank you for a great tutorial and here’s /etc/nginx/sites-enabled/schalk.net:
server {
# listen 80;
# listen [::]:80;
# listen 443;
# listen [::]:443;
root /var/www/schalk.net/html;
index index.html ;
server_name schalk.net;
location / {
# switch on logging
access_log on;
# redirect all HTTP traffic to http://127.0.0.1:3055
proxy_pass http://127.0.0.1:3055;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# WebSocket support (nginx 1.4)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_read_timeout 259200;
}
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/schalk.net/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/schalk.net/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
}
server {
if ($host = schalk.net) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
server_name schalk.net;
return 404; # managed by Certbot
}
I know very little about system administration. l uploaded my WebSockets/Cycle.js executable, put a little Upstart script in /etc/init, and my site went live on the Internet. It was like magic. I went back to writing project code and didn’t give Upstart a second thought.
Trying to run my executable, which is a Haskell-compiled WebSocket server / Cycle.js app combination, was a different story. The magic was gone. While trying to make it go live on the Internet, I wrote some nonsensical comments below. I meant well, but now I think reading my comments would be a waste of time. I will delete them when I figure out how.
Edit suggestion: Add step after adding the repository to sudo apt update. I had to run that for Ubuntu to see the python-certbot-nginx package