0

So after three weeks of 12hr shifts I am almost done with building a Knowledge Base system using Apostrophe. Now comes the task of speeding things on the front end. My questions are:

  1. How do I add expires headers: Express has inbuilt milddleware called static, can I just implement it normally under the index.js file?
  2. Minify JavaScript & CSS: http://apostrophecms.org/docs/modules/apostrophe-assets/ I saw that apostrophe has something inbuilt but its not clear how to enable it? And also do I need to put the assets in specific folder for it to work? Right now I have all the JS files under lib/modules/apostrophe-pages/public/js and CSS under public/css.
  3. Enable GZIP on the server: there is nothing mentioned but again express does have gzip modules can I just implement them under lib/modules/apostrophe-express/index.js?

Any help will is greatly appreciated.

Parik Tiwari
  • 1,525
  • 1
  • 12
  • 19
  • After reading the documentation http://apostrophecms.org/docs/tutorials/intermediate/deployment.html I added the code minify: true. And I had to move all the css files under the apostrophe-assets/public/css folder. Now when I start the server I see – Parik Tiwari Nov 04 '16 at 22:34
  • `[nodemon] starting 'node app.js' MINIFYING, this may take a minute... undefined [ 'Broken @import declaration of "/css/bootstrap.css"', 'Broken @import declaration of "/css/app/font-awesome.css"', 'Broken @import declaration of "/css/app/jquery.autocomplete.css"', 'Broken @import declaration of "/css/app/style.css"', 'Broken @import declaration of "/css/app/simple-sidebar.css"' ] [nodemon] app crashed - waiting for file changes before starting...` – Parik Tiwari Nov 04 '16 at 22:36
  • Actually never mind, it only takes less files as input. I was trying to add the css files and that was the issue. Once I changed the files to be less it started working fine. – Parik Tiwari Nov 04 '16 at 23:01

1 Answers1

2

I'm the lead developer of Apostrophe at P'unk Avenue.

Sounds like you found our deployment HOWTO with the recently added material about minification, and so you have sorted out that part yourself. That's good.

As for expires headers and gzip on the server, while you could do that directly in node, we wouldn't! In general, we never have node talk directly to the end user. Instead, we use nginx as a reverse proxy, which gives us load balancing and allows us to deliver static files directly. nginx, being written in C/C++, is faster at that. Also the implementations of gzip and TLS are very much battle-tested. No need to make javascript do what it's not best at.

We usually configure nginx using mechanic, which we created to manage nginx with a few commands rather than writing configuration files by hand. Our standard recipe for that includes both gzip and expires headers.

However, here's an annotated version of the nginx configuration file it creates. You'll see that it covers load balancing, gzip and longer expiration times for static files.

# load balance across 4 instances of apostrophe listening on different ports
upstream upstream-example {
  server localhost:3000;
  server localhost:3001;
  server localhost:3002;
  server localhost:3003;
}

server {
  # gzip transfer encoding
  gzip on;
  gzip_types text/css text/javascript image/svg+xml
    application/vnd.ms-fontobject application/x-font-ttf
    application/x-javascript application/javascript;

  listen *:80;

  server_name www.example.com example.com;

  client_max_body_size 32M;

  access_log /var/log/nginx/example.access.log;
  error_log /var/log/nginx/example.error.log;

   # reverse proxy: pass requests to nodejs backends        
  location @proxy-example-80 {
    proxy_pass http://upstream-example;

    proxy_next_upstream error timeout invalid_header http_500 http_502
  http_503 http_504;
    proxy_redirect off;
    proxy_buffering off;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
  }

  # Deliver static files directly if they exist matching the URL,
  # if not proxy to node
  location / {
    root /opt/stagecoach/apps/example/current/public/;
    try_files $uri @proxy-example-80;
    # Expires header: 7-day lifetime for static files
    expires 7d;
  }
}
Tom Boutell
  • 7,281
  • 1
  • 26
  • 23