github fabriziosalmi/certmate v2.43.0
v2.43.0 (install it where you already are)

latest release: ansible-v1.0.0
2 hours ago

v2.43.0 (install it where you already are)

A packaging release: CertMate can now be installed the way each platform expects, from one tested file per platform. The application code is unchanged, and the API contract stays at 2.32.

Every install path below was run end to end on the real platform before it was written down: install, first login, upgrade, and a reboot where the platform has one.


Read this before upgrading

The systemd unit could not issue with file-based DNS providers

certmate.service, the unit in this repository, sandboxes the service with ProtectSystem=strict. letsencrypt/ was not among its writable paths, and that is where CertMate writes a DNS provider's credential file for each certbot run. Every issuance with Cloudflare and the other file-based providers therefore failed with [Errno 30] Read-only file system, reported only as "Certificate creation failed unexpectedly".

If you installed CertMate on bare metal with that unit, copy the new one (or use the installer below). Two other changes come with it:

  • It listens on 127.0.0.1:8000 by default, instead of every interface. Set CERTMATE_BIND=0.0.0.0:8000 in /etc/certmate/certmate.env to keep the old behaviour, or put a reverse proxy in front.
  • It passes --no-control-socket to gunicorn, which otherwise tried to create a control socket in the read-only application directory at every start.

Docker, Kubernetes and the other container installs are not affected.


New ways to install

  • Docker Compose for production. deploy/docker-compose.yml runs the published image (the release pins it), keeps data in named volumes, listens on loopback, and refuses to start without API_BEARER_TOKEN and SECRET_KEY. One curl and docker compose up -d: see docs/docker.md.

  • A Linux server with systemd. deploy/install.sh installs CertMate with its own Python 3.12 (fetched with uv, so Debian 12 and RHEL 9 work too) and the same pinned dependencies as the image. It generates the secrets and starts the service. Run it again to upgrade. Verified on Debian 12, Ubuntu 24.04 and Rocky Linux 9.

    curl -fsSL https://raw.githubusercontent.com/fabriziosalmi/certmate/main/deploy/install.sh | sudo sh
  • Podman. A Quadlet unit, deploy/podman/certmate.container, rootful or rootless, with the secrets as Podman secrets.

  • Portainer. Deploy the compose bundle as a Git-repository stack; Pull and redeploy upgrades it.

  • A cloud VM. deploy/cloud-init/certmate.yaml is user data that installs Docker and the bundle, and generates the secrets on the VM.

  • Kubernetes. docs/kubernetes.md now opens with the Helm install, an Argo CD Application and a Flux HelmRelease, all run on a real cluster.

  • Ansible. A role, deploy/ansible/roles/certmate, idempotent, with secrets from Ansible Vault.

Where it is published

  • GHCR. The image is now also published to ghcr.io/fabriziosalmi/certmate, with the same tags as Docker Hub. Useful where Docker Hub's anonymous pull limits bite.
  • Artifact Hub. The Helm chart is listed there, with its image security-scanned.

Fixed

  • The Docker Hub page listed twelve DNS provider environment variables (AWS, Azure, GCP, DigitalOcean, Hetzner) that the application never reads. Every provider except Cloudflare is configured in the web UI. The page, the README's Quick Start and the Kubernetes example now show only what works. A test keeps them that way.
  • The Podman docs said named volumes work "regardless of the UID". Under rootless Podman the backups volume stayed owned by root and CertMate refused to start; every example now uses :U.
  • The README's Kubernetes example persisted only /app/certificates, so settings and users lived in the pod. It is replaced by the Helm chart.

How it was checked

  • Compose: from an empty directory; first admin, login, down/up, a version change.
  • Installer: Debian 12, Ubuntu 24.04 and Rocky 9 with systemd as PID 1; install, a DNS-01 issuance reaching certbot, upgrade, reboot.
  • Unit defect: measured before the fix. The same request failed with the old unit and succeeded with the new one.
  • Podman: Fedora 44, rootful and rootless with lingering, including a reboot.
  • Portainer: Portainer CE 2.45; a stack without the secrets refused, with them healthy, then pull and redeploy.
  • cloud-init: a real Ubuntu 24.04 cloud VM booted with the user data, then rebooted.
  • Kubernetes: Helm, Argo CD 3.5 and Flux on k3s.
  • Ansible: a fresh Debian 13 host; a second run reports no change.

Don't miss a new certmate release

NewReleases is sending notifications on new releases.