Serving docs statically via nginx¶
Add collect-static command to your app:
import shutil
import click
import flask
@app.cli.command("collect_static")
@click.argument(
"destination_dir",
nargs=1,
type=click.Path(file_okay=False, dir_okay=True, writable=True, resolve_path=True),
required=True,
)
def collect_static_command(destination_dir):
docs.collect_static(destination_dir)
shutil.copytree(
flask.current_app.static_folder, destination_dir, dirs_exist_ok=True
)
click.echo(f"Static files collected into {destination_dir}.")
Configure nginx:
server {
# ...
location ^~ /v1/static {
alias /home/user/static;
try_files $uri $uri.html =404;
}
location ^~ /v1/docs {
alias /home/user/static/docs;
try_files $uri $uri.html =404;
}
# ...
}
Whenever deploying the app, call:
flask --app foobar_api collect-static /home/user/static
About Nginx and HTTP cache¶
You might be changing API docs rapidly and as a consequence, swagger.json changes
rapidly too. There is a risk that other people will be looking at older version of
docs - unless they hard reload their browser.
To avoid this, we should configure nginx to inject correct Cache-Control header into
response for each served static files.
server {
# ...
location ^~ /v1/static {
alias /home/user/static;
try_files $uri $uri.html =404;
add_header Cache-Control "public, max-age=86400, must-revalidate";
}
location ^~ /v1/docs {
alias /home/user/static/docs;
try_files $uri $uri.html =404;
add_header Cache-Control "no-cache";
}
# ...
}
Above configuration assumes following:
files under
/home/user/static/change rarelyBrowser is instructed to cache them for 1 day. After one day, browser WILL check with server if file had been modified. If server returns
HTTP 304 Not Modified, file will not be re-downloaded.(via
ETag- Nginx injects that automatically for us) and download new version of file only if it had changed.files under
/v1/docschange more frequentlyBrowser is instructed to cache these files, but to check with server if they had changed on every request. Again, this happens automatically via
Etagthat Nginx injects for us everywhere. If server returnsHTTP 304 Not Modified, browser doesn’t need to re-download file. Otherwise, it re-downloads it.
There are a few mechanisms of comparing file contents between browser and server. Modern
servers use Etag and Nginx injects that everywhere where it is needed. Details are usually
not important if you are running somewhat modern system with Nginx.
For other web servers check their docs in combination with: