Tutorial: Deploying meteor app on vps/dedicated/own production server
Foreword (skip it if you're in rush)
Hi there, I'm deploying for the first time a meteor app and it's not easy to have a straight forward explanation for the all process. I got a lot disturbed between different choices, wasting time with a heroku account creation, passenger and other noisy tools/documentations which seem to be made in order to discourage people and make them pay for services which solve a problem but add another layer of documentation/community who suggests you to add another npm package and so on...
This tutorial is inspired of this passenger tutorial combined with apache reverse proxy setup in a way that fit me better, simpler, more vanilla, without passenger.
This tutorial is destined to developers who...
- ...know how to manage a vps/dedicated server with apache2/nginx
- ...don't want to pay $29 estimated by an unclear price of usage/hour-Mb or whatever just to run a simple meteor app server
- ...are willing to pay to get hosted "easily and quickly" their app but... oh I forgot about the database, it's not included ?
- ...want to understand how to deploy a meteor app in a simple way, with regular unix/gnu/linux tools
- ...don't want obscure mix up services/packages like galaxy, passenger, heroku or other stuffs
- ...like to make something expandable in case they want to host other meteor apps in the future on the same server
Any feedback appreciated
I wrote this tutorial at first as a reminder for myself for the next time I'll be willing to deploy another application. I also think that it may be useful for someone else so I publish it and put some efforts for your eye/mind comfort.
I don't pretend to know better or what, I just digged my way with oldschool, simple and trusty tools in my opinion, I'm not really sure about the quality of this setup but it actually works for me
Don't hesitate to correct and suggest, tell me if the solution that I provide doesn't work for you, if something doesn't make sense, I'll update this tutorial consequently.
Tutorial (Start here if you're in rush)
Goal
At the end of this tutorial, you will have your meteor application deployed and running on a subdomain like https://myapp.domain.com, usable simply by typing the address on your browser and by the android client using Apache2/nginx on your vps/dedicated.
Oh and of course redirection http to https included, we're not living in the caveman days.
I've been writing this tutorial with that:
- Ubuntu 18.04.1 LTS (dedicated server)
- node 11.7.0
- npm 6.6.0
- meteor 1.8.0.1
- apache 2.4
- mongodb-server 3.6.3
Required stuff
At this point, I consider that apache2 and mongodb are already installed and running on your server with this configuration:
- db name: myapp
- db user: myapp (with myapp db access only)
- db port: 27017 (default)
- You have a domain name linked to your vps/dedicated server with the DNS record A, if you browse on https://mydomain.com you should see the content of
/var/www/html
(default Apache2 configuration or your current website)
Everything exclusively related to our meteor application myapp
will have the same name.
Step 1: Build your app, copy it and extract it
On your development laptop/raspberry pi/piratebox, whatever the thing your meteor app is developed on:
Build it and copy to the server
user@development ~/myapp $ meteor build --server-only ../myapp.tar.gz
user@development ~/myapp $ scp ../myapp.tar.gz [email protected]
Login to your server
user@development ~/myapp $ ssh [email protected]
[email protected]'s password:
Welcome to your god damn server (•̀ᴗ•́)و
server ~ $ ls
...
myapp.tar.gz
...
Then, let's extract it in a convenient place
By default on Ubuntu, apache2 uses /var/www/
folder, but of course it depends on your distros and stuffs. If you use arch linux, it's gonna be /srv
which make a certain sense. For other distro/OS I don't know.
user@server ~ $ sudo mkdir /var/www/myapp
user@server ~ $ sudo tar xzf ~/myapp.tar.gz -C /var/www/myapp
ok cool my friends, if you ls
, it looks like this:
user@server $ sudo ls /var/www/myapp
bundle/
user@server $ sudo ls /var/www/myapp/bundle
main.js programs README server star.json
Step 2: Prepare the environment
Ok now we are about to run nodejs with your 364 npm dependencies that will get updated regularly. Writting a javascript code which scan the directories arround, create files etc... is easier than stealing a lollipop to a kid.
(。_°)☆\(-_– )
We gonna create an user dedicated to the meteor app, with his app folder access only.
Create user myapp
user@server ~ $ sudo adduser myapp
Don't care about the password, let blank to disable it (no login possible unless by root/sudoer user) or generate a strong one, this user is not supposed to be used as a regular one, don't type your personal password or 1234.
Now we can change the owner to myapp
user
user@server ~ $ sudo chown -R myapp /var/www/myapp
login to myapp user
For convenience, I create a symbolic link in myapp's home
user@server ~ $ sudo su myapp
myapp@server /home/user $ ln -s /var/www/myapp ~/app && cd ~/app/bundle
myapp@server ~/app/bundle $
Alright, we're ready to rock now.
Step 3: Run the server ᕕ(ᐛ)ᕗ
install dependencies
myapp@server ~/app/bundle $ (cd programs/server && npm install)
run on port 3000
myapp@server ~/app/bundle $ PORT=3000 MONGO_URL=mongodb://myapp:password@localhost:27017/myapp ROOT_URL=http://localhost node main.js
Browse on http://mydomain.com:3000 and you should be able to use your application, of course, your app is not working over ssl (https/port 443) and you shouldn't let it as it is, but isn't it feeling good to finally see it working in production \\ ٩( ᐛ )و // ?
(⌐▨_▨) - Ok now you can kill it (ctrl+c) and come back to the regular user we will make a proper reverse proxy with apache2.
^C
myapp@server ~/app/bundle $ exit
user@server ~ $
reverse proxy setup on Apache2
- Enable these modules and restart apache2
user@server ~ $ sudo a2enmod proxy
user@server ~ $ sudo a2enmod proxy_http
More information here: Enabling Necessary Apache Modules
- Let's edit the apache default config to force redirection http to https:
user@server ~ $ sudo vim /etc/apache2/sites-enabled/000-default.conf
<VirtualHost *:80>
ServerName mydomain.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
[...]
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
[...]
RewriteEngine on
# main domain running php in /var/www/html
RewriteCond %{SERVER_NAME} = mydomain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
# your application domain
RewriteCond %{SERVER_NAME} = myapp.mydomain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
# another application ?
RewriteCond %{SERVER_NAME} = myapp2.mydomain.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
[...] and so on [...]
</VirtualHost>
- Configure reverse proxy for port 443 (https)
user@server ~ $ sudo vim /etc/apache2/sites-enabled/000-default-le-ssl.conf:
<IfModule mod_ssl.c>
<VirtualHost *:443>
ServerName myapp.mydomain.com
[...]
SSLProxyEngine On
ProxyPreserveHost On
ProxyPass /websocket ws://localhost:3000/websocket
ProxyPassMatch ^/sockjs/(.*)/websocket ws://localhost:3000/sockjs/$1/websocket
ProxyPass / http://localhost:3000/
ProxyPassReverse / http://localhost:3000/
</VirtualHost>
</IfModule>
- Restart apache2
user@server ~ $ sudo systemctl restart apache2
- Run your meteor server and get out of here
user@server ~ $ sudo su myapp
myapp@server /home/user $ cd ~/app/bundle
myapp@server ~/app/bundle $ nohup `PORT=3000 MONGO_URL=mongodb://myapp:password@localhost:27017/myapp ROOT_URL=http://localhost node main.js` &
nohup: ignoring input and appending output to 'nohup.out'
myapp@server ~/app/bundle $ exit
user@server ~ $ exit
user@development ~/myapp $ echo "[x] meteor application deployment" >> completed-tasks.txt
(∩`-´)⊃━☆゚.*・。゚You made it. ヽ(´▽`)ノ
Now you can browse on https://myapp.mydomain.com
Note: http://mydomain.com:3000 is still usable tho, but you can forbid the access with iptables
This spam is courtesy of @fulltimegeek! A real piece of shit who flags manual curation projects like @themadcurator because he's a spiteful cunt!!!
what're you talking about ?
Congratulations @bidetaggle! You have completed the following achievement on the Steem blockchain and have been rewarded with new badge(s) :
Click here to view your Board
If you no longer want to receive notifications, reply to this comment with the word
STOP
Vote for @Steemitboard as a witness and get one more award and increased upvotes!
Congratulations @bidetaggle! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Vote for @Steemitboard as a witness to get one more award and increased upvotes!