WOW! Moving this application (my new website and blog) to my Debian VPS was a little harder than I wanted and anticipated. Of course this was my first time publishing a Node app to production so some learning time was to be expected...
Getting Ready for Production
Before moving from PHP to Node on my server I had read several articles and posts about different set ups. I decided to move to NGINX from Apache as my web server. I have used Apache since my first FreeBSD server - about 15 plus years ago - but it was time to move forward to something faster and with a fun name. Another post will follow about this move later...
Since I already had NGINX up and running I just needed to adjust my website config to the following (real ports are not below but would be the port of your apps):
server {
server_name www.hirerandybacon.com;
location / {
proxy_pass http://localhost:<NODEJSPORT>;
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;
}
location /blog {
proxy_pass http://localhost:<NODEJSPORT>;
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;
}
}
Additionally, I went the lazy route and published all my web files as is from the raw project. I plan on building a Grunt script to help with this but for now it was all manual.
What didn't work
I tried several methods to get my node app up and running. First I installed forever figuring it would be the easiest way (and I have heard others talking about it). Running forever from the command line is as simple as (note: the NODE_ENV=production export is for my ghost blog):
NODE_ENV=production forever start app.js
The first issue I had found was a warning about sqlite3. Because of my recent work with node-webkit I figured I needed to do an actual npm install on the machine to compile SQLITE. I changed to the web directory of my project and ran:
npm install sqlite3
Of course this yeilded some random error messages about permissions and also one of interest. I was missing make. So installing make was needed:
sudo apt-get install build-essential
After running this, the base application started but now the ghost module was complaining about sqlite3 (the joys of developing on Windows and publishing to Debian). I changed to the ghost directory inside of my web/node_modules directory and ran the npm install sqlite3 command again.
Finally this worked without issue and I was excited. Time to set it up to run via the cron. Being the old school Unix guy I was (or maybe more accurately the lack of recent Unix experience) - I rushed to set up an init.d script.
I tried several init.d scripts from git and Google search results. It seemed each had an issue and did not work well with my flavor of Debian - Wheezy. Additionally, more errors were caused by creating the scripts on Windows and coping it to my Debian box. Turns out carriage returns were the cause.
What finally worked after a while...
After wasting some good football watching time with the init.d I decided to try something simpler from the Ghost docs - Supervisor. The installation and config was pretty easy.
sudo apt-get install supervisor
On step 2 - service supervisor start
I received the following a useless error message:
Error: Another program is already listening on a port that one of our HTTP servers is configured to use. Shut this program down first before starting supervisord.
Great! A quick google search though indicated I just needed to run this:
sudo unlink /var/run/supervisor.sock
After running the command and trying again, the service was running. I banged out a quick config for my node application and saved it to the config.d directory - /etc/supervisor/conf.d/ - (of course the real path below is a little different but you get the idea):
[program:hirerandybacon]
command = node /mysecrectpath/app.js
directory = /mysecrectpath
user = www-data
autostart = true
autorestart = true
stdout_logfile = /var/log/supervisor/hirerandybacon.log
stderr_logfile = /var/log/supervisor/hirerandybacon_err.log
environment = NODE_ENV="production"
Now I went to fire off the supervisor program via:
sudo supervisorctl start hirerandybacon
And instead of a running app I received the following error message:
hirerandybacon: ERROR (no such process)
"GRRR," said Randy. This required more Google searching which brought me to this solution:
supervisorctl reread
supervisorctl reload
FINALLY starting the program yields success and my site is now running. Or is it?
More Issues
I guess because I'm bored I decided to log into my blog and finish up my first post. I tired to log in and received no response until a toast popped up saying a server error had occurred.
I checked the supervisor log and of course there where no relevant log items. At this point I was tired and wanted to brutte force my way though this thing. I decided to try to run the Node app again via the command line but this time as the www-data user (you know the user I assigned the app to above). A quick change of the user via:
sudo su www-data
Firing up the app via:
NODE_ENV=production node app.js
And finally a useful error message. The database was opening in read only mode. Why? Because when I deployed my database, although I thought I had chown'd the data directory and db to the :www-data group I hadn't changed permissions... After changing the permissions on the data directory (775) and database (664) and restarting my app, I was in business.
After a few hours (or maybe an evening) my node app and blog is running in production. I guess the plus side is I had another topic to blog about.