server { listen 80; root /usr/share/nginx/html; # Nginx's bundled mime.types does not name the APK type on every build, and # a wrong Content-Type is enough for a download manager to save an HTML # error page under the right filename. Say it explicitly. types { application/json json; application/vnd.android.package-archive apk; } default_type application/octet-stream; # The manifest changes every release; the APKs never do, because a new # release is a new filename. Cache accordingly. location = /manifest.json { add_header Cache-Control "no-cache"; } # The `latest` aliases MOVE — they are symlinks the release script # repoints — so they must never be cached as immutable. Exact-match # locations win over the regex below in nginx, which is what keeps a # one-year immutable header off the one URL people are told to use. location = /latest.apk { add_header Cache-Control "no-cache"; } location = /latest-linux.tar.gz { add_header Cache-Control "no-cache"; } # A versioned artifact never changes: a new release is a new filename. location ~ \.(apk|tar\.gz)$ { add_header Cache-Control "public, max-age=31536000, immutable"; } # Nothing here is a secret, but nothing here is a directory listing either. autoindex off; location / { try_files $uri =404; } }