Using MUP to deploy a Meteor app alongside static sites via Nginx

Hey’all.

This is probably due to my own lack of knowledge around MUP and Nginx; I’ve used MUP over the years to deploy to VPS’s – but usually when the meteor app is all that’s on the VPS. Works flawlessly after getting through whatever nuances.

However, this time around, I’m trying to use MUP to deploy to a Ubuntu 22.04 VPS that already had Nginx hosting two static sites.

I’m a little baffled; but managed to deploy the MUP app after stopping Nginx due to port 443 in use.

I know the proxy block is my missing link, but I’m just not sure how to accomplish this. It’s a pretty simple problem – I’m sure there’s many MUP-deployed Meteor apps out there with static sites hosted alongside.

I can’t get Nginx to start via sudo service nginx start because of the app now running; and so I get the output below from sudo systemctl status nginx.service.

What do I have to do to make this work? There isn’t much documentation for MUP around using the proxy.shared.nginxConfig block; but assuming that’s what I need. :slight_smile: I tried combining all my previous static site /etc/nginx/sites-available/* configs into one file and referencing that for mup setup and mup deploy thinking some magic might happen.

Mar 19 05:01:18 jammy-bare nginx[20626]: nginx: [emerg] bind() to [::]:443 failed (98: Unknown error)
Mar 19 05:01:19 jammy-bare nginx[20626]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Unknown error)
Mar 19 05:01:19 jammy-bare nginx[20626]: nginx: [emerg] bind() to [::]:80 failed (98: Unknown error)
Mar 19 05:01:19 jammy-bare nginx[20626]: nginx: [emerg] bind() to 0.0.0.0:443 failed (98: Unknown error)
Mar 19 05:01:19 jammy-bare nginx[20626]: nginx: [emerg] bind() to [::]:443 failed (98: Unknown error)
Mar 19 05:01:19 jammy-bare nginx[20626]: nginx: [emerg] still could not bind()
Mar 19 05:01:19 jammy-bare systemd[1]: nginx.service: Control process exited, code=exited, status=1/FAILURE
Mar 19 05:01:19 jammy-bare systemd[1]: nginx.service: Failed with result 'exit-code'.
Mar 19 05:01:19 jammy-bare systemd[1]: Failed to start A high performance web server and a reverse proxy server.

Start your meteor app on a different port (lets say 3001) and then configure a proxy on your nginx pointing to that port:

location / {
    proxy_pass http://localhost:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }

Thanks @bordalix .

**I should clarify, I’m using a wildcard SSL so I’m using proxy.ssl.

Can you let me know where in my mup.js I specify port 3001? Is it under app.servers.one.env.PORT? I can’t seem to figure that piece out.

I have the following in /etc/nginx/sites-available/app.[my_domain] and symlinked to sites-enabled. It is referenced in mup.js under proxy.shared.nginxConfig (Assuming that’s correct)

server {
    server_name app.[my_domain];
location / {
    proxy_pass https://localhost:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }
} 

I’m running into the same issue I was earlier with trying 3001 in a few areas – app will run but static sites won’t, or vice versa (depending on if I have nginx running on the VPS).

Started TaskList: Start proxy
[my_vps] - Start proxy
[my_vps] x Start proxy: FAILED

	      ------------------------------------STDERR------------------------------------
	      ...
mup-nginx-proxy (54cb0d309bb398b45c59ad6ae2f67af0981349b399e4ac5d0bbd2e836b23adb4): Error starting userland proxy: listen tcp4 0.0.0.0:443: bind: address already in use.

Almost kind of got it.

I disabled the whole mup.js’s proxy block and could hit http://app.[my_domain]:3001 but couldn’t get it to 443 (while nginx is running). This doesn’t feel right or clean. :sweat_smile:

I’m missing something either with the nginx block or configuring mup.js correctly.

Okay, I got it, but man is it ugly.

I hope this helps anyone else in the future who Googles their way here.

(And if this is wrong, please tell me how to make it better :rofl:).

Objective: Host a Meteor app alongside a server running multiple static websites via Nginx using Mup.

Mup.js:
1.) Don’t use the proxy block; it spins up a Docker image that uses port 80 & 443 – thus Nginx on the VPS can’t run. Comment this out.
2.) Regardless of whether or not you’er using SSL, keep env.ROOT_URL in mup.js to “http://” (I’m using SSL via an AlphaSSL wildcard certificate that I purchased for this app and multiple static sites).
3.) Specify servers.one.env.PORT: to the port your app is running on (in my case, 3001).
4.) Specify env.PORT: to the port your app is running on (again, 3001 in my case).
5.) My Nginx config looks like this:

server {
       server_name app.[my_domain];
       ssl_certificate /etc/ssl/[my_cert_name].crt;
       ssl_certificate_key /etc/ssl/[my_key_name].key;
location / {
    proxy_pass http://localhost:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }

    listen [::]:443 ssl;
    listen 443 ssl;
}

server {
       listen 80;
       listen [::]:80;
       server_name app.[my_domain];

location / {
    proxy_pass http://localhost:3001;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_set_header Host $host;
    proxy_cache_bypass $http_upgrade;
  }

       return 301 https://app.[my_domain]$request_uri;
}

I noticed an error page in Chrome until the redirect kicked in; but probably because of cached results. Incognito, it loads up hastily.

Again, this does not feel clean/right whatsoever – so if someone has advice, please improve or tell me how to do this properly. :smile:

Hi @ryan-lgtm, Not sure if this assists, but might help others…
I have a Meteor app that shares a VPS with a Node Express API service

These two applications co-exist and I got that working using

proxy: {
        domains: 'whatever.io,www.whatever.io',
        ssl: {
          forceSSL: true,
          crt: "/path/to/your/SSL/bundle.crt", // this is a bundle of certificates
          key: "/path/to/your/private.key", // this is the private key of the certificate
        },
        shared: {
          // The port number to listen to for http connections. 
          // Set to 8080 as we need to share the server with RestAPI that runs on port 80
          httpPort: 8080,
          httpsPort: 443,
        }
      }

Hey @robgordon , thanks for this!

I’ll give it a shot while my app is still brand new. Definitely appreciate the “proper” mup.js way. :slight_smile: