{"id":13416236,"url":"https://github.com/nginx-proxy/acme-companion","last_synced_at":"2025-05-14T01:06:12.766Z","repository":{"id":39607043,"uuid":"48857632","full_name":"nginx-proxy/acme-companion","owner":"nginx-proxy","description":"Automated ACME SSL certificate generation for nginx-proxy","archived":false,"fork":false,"pushed_at":"2025-04-03T15:15:45.000Z","size":1034,"stargazers_count":7528,"open_issues_count":45,"forks_count":822,"subscribers_count":97,"default_branch":"main","last_synced_at":"2025-04-13T03:58:32.686Z","etag":null,"topics":["acme","acme-protocol","acme-v2","buypass","docker","letsencrypt","nginx-proxy","ssl","zerossl"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nginx-proxy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-12-31T17:50:05.000Z","updated_at":"2025-04-13T02:44:47.000Z","dependencies_parsed_at":"2024-02-25T11:37:33.380Z","dependency_job_id":"2351f537-eb68-489a-840d-d72c373c8673","html_url":"https://github.com/nginx-proxy/acme-companion","commit_stats":null,"previous_names":["nginx-proxy/docker-letsencrypt-nginx-proxy-companion","jrcs/docker-letsencrypt-nginx-proxy-companion"],"tags_count":40,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nginx-proxy%2Facme-companion","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nginx-proxy%2Facme-companion/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nginx-proxy%2Facme-companion/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nginx-proxy%2Facme-companion/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nginx-proxy","download_url":"https://codeload.github.com/nginx-proxy/acme-companion/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248661706,"owners_count":21141450,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["acme","acme-protocol","acme-v2","buypass","docker","letsencrypt","nginx-proxy","ssl","zerossl"],"created_at":"2024-07-30T21:00:55.854Z","updated_at":"2025-04-13T03:58:38.948Z","avatar_url":"https://github.com/nginx-proxy.png","language":"Shell","funding_links":[],"categories":["Container Operations","Shell","开发运维工具","docker"],"sub_categories":["Reverse Proxy"],"readme":"[![Tests](https://github.com/nginx-proxy/acme-companion/actions/workflows/test.yml/badge.svg)](https://github.com/nginx-proxy/acme-companion/actions/workflows/test.yml)\r\n[![GitHub release](https://img.shields.io/github/release/nginx-proxy/acme-companion.svg)](https://github.com/nginx-proxy/acme-companion/releases)\r\n[![Docker Image Size](https://img.shields.io/docker/image-size/nginxproxy/acme-companion?sort=semver)](https://hub.docker.com/r/nginxproxy/acme-companion \"Click to view the image on Docker Hub\")\r\n[![Docker stars](https://img.shields.io/docker/stars/nginxproxy/acme-companion.svg)](https://hub.docker.com/r/nginxproxy/acme-companion \"Click to view the image on Docker Hub\")\r\n[![Docker pulls](https://img.shields.io/docker/pulls/nginxproxy/acme-companion.svg)](https://hub.docker.com/r/nginxproxy/acme-companion \"Click to view the image on Docker Hub\")\r\n\r\n**acme-companion** is a lightweight companion container for [**nginx-proxy**](https://github.com/nginx-proxy/nginx-proxy).\r\n\r\nIt handles the automated creation, renewal and use of SSL certificates for proxied Docker containers through the ACME protocol.\r\n\r\n### Features:\r\n* Automated creation/renewal of Let's Encrypt (or other ACME CAs) certificates using [**acme.sh**](https://github.com/acmesh-official/acme.sh).\r\n* Let's Encrypt / ACME domain validation through `HTTP-01` (by default) or [`DNS-01`](https://github.com/nginx-proxy/acme-companion/blob/main/docs/Let's-Encrypt-and-ACME.md#dns-01-acme-challenge) challenge.\r\n* Automated update and reload of nginx config on certificate creation/renewal.\r\n* Support creation of [Multi-Domain (SAN) Certificates](https://github.com/nginx-proxy/acme-companion/blob/main/docs/Let's-Encrypt-and-ACME.md#multi-domains-certificates).\r\n* Support creation of [Wildcard Certificates](https://community.letsencrypt.org/t/acme-v2-production-environment-wildcards/55578) (with `DNS-01` challenge only).\r\n* Creation of a strong [RFC7919 Diffie-Hellman Group](https://datatracker.ietf.org/doc/html/rfc7919#appendix-A) at startup.\r\n* Work with all versions of docker.\r\n\r\n### HTTP-01 challenge requirements:\r\n* Your host **must** be publicly reachable on **both** port [`80`](https://letsencrypt.org/docs/allow-port-80/) and [`443`](https://github.com/nginx-proxy/acme-companion/discussions/873#discussioncomment-1410225).\r\n* Check your firewall rules and [**do not attempt to block port `80`**](https://letsencrypt.org/docs/allow-port-80/) as that will prevent `HTTP-01` challenges from completing.\r\n* For the same reason, you can't use nginx-proxy's [`HTTPS_METHOD=nohttp`](https://github.com/nginx-proxy/nginx-proxy#how-ssl-support-works).\r\n* The (sub)domains you want to issue certificates for must correctly resolve to the host.\r\n* If your (sub)domains have AAAA records set, the host must be publicly reachable over IPv6 on port `80` and `443`.\r\n\r\nIf you can't meet these requirements, you can use the `DNS-01` challenge instead. Please refer to the [documentation](https://github.com/nginx-proxy/acme-companion/blob/main/docs/Let's-Encrypt-and-ACME.md#dns-01-acme-challenge) for more information.\r\n\r\nIn addition to the above, please ensure that your DNS provider answers correctly to CAA record requests. [If your DNS provider answer with an error, Let's Encrypt won't issue a certificate for your domain](https://letsencrypt.org/docs/caa/). Let's Encrypt do not require that you set a CAA record on your domain, just that your DNS provider answers correctly.\r\n\r\n![schema](https://github.com/nginx-proxy/acme-companion/blob/main/schema.png)\r\n\r\n## Basic usage (with the nginx-proxy container)\r\n\r\nTwo writable volumes must be declared on the **nginx-proxy** container so that they can be shared with the **acme-companion** container:\r\n\r\n* `/etc/nginx/certs` to store certificates and private keys (readonly for the **nginx-proxy** container).\r\n* `/usr/share/nginx/html` to write `http-01` challenge files.\r\n\r\nAdditionally, a third volume must be declared on the **acme-companion** container to store `acme.sh` configuration and state: `/etc/acme.sh`.\r\n\r\nPlease also read the doc about [data persistence](./docs/Persistent-data.md).\r\n\r\nExample of use:\r\n\r\n### Step 1 - nginx-proxy\r\n\r\nStart **nginx-proxy** with the two additional volumes declared:\r\n\r\n```shell\r\n$ docker run --detach \\\r\n    --name nginx-proxy \\\r\n    --publish 80:80 \\\r\n    --publish 443:443 \\\r\n    --volume certs:/etc/nginx/certs \\\r\n    --volume html:/usr/share/nginx/html \\\r\n    --volume /var/run/docker.sock:/tmp/docker.sock:ro \\\r\n    nginxproxy/nginx-proxy\r\n```\r\n\r\nBinding the host docker socket (`/var/run/docker.sock`) inside the container to `/tmp/docker.sock` is a requirement of **nginx-proxy**.\r\n\r\n### Step 2 - acme-companion\r\n\r\nStart the **acme-companion** container, getting the volumes from **nginx-proxy** with `--volumes-from`:\r\n\r\n```shell\r\n$ docker run --detach \\\r\n    --name nginx-proxy-acme \\\r\n    --volumes-from nginx-proxy \\\r\n    --volume /var/run/docker.sock:/var/run/docker.sock:ro \\\r\n    --volume acme:/etc/acme.sh \\\r\n    --env \"DEFAULT_EMAIL=mail@yourdomain.tld\" \\\r\n    nginxproxy/acme-companion\r\n```\r\n\r\nThe host docker socket has to be bound inside this container too, this time to `/var/run/docker.sock`.\r\n\r\nAlbeit **optional**, it is **recommended** to provide a valid default email address through the `DEFAULT_EMAIL` environment variable, so that Let's Encrypt can warn you about expiring certificates and allow you to recover your account.\r\n\r\n### Step 3 - proxied container(s)\r\n\r\nOnce both **nginx-proxy** and **acme-companion** containers are up and running, start any container you want proxied with environment variables `VIRTUAL_HOST` and `LETSENCRYPT_HOST` both set to the domain(s) your proxied container is going to use.\r\n\r\n[`VIRTUAL_HOST`](https://github.com/nginx-proxy/nginx-proxy#usage) control proxying by **nginx-proxy** and `LETSENCRYPT_HOST` control certificate creation and SSL enabling by **acme-companion**.\r\n\r\nCertificates will only be issued for containers that have both `VIRTUAL_HOST` and `LETSENCRYPT_HOST` variables set to domain(s) that correctly resolve to the host, provided the host is publicly reachable.\r\n\r\n```shell\r\n$ docker run --detach \\\r\n    --name your-proxied-app \\\r\n    --env \"VIRTUAL_HOST=subdomain.yourdomain.tld\" \\\r\n    --env \"LETSENCRYPT_HOST=subdomain.yourdomain.tld\" \\\r\n    nginx\r\n```\r\n\r\nThe containers being proxied must expose the port to be proxied, either by using the `EXPOSE` directive in their Dockerfile or by using the `--expose` flag to `docker run` or `docker create`.\r\n\r\nIf the proxied container listen on and expose another port than the default `80`, you can force **nginx-proxy** to use this port with the [`VIRTUAL_PORT`](https://github.com/nginx-proxy/nginx-proxy#multiple-ports) environment variable.\r\n\r\nExample using [Grafana](https://hub.docker.com/r/grafana/grafana/) (expose and listen on port 3000):\r\n\r\n```shell\r\n$ docker run --detach \\\r\n    --name grafana \\\r\n    --env \"VIRTUAL_HOST=othersubdomain.yourdomain.tld\" \\\r\n    --env \"VIRTUAL_PORT=3000\" \\\r\n    --env \"LETSENCRYPT_HOST=othersubdomain.yourdomain.tld\" \\\r\n    --env \"LETSENCRYPT_EMAIL=mail@yourdomain.tld\" \\\r\n    grafana/grafana\r\n```\r\n\r\nRepeat [Step 3](#step-3---proxied-containers) for any other container you want to proxy.\r\n\r\n## Additional documentation\r\n\r\nPlease check the [docs section](https://github.com/nginx-proxy/acme-companion/tree/main/docs).\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnginx-proxy%2Facme-companion","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnginx-proxy%2Facme-companion","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnginx-proxy%2Facme-companion/lists"}