Retry GET requests of githubApi() up to three times when GitHub answers
with a 5xx error or the connection fails. One 502 or one timeout on the
repository lookup before a deployment failed the deployment. Writes are
not retried, so a pull request comment is not posted two times. The
installation token request uses the same retry rule.
Closes#9785
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stop calling /zen before each installation token request. A short
network problem to GitHub failed deployments with a cURL timeout on
/zen. assertGithubClockInSync now takes the failed response and reads
its Date header, so the "System time is out of sync" error still shows
when GitHub rejects the JWT.
Call it on failed JWT requests in the webhook installation check, the
permission job, the source connection test, and the server transfer
checklist. Remove the /zen fakes from the tests.
S3 storages with a self-signed or private CA certificate failed with
"cURL error 60", because the Coolify container and the backup helper do
not use the CA certificates of the host. The new opt-in setting turns off
the certificate check in the PHP S3 clients and sets MC_INSECURE for mc.
Closes#9762
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
New Outline versions run CREATE OR REPLACE TRIGGER in a migration,
which needs PostgreSQL 14 or later. On postgres:12-alpine the migration
failed and the Outline container restarted in a loop.
Closes#12345
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
AppFlowy Web runs on its own domain and sends a Redirect_to header to
/gotrue/magiclink on the admin domain. GoTrue does not allow that
header by default, so the CORS preflight failed and email sign-in
showed "Network error". Set GOTRUE_CORS_ALLOWED_HEADERS=redirect_to.
Closes#10545
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The template used mysql:latest with binary logging on and no limit,
so the binary logs filled the disk and Bugsink stopped. Use
postgres:17-alpine and bugsink/bugsink:2, as the Bugsink Docker
Compose sample does. Existing services keep MySQL; the changelog
tells how to purge the logs and turn binary logging off.
Closes#10626
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Deleting a server with "Delete all resources" (UI) or ?force=true (API)
deleted every application that used the server, also applications that
use it only as an additional destination, for example after Promote.
Server delete now deletes only resources whose main destination is on
the server. Applications that use it only as an additional destination
lose their additional_destinations row for the server, and their
containers on it are stopped (best effort). The check for resources and
the transfer archive path use the same Server::primaryResources().
The delete confirmation lists the resources to delete and the
applications that keep running on another server.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Use usesend/usesend:v1.10.0 instead of latest, so servers do not keep
an old cached image without the v1.10.0 security updates. The template
never used MinIO, so the RustFS change of v1.10.0 does not apply.
Closes#12443
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The stuck resources cleanup selected every column of every deployment,
including logs, and ran out of memory during app:init. Select only the
id and application_id. Also drop the unused executions property on the
backup pages and an unused execution loader.
Closes#12435
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The MCP deploy tool and control start skipped the deployment queue, so
two rolling updates of one application could run at once and remove the
new container of each other. A rolling update now also removes only the
containers that ran before it started.
Closes#12442
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Traefik renews every certificate in acme.json, also when no route uses
its domain. The TLS certificates page now marks certificates that no
Traefik label, proxy config file, or resource domain on the server uses,
and a "Delete unused" button removes them in one write with one backup.
Closes#12447
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Use the only reported disk when no known root mount is reported, and stop
filtering disk history by mount names so Sentinel 1.1.4+ keeps that disk.
Closes#12448
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- read the docker.io tags from the documented tags API
- check that docker.io still has a manifest before deleting it, docker.io also answers 202 to the deletion of a missing manifest
- count every manifest in --delete
- a run can stop after the deletion on ghcr.io and before the one on docker.io, so every run deletes on docker.io the versions that ghcr.io deleted last
Webhooks matched rows only by subscription ID, so a paid row without one
stayed active after the customer canceled. The deleted and updated events
now verify such a row, the verify job also finds canceled subscriptions,
and the invoice-failed job counts only invoices of the row's subscription.
cloud:sync-stripe-subscriptions reports these rows, and
cloud:fix-subscription --verify-all writes its CSV to a file and shows
details only with -v.
- they came after every index, so the leftovers of earlier runs waited about 190 runs
- delete the oldest first on both registries instead of the manifests that only docker.io has first
- read every docker.io manifest from the Docker Hub API, tagged or not
- delete the images and attestations of an index right after the index
- show the docker.io sizes next to the ghcr.io ones
- push the stable channel to sync/stable-v<version> instead of a branch named after the time, a new sync of the same version updates its pull request
- close the open sync pull requests of older stable versions as superseded
- name the commit and the pull request after the version change, like the upstream check of peakimages/sqlite, with a note to squash merge it
- the stable channel opens a pull request and the preview channel pushes to main, both from a fresh clone of the CDN
- the stable pull request now branches off main after the preview push, so a release that moves both latest and preview no longer leaves it with a conflict in versions.json
- a local tag that differs from origin, such as a tag moved on origin before the tag protection rule, failed the fetch with "could not fetch origin" and no reason, as --quiet also hid the rejected tags