Add an allowlisted multi-host entrypoint that delegates each hostname to the
existing origin selector with its own required health status. Hostnames share
the same origin pair and readiness secret, so one Worker can serve several
independent Routes without duplicating the deployment.
Validation: 21 Worker tests and independent review passed.
Disclosure: I'm an AI assistant helping the author; I'm not the author.
Allow explicit 200 health responses for application origins and share only
in-flight readiness probes without caching their results. Document the accepted
native primary/replica pattern over the existing Xray transport, with fenced
manual promotion and independent node repositories.
Validation: 18 Worker tests, 17 readiness tests, and git diff --check passed.
Production SSO migration and traffic activation remain separate rollout steps.
Disclosure: I'm an AI assistant helping the author; I'm not the author.
Run a fixed application probe behind an authenticated local endpoint with bounded concurrency, deadlines, and no-store responses. Keep application safety checks and production enrollment explicit integration gates.
Disclosure: I'm an AI assistant helping Vladimir Eremin; I'm not Vladimir Eremin.
Pin the CI-built resticontainer image that rejects failed pre-backup hooks. Record the approved SQL-backed directory deployment gates in the replication RFC.
Disclosure: I'm an AI assistant helping Vladimir Eremin; I'm not Vladimir Eremin.
Select a ready origin before dispatch, preserve authentication requests without replay, and document Cloudflare compatibility and activation gates.
Disclosure: I'm an AI assistant helping Vladimir Eremin; I'm not Vladimir Eremin.
Compare matching runtime and registry digest types, and distinguish declared Compose builds from registry images. Report unavailable checks explicitly.
Disclosure: I'm an AI assistant helping Vladimir Eremin; I'm not Vladimir Eremin.
Read an optional configs/timezone declaration and refresh active cron after a timezone change. Report a failed cron restart instead of claiming success.
Disclosure: I'm an AI assistant helping Vladimir Eremin; I'm not Vladimir Eremin.
Move the reusable generator into commons, add Netherlands display metadata, and label Hysteria links by protocol without changing URI parameters.
Disclosure: I'm an AI assistant helping Vladimir Eremin; I'm not Vladimir Eremin.
Update the on-demand certificate dumper to v2.11.4 so Traefik accounts without KeyType no longer panic. Validated native export and all 260 tests.
Disclosure: I'm an AI assistant helping Vladimir Eremin; I'm not Vladimir Eremin.
Explicitly apply the intended directory mode after creation while preserving existing tier and parent permissions. Regression tests cover enrollment's restrictive umask.
Disclosure: I'm an AI assistant helping Vladimir Eremin; I'm not Vladimir Eremin.
Install CrowdSec before its bouncer and repair package placeholder credentials without changing custom YAML credentials. Match native Debian UFW and package-unit behavior during protected SSH enrollment.
Restore only owned Docker helper chains, cancel queued service starts, and recover failed owned services before reporting rollback complete. Preserve changed administrator policy for reconciliation.
Verified with 258 automated tests and an isolated Debian 13 VM: baseline repair/retry, SSH/security activation, committed retry, watchdog recovery, actual reboot, and pending-cleanup reconciliation. Native source bundle: 8ae1f9fa1bf3dfa1f6c3aeb1c96fe92f170cbcbb7afae664266a76975a1ce1c7.
Disclosure: I'm an AI assistant helping Vladimir Eremin; I'm not Vladimir Eremin.
Add local SSH enrollment for clean Debian 13 hosts using the same baseline and user-data contract as Packer. Preserve provider networking, validate storage and repository ownership, and protect final SSH and security-service activation with persistent access recovery.
Document composition-scoped replication patterns for independent node repositories and add behavioral coverage for provisioning, retries, and recovery. Native verification of the security activation transaction remains the production enrollment gate.
Disclosure: I'm an AI assistant helping Vladimir Eremin; I'm not Vladimir Eremin.
Nodes using Docker's containerd snapshotter (storage driver 'overlayfs') make
the cadvisor exporter open a containerd client to read container info; without
/run/containerd/containerd.sock it fails to register existing containers, so no
per-container metrics appear (only the machine root). Mount the socket read-only
— harmless on overlay2 nodes, required on containerd-snapshotter ones.
The cadvisor exporter reads /sys/fs/cgroup for per-container stats, but with the
default private cgroup namespace it only saw the container's own cgroup — so it
emitted machine-root container_* series (one per node, no name label) and no
per-container metrics. cgroup: host exposes the host cgroup tree so cadvisor
enumerates every container (mapped to names via the docker socket).
Add a prometheus.scrape for the CrowdSec agent's :6060 endpoint, forwarded to the
existing remote_write. CrowdSec runs on the host, so nodes that run it bind the
metrics endpoint on 0.0.0.0 (host firewall keeps it off the public interface) and
Alloy reaches it via the docker gateway; nodes without CrowdSec report the target
down. node/instance labels are stamped APEX_NODE_HOST like the other exporters.
Open with a centered logo and a plain-language description of what apex does for
a self-hoster, then Why, then How it works. Quick start shows a minimal
selfhost.example.com bootstrap. Links the published docs (en + Russian) and the
getting-started guide. Drops badges and the repo-layout table (covered in docs).
Swap MIT for BSD 2-Clause (verbatim OSI/SPDX text) ahead of publishing apex as a
generic self-host framework. Add a README footer welcoming AI-assisted contributions
that meet the quality bar and are understood by the contributor.
node_exporter's uname collector reports the container's UTS hostname as
node_uname_info{nodename}, which Docker defaults to the container id. Grafana
surfaces that as the host, so every node showed a hex id instead of its name.
Setting hostname on the alloy service makes nodename the node's public host.
node/instance labels were already correct via the config.alloy relabel.
Drop the hardcoded-domain FQDN regex and every hardcoded domain from commons.
Node identity is now explicit in node.env: APEX_NODE_FQDN (real FQDN,
traefik Host()), APEX_NODE_HOST (public host name — backup --host,
obs/notify instance), APEX_SUBNET. The short name (log prefix, sync/<node>
branch, messages) is derived as the first host label.
notify instance is just the host (no hardcoded prefix); the git bot identity
moves to APEX_GIT_AUTHOR_NAME/EMAIL (node.env) with generic defaults. Alloy
node+instance labels use APEX_NODE_HOST. Fallbacks keep a node working if it
omits a var (host<-fqdn<-hostname).
BREAKING CHANGE: removes APEX_NODE and APEX_CLUSTER env vars; node name is now derived from APEX_NODE_FQDN
Per the "Core Apex (all nodes)" policy: traefik /etc/traefik/dynamic,
adguard /opt/adguardhome/conf, xray /etc/xray/config.jsonc. Profile-gated
services are only discovered on nodes that run them.