Skip to content

Latest commit

 

History

History
175 lines (113 loc) · 7 KB

deployment.md

File metadata and controls

175 lines (113 loc) · 7 KB

Hoodie Deployment Guide

Note that this is a incomplete draft. It should get you going with production system, but there is no guarantee that there isn’t anything wrong with the setup form a performance or security perspective. Please check with your local sysadmin to make sure and please let us know if we can improve anything :)

This guide is for Linux only at this point. Other UNIXes should be covered too, with slight modifications.

Install Dependencies:

  • Install CouchDB 1.2.0 or later, 1.4.0 or later recommended for performance.
  • Install NodeJS 0.10.0 or later.
  • Install nginx, any recent version will do.
  • Install Monit, any recent version will do.
  • Install git.

Set Up

CouchDB:

Hoodie is in development mode by default and there it starts its own CouchDB instance to manage. For production deployments, we recommend running CouchDB in a separate instance for various reasons like operational simplicity and security.

We assume you set up CouchDB with your package manager or manually following the installation procedure documented in the CouchDB source tree in the INSTALL.Unix file.

If you are already using CouchDB for other things, recommend starting a second instance of CouchDB that is completely separate from your original one. See below* for instructions.

For now we assume, your CouchDB is available at http://127.0.0.1:5984/

Create a CouchDB admin user called “admin” with a strong password of your choice at http://127.0.0.1:5984/_utils/ by clicking on the “Fix this” link in the lower right corner. Remember that password.

Next we want to change CouchDB’s default configuration on a few points. The easiest thing is to go to http://127.0.0.1:5984/_utils/config.html and edit the following fields (double click the value to get into the editing mode):

couchdb -> delayed_commits: false
couchdb -> max_dbs_open: 1024
couch_httpd_auth -> timeout: 1209600 ; that’s two weeks

System

Add this to /etc/security/limits.conf:

hoodie    soft    nofile    768
hoodie    hard    nofile    1024

Hoodie

Create a new system user:

useradd --system \
       -m \
       --home /home/hoodie \
       --shell /bin/bash \
       --no-user-group \
       -c "Hoodie Administrator" hoodie

This will create a new user and its home directory /home/hoodie.

cd in to that directory.

As user Hoodie, install your application, either with Hoodie’s application template function:

[sudo -u hoodie] hoodie new appname githubname/reponame # think https://github.com/githubname/reponame

Or via a git checkout and manual setup

[sudo -u hoodie] git clone repourl appname
# make sure package.json has a valid `name` property.
[sudo -u hoodie] npm install

To start, copy over the script from this gist: https://gist.github.com/janl/b097f7a578ec07e4101c

wget https://gist.githubusercontent.com/janl/b097f7a578ec07e4101c/raw/01ab9816f64660075e6fe9e5a787545097f22da8/hoodie-daemon.sh
chmod +x hoodie-daemon.sh

It is meant to be run as root. It is also an early version of what should eventually be an init.d script should be, but we are not there yet, so bear with us :)

To launch Hoodie now, do this, as root:

HOODIE_ADMIN_PASS=yourcouchdbadminpasswordfromearlier ./hoodie-daemon.sh start

That’s it! You can check if the setup was correct by checking the log files:

tail -f /home/hoodie/log/*

If you see any errors, check if you missed any steps from above. Let us know if you get stuck.

Your Hoodie app should now be running on http://127.0.0.1:6001/

WWW

You likely want your Hoodie app to be listening on port 80 and maybe even have it available under a regular domain. The domain mapping is out of scope for this setup, but listening to port 80 can be done. On UNIX, non-admin users can’t run programs that bind to ports under 1024. But instead of running Hoodie as root, which we’d consider a security hazard. DO NOT RUN HOODIE AS root.

Instead we use some software that is battle tested and gives us a bonus feature that we think you are going to like.

We will be using nginx as an HTTP proxy. Other HTTP proxy software should be equally suitable, Apache 2, HAProxy are just two that came to mind. We are going with nginx because our hosting provider offers support for it, so we are going with that :)

We add a new file /etc/nginx/vhosts.d/appname.conf with the contents of https://gist.github.com/janl/2a8e6ebc80a25817dca0

You will need to adjust the domain name and paths to log files and SSL certificates and keys.

NOTE: Due to an issue with SSL session termination, we recommend using HAProxy to do the SSL termination in front of nginx. Example configuration will be added later.

Once this is all set up, you can reload the nginx configuration:

[sudo] nginx reload

Now your app should be available on the public IP for that machine and from any domains that point to that domain. All requests should be automatically forwarded to HTTPS for security. DO NOT RUN HOODIE WITHOUT HTTPS.

The Bonus Feature

Now all your app’s request will be served over HTTPS. nginx terminates the HTTPS and proxies to Hoodie over HTTP. We also told nginx to server / from your app’s /www directory and proxy only /_api to Hoodie instead of letting Hoodie serve the static files and the dynamic backend.

This has the advantage that in case of an issue with Hoodie, your clients will still be able to request all the static assets and should largely still be able to use your application. This is a big benefit of an offline-first architecture: Your users can keep using your app, even if the backend is down. While the design is meant for users to be offline, it also allows backends to be offline :)

logrotate

We’ve set up a bunch of log files, you will want to make sure you don’t run out of space. Let’s set up log rotation in /etc/logrotate.d/hoodie:

/var/log/hoodie.std* {
       weekly
       rotate 10
       copytruncate
       delaycompress
       compress
       notifempty
       missingok
}

Monit

Finally, we want to make sure that Hoodie stays up in healthy even if the main node process terminates for whatever reason. We are using Monit to watch and restart Hoodie on demand.

Create /etc/monit.d/hoodie with:

check process hoodie with pidfile /home/hoodie/log/hoodie.pid
  start program = "/home/hoodie/hoodie-daemon.sh start"
  stop program  = "/home/hoodie/hoodie-daemon.sh stop"
  if failed URL https://yourapp.com/_api then restart

Again, adjust with your app’s domain. This will restart if the /_api endpoints (Hoodie’s main API) is not available.

While we are here, we set up the same thing for nginx:

/etc/monit.d/nginx check process nginx with pidfile /var/run/nginx.pid start program = "/etc/init.d/nginx start" stop program = "/etc/init.d/nginx stop" if failed host 127.0.0.1 port 80 then restart if failed host 127.0.0.1 port 443 then restart

*Set up a secondary CouchDB instance

TBD