Production
The API ships as a multi-arch Docker image built from src/Schuly.API/Dockerfile.
Container image
- Build context is
./src. The Dockerfile'sCOPYpaths are relative to that directory, not the repo root. - Build stages: SDK build/publish on
mcr.microsoft.com/dotnet/sdk:10.0, runtime onmcr.microsoft.com/dotnet/aspnet:10.0. Entry point isdotnet Schuly.API.dll. - The repo-root
application.properties(whichDirectory.Build.propsnormally reads for the version) is not in the build context, so the image is built with-p:Version=$VERSION. The release workflow passes the release tag asVERSION; this keeps the host assembly version aligned with what runtime-loaded plugins bind against. - The image pre-creates
/app/pluginsand/app/plugins-configfor runtime-loaded plugins and their per-plugin config.
Versioning + release
Single source of truth: application.properties (<version>). src/Directory.Build.props
reads it via XmlPeek.
Publishing a GitHub Release triggers docker-publish-release.yaml:
sync-version— compares the release tag (vstripped) againstapplication.properties. If they differ, it opens arelease-sync/<version>branch updating the file and auto-merges (squash) the PR intomain.build-and-push-multiarch— buildslinux/amd64+linux/arm64from./srcand pushes tags:ghcr.io/schulydev/schuly:<semver>plus:<major>,:<major>.<minor>, and:latest(latest only for non-prereleases).<DOCKERHUB_USERNAME>/schuly:<semver>(Docker Hub, best-effort — the login step iscontinue-on-error).
Migrations on startup
The container applies EF Core migrations automatically at startup
(ApplyMigrations() in Program.cs → db.Database.Migrate()) and seeds the
school-systems catalog. No separate migration step is required when deploying; ensure
the database is reachable via the SchulyDatabase connection string. See
Migrations and Configuration.