Skip to content

Releases

v1.1.0

Choose a tag to compare

@xinitd xinitd released this 24 Oct 21:23
Immutable release. Only release title and notes can be modified.
v1.1.0
acd0a99

The first update since the release on October 11: the Python base image is pinned by digest, CI checks every build of the image against requirements.txt, and the README covers what to check after an update.

Upgrading from 1.0.0

docker-compose.yaml, .env.example, webserver/ and static/ are unchanged, and main.py only has the new version number, so a deployment of 1.0.0 updates in place: git pull and docker compose up -d --build, then the checks in After an update.

If you copied 1.0.0 into a project of your own:

  • Take the FROM line from the Dockerfile. The Python base image is now pinned by digest and changes only through a pull request, so keep Dependabot on: without it the base image never gets updates, security fixes included.
  • Take requirements.txt as a whole: it pins the full set the image was tested with.
  • If you take the CI workflow, take the github-actions entry in .github/dependabot.yml with it, so the action pinned by SHA keeps getting updates.
  • FastAPI 0.144 to 0.157 removed openapi_prefix and extra keyword arguments from FastAPI() and deprecated root_path. Sclerotin uses none of them, but code you added on top might.

What's changed

Build and updates

  • Pin the Python base image by digest (#19). With the tag alone, the build checked it against Docker Hub every time, so a rebuilt python:3.14.8-slim reached the server without passing CI (#15)
  • Add a CI workflow that builds the image, compares pip freeze with requirements.txt and runs pip check on every pull request and every commit to main (#4, #18). Dependabot now updates the action it uses (#4)

Security policy

  • Add SECURITY.md: private reporting through GitHub, scope and supported versions (#3)

Documentation

  • Add what to do after an update: the commit to return to, checks on the server and from another machine, and cleanup, including the previous Nginx image (#11, #20)
  • Correct the README sentence that said the build reuses a cached Python base image (#19)

Dependencies

  • Python from 3.14.7 to 3.14.8, an expedited security release (#7)
  • FastAPI from 0.142.3 to 0.157.0 (#6, #8, #14)
  • Starlette from 1.7.0 to 1.9.0 (#9, #13)
  • Pydantic from 2.13.5 to 2.14.1 (#5, #10)

Full Changelog: v1.0.0...v1.1.0

v1.0.0

Choose a tag to compare

@xinitd xinitd released this 11 Oct 13:40
cf1a3e0

First public release. A hardened reference deployment of FastAPI behind Nginx with Docker Compose, running at https://sclerotin.args.tech

The application is one endpoint, trivial on purpose: the release is everything around it.

What's in place

  • A Content Security Policy per kind of response: default-src 'none' for the API, a policy of its own for the landing page, a relaxed one for the docs only while they are switched on
  • Security headers split between Nginx and the app, error responses included
  • The app on an internal network with no route out of the host
  • Read-only root filesystems, all capabilities dropped, no-new-privileges, memory, CPU and PID limits, an unprivileged app user
  • Unknown host names and bare-IP requests dropped without an answer
  • Per-address rate limits that see real IPv6 addresses, request size limits and timeouts against slow clients
  • TLS 1.2 and 1.3 with Mozilla's intermediate profile, post-quantum hybrid key exchange (X25519MLKEM768) and HSTS; Let's Encrypt with automatic renewal

Pinned in this release

  • Python 3.14.7 (slim), FastAPI 0.142.3, Uvicorn 0.54.0 and the rest of the dependency set in requirements.txt
  • nginx:stable-alpine by SHA256 digest
  • opentelemetry-api is pinned too: FastAPI 0.142 requires it. With no OpenTelemetry SDK in the image it stays inert, and the app has no route out anyway
  • Weekly Dependabot pull requests keep the pins current

Requirements

Docker Engine 27+ and Compose 2.17+, a rootful daemon without userns-remap. Why each of them is needed is in the README.

Check the live headers

curl -sD - https://sclerotin.args.tech/api/v1/ping

Every choice is explained in How it works.