Serve static files from a CDN rather than Flask in production

Solution 1:

There's no need to change how you link to static files, you can still use url_for('static', filename='myfile.txt'). Replace the default static view with one that redirects to the CDN if it is configured.

from urllib.parse import urljoin
# or for python 2: from urlparse import urljoin
from flask import redirect

@app.endpoint('static')
def static(filename):
    static_url = app.config.get('STATIC_URL')

    if static_url:
        return redirect(urljoin(static_url, filename))

    return app.send_static_file(filename)

Whether you're on a dev machine or production, set the STATIC_URL config value to the CDN and requests for static files will be redirected there.


Redirects are relatively cheap, and are remembered by browsers. If you get to the point where performance is meaningfully affected by them, you can write a function that links directly when using the CDN.

@app.template_global()
def static_url(filename):
    static_url = app.config.get('STATIC_URL')

    if static_url:
        return urljoin(static_url, filename)

    return url_for('static', filename=filename)

The template_global decorator makes the function available in all templates. Use it instead of url_for when you need urls for static files.


There may be a Flask extension that does this for you already. For example, Flask-S3 provides a url_for that serves static files from AWS S3.

Solution 2:

This flask cdn integration guide may be worth taking a read through. Basically you can install the Flask-CDN extension and define your CDN URL within your app.py file like so:

from flask import Flask
from flask.ext.cdn import CDN

app = Flask(__name__)
app.config['CDN_DOMAIN'] = 'cdn.yourdomain.com'
CDN(app)