I’m a big fan of thumbor and resizing images on the fly behind a CDN; what a great way to keep the front end flexible while seeing the same* performance as storing pre-sized images. When I’m working with a fast-moving startup we don’t want image processing API integrations; we want to add a few settings in the img tag src url and see results. Strangely I only found a couple services that do this, with imgix being the most prominent. I may be searching the wrong thing, so I’d love see more options in the comments. But meanwhile I didn’t want to saddle my client with an extra $50 per month just to see a bump in image performance, and their IP/image ownership was a concern.

Enter Thumbor

There’s a great post by Yipit on using a Thumbor-based solution at scale, and apparently I completely missed out on a more in-depth tutorial when I set about borrowing Yipit’s image strategy (you might head there if you want to install on an Amazon Linux AMI, though I haven’t tried Reed’s steps myself). I had an Ubuntu image ready to go so I thought I’d write a short post on getting a quick-and-dirty** image processor up and running with a few apt-get commands. Go ahead and launch an Ubuntu EC2 image with ports 22 and 80 exposed, ssh into it and follow along:

# Install nginx
sudo su
apt-get update
apt-get install nginx
/etc/init.d/nginx start
# Install Thumbor
apt-get install python-dev
apt-get install python-pip
apt-add-repository ppa:jon-severinsson/ffmpeg
apt-get update
apt-get install ffmpeg libjpeg-dev libpng-dev libtiff-dev libjasper-dev libgtk2.0-dev python-numpy python-pycurl webp python-opencv
ln -s /usr/lib/x86_64-linux-gnu/libjpeg.so /usr/lib
pip install pillow
pip install thumbor
thumbor-config > /etc/thumbor.conf
# Install Supervisor
easy_install supervisor
mkdir logs # For Supervisor logs

Now we just have a few config files to write. Again this is going to be simplified—you’ll probably want to do a deeper dive into the settings, but this will get you started.

Supervisor Config File

# /etc/supervisord.conf

command=thumbor --port=800%(process_num)s

Nginx Config File

# /etc/nginx/nginx.conf
# Put this inside the http section, replacing the server name with
# your EC2 Public DNS

upstream thumbor {
server {
    listen 80;
    server_name ec2-53-236-234-31.compute-1.amazonaws.com;
    location / {
        proxy_pass http://thumbor;

A few more commands will wrap up this shindig:

# Start Supervisor
supervisord -c /etc/supervisord.conf
# Restart nginx
service nginx restart

Voilà, image processing server ready to go. Try the thumbor example image by navigating here in your browser:


There are a few more things you’ll want to do before you use this in a production environment (probably more than a few). To name some:

  1. Assign your instance an Elastic IP
  2. Put the instance behind a CDN like CloudFront
  3. Read about and implement Thumbor Security Measures
  4. Configure your image storage depending on your needs/resources
  5. Other Thumbor config, app monitoring, and all the other fun stuff that comes along with your new “custom” image processing solution

That being said, it is pretty exciting to introduce even a simple version of this stack in your product. If you are iterating on thumbnail sizes while your early adopters are uploading large images even the simple implementation above will give you huge performance gains, and you can focus on optimizing security/storage/etc as your business matures.

* Close enough given the benefits :)
** I’m going to ignore/omit a few things like thumbor security. Head to Reed’s the more in-depth post for something more comprehensive.