Updated Guide: Weewx, Nginx, Belchertown, MQTT/WS


Nginx… a web daemon that seemingly can do everything, well, just about everything web-related. In this segment, as we’ve already installed Nginx above, we’ll need to add and modify some Nginx files to make the Belchertown stuff function.

Your nginx.conf in /etc/nginx/nginx.conf should look like this…

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    tcp_nopush      off;
    keepalive_timeout  65;
    gzip  on;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*.conf;

Create a file within /etc/nginx/sites-available/ named weewx.conf.

Add this to weewx.conf:

NOTE: Replace weewx.yourdomain.com with your website name. Preferably as a subdomain; wx.somedomain.com, weather.somedomain.com, whatever.thebestdomain.biz. You will need to do the same for weewx-socket.yourdomain.com – however, the domain name will need to be different than the main weather sub-domain name. It’s best to keep it as weewx-socket for sanity.

NOTE: Modify in the upstream/appserver segment. This is telling where to direct the websockets traffic to internally. Typically, you want this IP to be the same as the weewx machines IP. If it’s a public/WWW IP, put it there, otherwise if you’re behind a firewall with a VLAN/LAN routing scheme active, you’re going to use a LAN based IP here.

With the config file below, I intentionally do not redirect the weewx-socket domain from http to https. There’s really no need to do this, unless you’ve misconfigured something on weewx’s mqtt stuff. But internally, i take the https traffic, and send it over http on the local machine – why bother with multiple cert locations when a central service does it all for me? 🙂

server {
        listen 80;
        listen [::]:80;
        server_name weewx.yourdomain.com;
        return 301 https://$server_name$request_uri;

server {
        root /var/www/html/weewx;
        access_log /var/log/nginx/weewx.access.log;
        error_log /var/log/nginx/weewx.error.log;
        listen 443 ssl http2;
        listen [::]:443 ssl http2;
        server_name weewx.yourdomain.com;
        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;

# For Websockets / mosquitto.
map $http_upgrade $connection_upgrade {
    default upgrade;
    '' close;

upstream appserver {
server {
        server_name weewx-socket.yourdomain.com;
        listen 443 ssl;
        access_log /var/log/nginx/weewx.mqtt.access.log;
        error_log /var/log/nginx/weewx.mqtt.error.log;
        location / {
                proxy_pass http://appserver;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection "Upgrade";
                proxy_set_header Host $host;
                proxy_read_timeout 86400;

Save that file, and link it to the /etc/nginx/sites-enabled/ directory.

ln -s /etc/nginx/sites-available/weewx.conf /etc/weewx/sites-enabled/weewx.conf

Restart nginx: service nginx restart

We’ll add the SSL certs in a moment to the weewx.conf file.

Let’s Encrypt

Next, we’ll be setting up Let’s Encrypt for your domain or subdomain, or both – up to you. We’ll need SSL for Websockets to function.

If you set up the domains individually, with no wildcard, this process is generally pain and stress-free, if you go the wildcard domain route (eg: *.potatoforinter.net) you’ll likely have a two-stage auth system to validate the wildcard domain – which can sometimes be quite problematic if you do not run your own DNS Resolver for your domain name (Nginx verification plus DNS verification).

Once you have your vhost for nginx above all saved, let’s get our own certificate(s)!

Option One: Two certificates for two subdomains (easiest):

  1. certbot run --agree-tos --nginx -d weewx.yourdomain.com
  2. certbot run --agree-tos --nginx -d weewx-socket.yourdomain.com

Option Two: Wildcard domain and the main domain. This step WILL require manual intervention about every 90 days to make function (Web Server tweaking and DNS TEXT record additions), but the plus side is that you can have as many whatever-sub-domains-to.yourdomain.com due to the wildcard!

  1. certbot run --agree-tos --manual -d *.yourdomain.com,yourdomain.com

With Option One, you should get a notification if you’d like for cert bot to automatically modify the nginx vhost for your SSL details – press 1, and let it do its thing.

If you wish to begin the SSL cert auto-renew process, check out this blog post here: https://www.tmn.io/posts/lets-encrypt-with-nginx-auto-renewal