top
(README.md)
# VOKAL Image Proxy

[![line cvr](https://cvr.vokal.io/vokal/vip/shield.svg)](https://cvr.vokal.io/vokal/vip) [![Build Status](https://drone.vokal.io/api/badge/github.com/vokal/vip/status.svg?branch=master)](https://drone.vokal.io/github.com/vokal/vip)

`vip` is an image proxy designed for easily resizing and caching images.


## Usage

### Getting resized images

Images are served up with a URI that contains a bucket name, as well as a unique identifier for the image: `http://images.example.com/mybucket/5272a0e7d0d9813e21`.

When images are requested they are placed into an in-memory cache to make repeated requests for that image faster.

You can resize an image on the fly by providing an `?s=X` parameter (where `X` is an integer) that specifies a maximum width for the image in pixels. Resized images may also be center-cropped by passing `?c=true` in the querystring. The resized image or thumbnail will then be cached to both `groupcache` and S3. If the image leaves the in-memory cache it will not need to be resized again.

For example:
- If you want to resize an image down to a 500 pixel size:  
  `http://images.example.com/mybucket/5272a0e7d0d9813e21?s=500`
- If you needed a square thumbnail of the same image:  
  `images.example.com/mybucket/5272a0e7d0d9813e21?s=160&c=true`. 

For performance reasons, `vip` has a configurable maximum width, set via the environment variable `VIP_MAX_WIDTH`. You'll want to balance your own app's needs with memory needed to cache larger images, though the default max is a reasonable 720 pixels.

### Uploading images

Images are uploaded through `vip` to generate the serving URL. Upload requests should have the raw binary data of the image encoded as the body. `Content-Type` and authentication headers will also need to be provided. The route for uploads is: `images.example.com/upload/mybucket`.

This will upload the supplied image into an S3 bucket named `mybucket` and return a JSON-encoded serving URL:
```json
{
    "url": "http://images.example.com/mybucket/5272a0e7d0d9813e21"
}
```

You can also limit the maximum filesize that `vip` can accept by specifying `VIP_SIZE_LIMIT` in megabytes (e.g. `VIP_SIZE_LIMIT=10`). The default is 5MB, which is generally sufficient for JPEG photos from most mobile devices.

### Pre-warming the cache

For mobile clients that use one or more common sizes, those sizes can be cached in the background while uploading a new image. Simply set a comma-delimited list of query parameters for each expected size in a `X-Vip-Warmup` header:
```
X-Vip-Warmup: s=250&c=true,s=500,s=1024
```
This will automatically generate a 250x250px thumbnail, as well as 500px wide and 1024px wide versions of the uploaded image, and all three will be ready in the cache for immediate retreival.


## Deployment

`vip` can be deployed with Docker:

        $ docker run -e AWS_SECRET_ACCESS_KEY=... \
            -e AWS_ACCESS_KEY_ID=... vokal/vip

It is recommended that you deploy `vip` behind SSL and with an authentication token. This
token can be generated by your own application, but should be used by clients when uploading.

Authentication is only checked during uploads. The expected format for authentication is in the
`X-Vip-Token` header:
```
X-Vip-Token: c5411c3aac6f2c6d55a1fdc2d0a98c49
```

To set the token for your deployment, pass it as the environment variable `AUTH_TOKEN` when deploying:
```bash
$ docker run -e AUTH_TOKEN=... -e AWS_SECRET_ACCESS_KEY=... \
    -e AWS_ACCESS_KEY_ID=... vokalinteractive/vip
```

To configure CORS support for browser-based clients, supply a comma separated list (no spaces) of allowed hosts in the environment variable `ALLOWED_ORIGIN`. Setting `ALLOWED_ORIGN=*` allows any host; setting `ALLOWED_ORIGIN=*.project.com` allows any subdomain of project.com. For staging setups, you likely want to allow `localhost` as well, or any upload tests from drone or a local dev environment will fail. Ex: `ALLOWED_ORIGIN=localhost,*.project.com`. (_Note:_ Requests from an allowed origin _do not_ require an `X-Vip-Token`.)


## Configuration Summary

- `AWS_ACCESS_KEY`: The access key for an IAM user or role with access to S3 bucket(s)
- `AWS_SECRET_ACCESS_KEY`: The secret key for an IAM user or role with access to S3 bucket(s)
- `AWS_REGION`: The AWS region in which image storage buckets are configured (default `us-east-1`)
- `URI_HOSTNAME`: The hostname used to build image URLs, e.g. `images.example.com`
- `AUTH_TOKEN`: A secret token that non-browser clients can use to autheticate for uploads. If no token is supplied, anyone could upload to your image proxy
- `ALLOWED_ORIGIN`: a comma-delimited list of hostnames to accept CORS requests from browser-based clients, e.g. `www.example.com,*.example2.com` will accept uplaod requests from pages originating from www.example.com or any subdomain of example2.com. If this is not set, CORS is disabled and will likely fail for any upload requests from a browser.
- `VIP_SIZE_LIMIT`: A maximum file-size limit in megabytes (default `5`)
- `VIP_MAX_WIDTH`: A maximum width for resized images in pixels (default `720`)

For serving via HTTPS (recommended), `vip` expects to find an SSL certificate as well as the matching private key in the following locations:
- `/etc/vip/application.pem`
- `/etc/vip/application.key`

By default, `vip` will also respond to HTTP/2 requests; however, some mobile clients have incomplete implementations and may fail. You can turn off HTTP/2 support by setting `DISABLE_HTTP2` to `True`. _In particular,_ iOS 8 clients have problems with this draft version of HTTP/2.


## Cloudfront

`vip` can (and should be) used behind a CDN like Amazon Cloudfront. To use `vip` behind the 
Cloudfront CDN setup a custom origin with the FQDN of your proxy, and also permit `POST` HTTP 
methods on the distribution.

![alt text](https://images.vokal.io/vokalvip/c528c0a28a980402a236267e60009422?s=650 "VIP was here")


## Maintainer

Chris Foresman ([foresmac](https://github.com/foresmac/)) chris.foresman@vokal.io

Imports 6 package(s)

  1. github.com/mitchellh/goamz/aws
  2. github.com/vokal/q
  3. github.com/mitchellh/goamz/s3
  4. github.com/gorilla/mux
  5. github.com/bradfitz/http2
  6. github.com/golang/groupcache

Test imports 1 package(s)

  1. gopkg.in/check.v1