Skip to content

deltaepsilon/quiver-cms

Repository files navigation

quiver-cms

A CMS built on Angular, Firebase, Express and Node.

Installation

Quiver-CMS relies on Node.js, NPM, Yeoman, Grunt, Bower, Firebase, Mandrill, Redis, ImageMagick, TypeKit and Amazon Web Services S3.

  1. Install Node.js if necessary. You'll get NPM as part of the new Node.js install.
  2. Install Yeoman, Grunt and Bower. npm install -g yo bower grunt-cli
  3. Create a Firebase account and create a Firebase app. This will be your datastore.
  4. Create an AWS account, activate S3 and create an S3 bucket.
  5. Clone the repo. clone git@github.com:deltaepsilon/quiver-cms.git
  6. Navigate to the repo and install NPM and Bower dependencies. cd quiver-cms && npm install && bower install
  7. Install redis and ImageMagick.
  8. Copy /config/default.json to /config/development.json and again to /config/production.json.
  9. default.json contains the default config which will be overridden by development.json or production.json depending on your node environment. See more documentation at node-config.
  • Sign up for a GoogleMaps API account if you'd like to use public.maps.apiKey.
  • Sign up for a Disqus account to use public.disqus.shortname take advantage of Disqus comments.
  • Sign up for Amazon S3 and create your first bucket to use public.amazon.publicBucket. Also make sure to get Amazon keys and fill in the details at private.amazon.
  • Get your Firebase secret for private.firebase.secret.
  • Generate some gibberish for private.sessionSecret. The project does not currently use sessions... but it might.
  • You'll need Mandrill and Instagram api keys to use those services.
  • Add your VPS login details and deploy commands to private.server if you'd like to take advantage of grunt deploy for quick deploys. More on this later.
{
  "public": {
    "environment": "development",
    "firebase": {
      "endpoint": "https://my-firebase.firebaseio.com/quiver-cms"
    },
    "api": "https://my-site.com/api",
    "root": "https://my-site.com",
    "email": {
      "from": "TyrionLannister@westeros.com",
      "name": "Tyrion Lannister"
    },
    "imageSizes": {
      "small": 640,
      "medium": 1024,
      "large": 1440,
      "xlarge": 1920
    },
    "supportedImageTypes": ["jpg", "jpeg", "png", "gif", "tiff"],
    "supportedVideoTypes": ["mp4", "webm", "mpeg", "ogg"],
    "maps": {
      "apiKey": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    },
    "disqus": {
      "shortname": "my-disqus-shortname"
    },
    "amazon": {
      "publicBucket": "assets.westeros.com"
    },
    "structuredOrganization": {
      "@context": "http://schema.org",
      "@type": "Organization",
      "name": "Quiver CMS",
      "url": "https://dev.quiver.is",
      "logo": "https://dev.quiver.is/logo.png",
      "contactPoint": [{
        "@type": "ContactPoint",
        "telephone": "+1-801-867-5309",
        "contactType": "customer service"
      }],
      "sameAs": [
        "https://twitter.com/quivercms",
        "https://www.facebook.com/groups/123456/",
        "https://www.pinterest.com/quivercms/",
        "https://instagram.com/quivercms/"
      ]
    }
  },
  "private": {
    "firebase": {
      "secret": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    },
    "sessionSecret": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
    "mandrill": {
      "apiKey": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    },
    "instagram": {
      "clientId": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
      "clientSecret": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    },
    "amazon": {
      "accessKeyId": "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
      "secretAccessKey": "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    },
    "redis": {
      "dbIndex": 0,
      "ttl": 3600
    },
    "elasticSearch": {
      "host": "127.0.0.1",
      "port": 9200
    },
    "server": {
      "HostName": "server.my-remote-server.com",
      "Port": 22,
      "User": "admin",
      "IdentityFile": "~/.ssh/id_rsa",
      "destination": "/var/www/my-site-folder",
      "remoteCommand": "sh /var/www/my-site-folder/install"
    }
  }

}
  1. Set up your Firebase app's security rules. These are a work in progress, and you'll want to make sure that you understand Firebase security rules well before attempting to deploy this app into the wild. You'll find my rules in /security-rules.json.
  2. Start cms-server.js and content-server.js using either node or nodemon. You'll need two terminal windows. You'll run nodemon cms-server.js in the first and nodemon content-server.js in the second.
  3. I was originally using grunt serve to serve up my static files, but as the site got more complex I've switched to NGINX. Here's the configuration that I'm using. You'll need to change the paths to your snakeoil cert and key. You'll also need to edit /etc/hosts to redirect dev.quiver.is to 127.0.0.1. See /etc/hosts instructions.
server {
  listen 80;
  server_name dev.quiver.is;
  return 302 https://dev.quiver.is$request_uri;
}


server {
  listen	443;
  server_name dev.quiver.is;

  ssl on;
  ssl_certificate      /Users/quiver/development/quiver-cms/certs/snakeoil.crt;
  ssl_certificate_key  /Users/quiver/development/quiver-cms/certs/snakeoil.key;

  ssl_session_timeout 5m;

  ssl_protocols  SSLv2 SSLv3 TLSv1;
  ssl_ciphers  HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers   on;

  #rewrite_log on;

  location ~ ^/(app|images|lib|scripts|styles|views) {
    proxy_pass http://127.0.0.1:9800;
  }

  location ~ ^/api(/?)(.*) {
    proxy_set_header X-Real-IP  $remote_addr;
  	proxy_set_header X-Forwarded-For $remote_addr;
  	proxy_set_header Host $host;
  	proxy_pass http://127.0.0.1:9800/$2$is_args$args;
  }

  location / {
    proxy_set_header X-Real-IP  $remote_addr;
  	proxy_set_header X-Forwarded-For $remote_addr;
  	proxy_set_header Host $host;
  	proxy_pass http://127.0.0.1:9801;
  }


}


  1. If you're adventurous and don't want to run NGINS, run grunt serve from the quiver-cms directory and the app might run. You'll access the front end at http://localhost:9900. I don't think the back end will work with this deploy method.

Deploy Without Docker

Quiver-CMS is built for deploying to a VPS running linux. I recommend DigitalOcean, particularly their "MEAN on Ubuntu" image.

Once you have a VPS up and running, you'll need to install NGINX and install Node as well if you don't have it pre-installed with the "MEAN on Ubuntu" image.

Next install forever to daemonize content-server.js and cms-server.js.

You'll also need to configure NGINX to support multiple node processes.

Here's a sample config complete with a redirect to SSL. The SSL is not necessary, but it makes the entire operation much more secure.

server {
	listen 	80;
	server_name  quiver.is  *.quiver.is;
	return 301   https://quiver.is$request_uri;
}
server {
	listen 443 ssl;
	server_name quiver.is;

	keepalive_timeout   70;

  ssl_certificate      /etc/ssl/certs/quiver.crt;
  ssl_certificate_key  /etc/ssl/quiver.key;
  ssl_protocols  SSLv2 SSLv3 TLSv1;
  ssl_ciphers  HIGH:!aNULL:!MD5;
  ssl_prefer_server_ciphers   on;
  ssl_session_cache   shared:SSL:10m;
  ssl_session_timeout 10m;

	#rewrite_log on;

	client_max_body_size 2M;

	location ~ ^/(app|images|lib|scripts|styles|views) {
    proxy_pass http://127.0.0.1:9801;
  }

  location ~ ^/api(/?)(.*) {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    proxy_pass http://127.0.0.1:9801/$2;
   }

  location / {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header Host $host;
    proxy_pass http://127.0.0.1:9800;
  }

}


Deploy With Docker

Copy run.sh.dist and start.sh.dist without the .dist suffix into /bin. Edit both of those files to reference your development directory instead of mine. Then review the files within certs, /config and /nginx to make sure that they match your paths and your information. Once it looks good, run sh /bin/run.sh and hold your breath. Run docker ps to see if your instance is running and what it's called. Try to hit your dev site at https://dev.quiver.is or whatever domain you set up in /etc/hosts.

Known Issues

  • If you're having trouble with TypeKit, get rid of the following lines in index.html:
<script type="text/javascript" src="//use.typekit.net/bmk8cii.js"></script>
<script type="text/javascript">try{Typekit.load();}catch(e){}</script>

Then modify app/styles/theme/_font.scss so that $font-primary and $font-secondary are fonts names to which your page has access.

I've set up my TypeKit bundle to allow access for localhost and 127.0.0.1, but you'll run into issues if you attempt to load TypeKit fonts on your own domain.

Testing

Run grunt test

About

A CMS built on Angular, Firebase, Express and Node.

Resources

License

Stars

Watchers

Forks

Packages

No packages published