App Servers

How requests are served

When a request is forwarded from an ELB to an app server, the request first hits NGINX, an open-source HTTP/Reverse proxy server.

After NGINX receives the request, it proxies the request upstream to Phusion Passenger, an open-source web server which serves requests to your Workarea application concurrently on a number of threads.

Common web server tasks

While it's possible to use NGINX for redirects, basic authentication, and other common web tasks, we recommend that you do leave this up to Rack middleware or application code for portability, readability, and testability.

If your application requires advanced redirect logic or HTTP basic authentication, check out the rack-rewrite and workarea-basic_auth gems respectively.

Images and image processing

All application servers come with Imagemagick installed to perform resizing/processing work.

We don't store any images on app servers, aside from those found in your app's /assets/ directory.

Because images are not stored on an app server and are processed on the fly, it's important that all images are served with an asset_host or image_tag helper to ensure they use your environment's CDN.

Without putting your images behind the CDN, this can result in slow page load times and potentially act as a DDoS in cases where a large number of image processing jobs are triggered.

What happens when your application is deployed

Workarea applications are deployed using Chef, in a manner similar to how a Capistrano deploy works.

By default your app is deployed to /var/www/weblinc_direct, and the directory structure looks like this:

├── current -> /var/www/weblinc_direct/releases/A # Symlink to deployed git REF
├── releases                                                                          # Directory of current/past deploys
│   ├── A
│   └── B
└── shared                                                                                # Resources that are shared across deploys
    ├── bundle
    ├── log
    ├── pids
    └── system

Imagine we wanted to deploy the f00 git revision, the deploy process would look like:

  • Clone git revision to weblinc_direct/releases/f00
    • Quiet currently running Sidekiq processes found in weblinc_direct/current/tmp/pids
    • Template environment variables in .env file (Workarea V1 or less)
    • Template mongoid config (Workarea V2 or less)
    • Template Rails secrets
  • Symlink shared resources and weblinc_direct/releases/f00 => weblinc_direct/current
  • Prepare to restart the app
    • Run bundle config based off Environment config
    • Run bundle install
    • Run bundle exec rake rails:update:bin if weblinc_direct/releases/f00/bin is empty
    • Run bundle exec rake assets:precompile
    • Template /etc/nginx/sites-enabled/weblinc_direct NGINX configuration
  • Restart the app
    • Reload NGINX configuration
    • Restart Sidekiq through Monit
    • Run touch weblinc_direct/current/tmp/restart.txt to restart Passenger
  • f00 revision is now deployed.

Useful logs and commands for debugging

# See basic Passenger status
$ passenger-status

# See detailed information about Passenger threads
$ passenger-status --show=server

# NGINX Access Logs
$ tail -f /var/log/nginx/access.log

# NGINX Error Logs
$ tail -f /var/log/nginx/error.log

# Rails Logs
$ tail -f /var/www/weblinc_direct/current/log/staging.log

# Sidekiq Logs
$ tail -f /var/www/weblinc_direct/current/log/sidekiq.log