Repository navigation
AppTown v1.0.0-rc.9
Pre-releaseFlokkit AppTown v1.0.0-rc.9
RC9 makes projects easier to create and rename, adds named release environments
and external sign-in, and brings operational warnings together in Attention.
It also tightens checks, credential handling and recovery of retained database
storage. Read the upgrade changes below before updating an RC7 installation.
Upgrade correction
RC8 was withdrawn because its repository-layout migration rejected historical
ended console sessions that legitimately had no checkout path. RC9 preserves
that history while retaining the checks required for live sessions and orphaned
checkouts. The upgrade regression now includes this retained RC7 state.
The changes below cover everything since RC7, the previous available release.
Take matching database and file backups before upgrading, as described in the
upgrade guide.
New and improved
- Start with what you want to build. Project creation starts with a
description and proposes a name and address you can change. Local repositories
use immutable project IDs. Renaming a project keeps its previous addresses
usable and does not rename its upstream repository or running apps. Addresses
stay reserved even after a project is purged. - Name your release environments. Targets, integrations and deployments can
have your own labels. Select a project's default release environment and use
the same release plan and permission checks as a release to a named deployment.
Application hostnames belong to deployments, independently of project names.
Newly prepared Docker apps and previews receive their exact browser origin,
removing wildcard trust of sibling projects. Portainer connections and upstream repositories are checked against
their recorded provider identities before use. - External sign-in. Add one OpenID Connect provider alongside local password
sign-in. Accounts link through stable provider subjects, not matching email
addresses. An enabled local administrator remains available for recovery.
This does not configure sign-in for the apps AppTown hosts. See
external sign-in. - Attention. A shared page, top-bar count and Home summary show operational
warnings for resources you can read: storage, workers, deployments and data
protection. Missing or stale observations remain visible. Disk warnings are
bounded on large disks and show their threshold. - Application health. Portainer honors declared ports, ordered initialization
and health checks for the exact release. App Platform honors startup grace and
expected readiness status. Maintained health observations use the declared
execution policy and distinguish the running generation from a failed update. - Bounded Janitor assessment. Preview and record standing consent, then
inspect an exact candidate for supported npm patch/minor updates, same-version
Node base-image digest updates, supported security fixes and explicitly
classified guidance-only adoption changes. Unsupported changes require a
person. Automatic acceptance, landing and deployment are not available.
Saving consent or running an assessment does not update software. See
Janitor. - AppTown update preparation. Administrators can check signed release
notifications. Linux archives include a separate managed supervisor for
explicitly enrolled root-run systemd and local Docker installations. It keeps
installation identity and interrupted-update startup controls outside AppTown's
replaceable directories. Enrollment does not enable automatic replacement.
Continue to use the documented
upgrade procedure. - A revised tour. The tour follows the current project flow, demonstrates a
plain club website becoming a bright neon version, and preserves tours at
versioned URLs so earlier releases remain viewable. - Stock content ships beside release binaries as update files. Packs can name
tool lines, and versions record their source and signer. The .NET way of
working moves to .NET 10; the Go starter trusts configured extra certificate
authorities. Homebrew support is available for final releases; release
candidates do not update the formula.
Breaking changes
Upgrades and whole-AppTown restores start at RC7
The oldest supported installation and backup schema is now 167
(1.0.0-rc.7). Earlier schemas are refused before migration or restore
changes data. RC7 and RC8 installations retain their records and versions;
new installations use the complete assembled schema. RC7 archives without
database provenance remain supported. Retired migration history remains
in Git.
Root-installed archive ownership
The Linux installation instructions now keep extracted release files owned by
root, rather than the release builder. Existing archive installations should
stop the service and repair ownership of /opt/apptown (or
/opt/apptown-worker) before restarting; see the
server setup guide.
Do not change ownership of the data directory or project repositories.
Native Mac database storage
Fresh native Mac installations keep the built-in PostgreSQL database in a
Docker-managed volume. Docker Desktop's shared Mac filesystem can otherwise
change observed ownership during initialization and leave startup unable to
complete. Existing bound volumes stay in place; no data moves automatically.
The local pgdata receipt records the managed volume before PostgreSQL starts.
Missing or replaced recorded storage requires recovery. Use a whole-AppTown
backup or a database dump plus the matching data-directory copy; a directory
snapshot alone does not contain a managed database. Linux storage is unchanged.
Local repositories move to immutable project locations
Startup moves existing local repositories to project-ID directories before
application recovery. An interrupted move resumes from its journal. Unknown
ownership or surviving writers stop the upgrade for operator investigation;
AppTown does not guess which files belong to a project. -verify-only performs
this layout transition as well as schema changes. Stop writers and keep matching
database and data-directory backups before upgrading. See the
upgrade guide.
Keep the shipped update files beside the binaries
Copy share/ with bin/ when installing an archive. The daemon and worker now
read the shipped ways of working and tool versions from share/apptown/updates;
they do not start without the required files. Copying only a replacement binary
is no longer sufficient.
Confirm existing Portainer targets and addresses
Before releasing an existing Portainer deployment, an administrator must inspect
and confirm the target's provider association. Then inspect and confirm each
upgraded deployment's observed host rules and certificate domain. The upgrade
keeps the old addresses as evidence but does not treat them as verified.
These confirmations do not change the running stack or clear restore holds.
Old pending release requests without the required address snapshot need a new
release request after confirmation. See
Portainer connection identity
and deployment addresses.
Checks say "not applicable" instead of passing on nothing
A check that had nothing to judge used to pass: a Go check with no go.mod,
a frontend check with no frontend, an image scan with no image. Now each
check says what it applies to, and AppTown works out from the app contract
whether it applies before anything runs. A check that does not apply says
not applicable and why ("no part is built with go"). It is never a
pass and never an error. It does not stop anyone approving or landing, and
the change's record lists every check that was not applicable, so none is
read as passed. Once a check applies, finding nothing to judge is a
failure: the contract and the code disagree.
What changes for an existing project:
- Landing is stricter.
- The tests step fails when a part is built with Go, Node, Python,
Ruby, Java, .NET or Rust and no test command is found. Before, it
passed with "no tests found". A test command AppTown already found
still runs, whatever the contract says. - The dependency scan (osv) fails when it finds no package files in an
app whose parts are built with a language it reads. Before, it passed.
A .NET app now commitspackages.lock.json. - An app whose public part is a static site has image scans that say not
applicable. Before, they passed with a note.
- The tests step fails when a part is built with Go, Node, Python,
- The shipped checks' scripts fail where they used to pass on a missing
subject, once the check applies. - The app contract gains two fields, both optional:
tools:on a part names what it is built with, for example
tools: [go, node]. Without it, a project's language checks, the
dependency scan and the licence scan are not applicable.notAppCode:lists folders whose code is not the app's (docs, tooling).
- A new platform check, "the contract matches the code", reports each
package.json, go.mod, pyproject.toml, Gemfile, Cargo.toml, pom.xml,
.csproj, composer.json or project.godot that no part'stools:covers.
It fails a landing that leaves a new one undescribed. - The check format gains
appliesTo, and it is required. A check, or a
scanner that is not manual, saved without it is refused. Checks and
scanners already stored are givenappliesTo: [repository]when the
database migrates. That is what they meant before, so nothing stored
behaves differently. - A yes given in advance has new wording. The stock landing's sentence
is now "every check passing or not applicable". A yes given on the old
sentence is left for a person. - New starters with no app yet ship their
make testtarget commented
out. The change that writes the app uncomments it.
What to do after upgrading
- For each project, add
tools:to each part in.apptown/app.yaml, in a
change of its own. The contract check's finding names each manifest to
cover. AddnotAppCode:for folders that are not the app's code. - Give each part built with a language a test command (a Makefile
test
target, a package.jsontestscript, go.mod or pom.xml at the root, or
the tests step'scommand). - Commit
packages.lock.jsonin a .NET app
(<RestorePackagesWithLockFile>true</RestorePackagesWithLockFile>). - Run What-if on each pack's new version, then adopt it under
Settings → Way of working. - Write
appliesToon any check you author from now on.
Until a project's contract names its tools, its dependency and licence
scans say not applicable on every change. They are never shown as passed.
Invalid contract versions are refused
App contracts with a negative version now fail validation with the invalid
value named. Choose the supported version the contract is intended to use;
AppTown does not rewrite it. Omitted versions still mean version 1, explicit
versions 1 and 2 keep their existing meaning, and future versions still report
that they require a newer AppTown.
Standing Docker database needs refuse to open retained data without matching
observed engine, mount destination and volume evidence. Verified container-loss
recovery uses the bound immutable engine; unknown retained files and changed
declarations require explicit recovery. AppTown does not automatically migrate
database engines.
Backup engine provenance
Whole-AppTown backups record observed PostgreSQL server and dump-client versions.
New restores refuse malformed metadata or a recorded server major other than
PostgreSQL 16 before extracting data. Older archives without this metadata keep
the existing restore behavior; this does not add cross-major database upgrades.
Project-scope lookup failures stop authorization with an unavailable response.
They no longer become an empty group, instance scope or partial capability list.
A grant for a confirmed missing project can still be cleaned up by an instance
administrator.
Open-mode and trusted-header requests now return 503 when AppTown cannot record
the person, instead of continuing with an incomplete identity. The same refusal
applies to trusted-header OAuth consent; invalid names still return 401.
Authentication and execution failures
Unavailable credential or account lookups return 503 on the API, MCP and browser
OAuth authorization doors. They no longer appear as invalid tokens or anonymous
sessions. MCP sends no replacement-credential challenge for this failure.
Root systemd services
The daemon and worker units set DOCKER_CONFIG=/root/.docker, so boot
checks can locate Docker configuration when systemd supplies no HOME.
An operator can override the location in the service environment file.
Identity administration requires the admitted person's immutable ID. An actor
header alone no longer supplies authority to route or project membership checks.
Normal open-mode and trusted-header admission still record the person first;
receipt attribution remains separate from authorization.
Database storage and physical restore
Standing Docker databases now bind their data volumes to observed immutable engine
images, mount destinations and volume incarnations. Container loss can recover using that exact engine;
a changed declaration, replaced volume or unknown retained store refuses writable
startup. These records grant no new permission to delete data.
Whole-instance database restoration establishes new target storage before engine
startup. Physical copies require immutable source-engine evidence captured when
copied. Older physical items, including RC7 Redis RDB backups, lack that evidence
and require independently verified recovery; their archive bytes are preserved,
but automatic fill refuses. Logical copies keep their supported restore path.
A failed restore that leaves engine-data volumes requires explicit recovery before
retry; those volumes are never assumed empty. See the backup guide.
HTTP API changes
These changes are relative to RC7. The HTTP API remains experimental. The
OpenAPI description
contains the request and response definitions.
Projects, releases and storage
- Project creation accepts
automaticAddress,requestIdand typedsetup
intent. Settings changes acceptslugandrequestIdfor an address change,
with the expected settings revision. Historical addresses resolve to the
current project; they are never reassigned. GET /api/v1/projects/{slug}/repo/remotereads the upstream attachment.
The existing POST acceptsrepositoryName,requestId,
expectedAttachmentIdandrecoverProviderId; its response adds
attachmentId. Attachment operations verify provider repository identity.GET /api/v1/projects/{slug}/release/planreturns the typedReleasePlan;
GET /api/v1/projects/{slug}/targetsreturnsProjectTargets.
POST /api/v1/projects/{slug}/releaseuses the selected default environment
and that deployment's current authority. Its request addsdefaultRevision,
addressRevisionandacceptUncheckedCopy.- New default-environment operations:
GETandPUT /api/v1/projects/{slug}/release/default, andPOST /api/v1/projects/{slug}/release/default/setup. - New label operations:
PUT /api/v1/targets/{id}/label,PUT /api/v1/integrations/{id}/labelandPUT /api/v1/projects/{slug}/deployments/{id}/label. - New deployment operations:
PUT /api/v1/projects/{slug}/deployments/{id}/promotion-policy;GETandPUT
/api/v1/projects/{slug}/deployments/{id}/address; andGETandPOST
/api/v1/projects/{slug}/deployments/{id}/address/observation. - New retained-storage operations:
GETandPOST /api/v1/projects/{slug}/deployments/{name}/storage-bindings. New provider
association operations:GETandPOST /api/v1/targets/{name}/provider-association. GET /api/v1/tiersnames the customer tierrelease, replacing the configured
release deployment name (usuallylan). Entries describe current standing
deployments, withdeploymentIdanddeploymentLabel; multiple entries can
share a project slug. URLs and running/unknown states reflect current
observations, and removed deployments disappear. Use release history or the
departures view for historical releases.- Target settings cannot redirect a verified Portainer target to another
endpoint by changing its environment name; attach a new target instead. - Deployment responses add
displayLabel,requirePromotionand
policyRevision; deployment views also includeidandtargetId.
Target views adddisplayLabel. Backup items addengineImageID.
Sign-in, operational status and updates
GET /api/v1/auth/meremovescan.amendandcan.release(the entirecan
field). ReadGET /api/v1/authz/mefor current capabilities. The response
also adds an optionalexternalsummary withdisplayNameandallowSignup
when external sign-in is enabled.GET /api/v1/attentionreturns authorized conditions and observation coverage.GET /api/v1/instance-updatesreads release and supervisor status;
POST /api/v1/instance-updates/checkrequests a release check.- External sign-in adds
GETandPUT /api/v1/auth/external/provider,
POST /api/v1/auth/external/test,POST /api/v1/auth/external/enabled,
POST /api/v1/auth/external/startandGET /api/v1/auth/external/callback.
Bindings useGETandPOST /api/v1/auth/external/bindings,DELETE /api/v1/auth/external/bindings/{id}andPOST /api/v1/auth/external/bindings/{id}/unlink. - Credential, account, identity-recording and authorization-scope lookup failures
return unavailable responses, including HTTP 503 where described above,
instead of proceeding anonymously or reporting invalid credentials.
Consequential actions require an admitted principal ID and recheck retained
credentials before queued release effects. Ambiguous need and scoped-secret
credentials are refused; credentialed provider requests refuse redirects.
Checks and standing consent
- Check verdicts add
not-applicable; step states addnot_applicable.
Check and nonmanual scanner declarations requireappliesToas described
above. Scanner evidence can includenotApplicableexplaining the result.
Pack specifications and views addtools. Published version history adds
sourceandsigner; shipped stock records explicitly say when unsigned. - Standing consent adds
GETandPOST /api/v1/standing-approvals, and
POST /api/v1/standing-approvals/preview. Each rule supportsPOST /api/v1/standing-approvals/{id}/assess,POST /api/v1/standing-approvals/{id}/disableandGET /api/v1/standing-approvals/{id}/history. - Routine publication classification adds
POST /api/v1/routine-publications,
POST /api/v1/routine-publications/preview,POST /api/v1/routine-publications/{id}/revokeandGET /api/v1/routine-publications/{kind}/{id}/history.
Deprecations
None. The RC7 upgrade floor and other compatibility changes above take effect
in this release candidate.