NGINX with DNS-01 (Linux)
Linux / NGINX — This page walks through a production certificate request using the DigiCert ACME Client with command-line flags only. Do not pass --use-default-config on this page—the client will not read dc-acme.toml. For config-based enroll instead (shorter commands, copy settings across servers), see Configuration (dc-acme.toml).
Explicit CLI flags help you:
- See credential and handler usage clearly
- Confirm connectivity, permissions, and DCV on your production ACME Directory URL
- Prove issuance and NGINX installation end to end
- Get a clear success signal in both the client and CertCommand before enabling automation
Acronyms used on this walkthrough
| Term | Meaning |
|---|---|
| ACME | Automated Certificate Management Environment — the protocol used to automate certificate issuance and renewal |
| ADU | ACME Directory URL — the endpoint and credential profile you create in CertCommand under Automation > ACME Directory URLs |
| CLI | Command-Line Interface — run `dc-acme request enroll` with explicit flags instead of loading settings from `dc-acme.toml` |
| EAB | External Account Binding — Key ID and HMAC credentials that authenticate your ACME client to GeoCerts |
| DCV | Domain Control Validation — proof that you control a domain name (via a DNS-01 or HTTP-01 challenge) |
| DAC | DigiCert ACME Client — GeoCerts' recommended ACME client (`dc-acme`) |
| DNS-01 | DNS challenge — publish a `_acme-challenge` TXT record to prove domain control |
| HTTP-01 | HTTP challenge — serve a token file on port 80 at `/.well-known/acme-challenge/` |
| CN | Common Name — primary hostname on the certificate (`--cn` flag) |
Haven't validated DCV yet? Run a Sandbox Walkthrough (Linux) first. Sandbox requests are not billed and let you prove EAB, DCV, and install before you create real orders.
On Windows with IIS? See IIS with HTTP-01 or the Sandbox Walkthrough (Windows/IIS) for platform-specific guidance.
This walkthrough uses the DigiCert ACME Client (DAC). Other EAB-capable clients (Certbot, win-acme) produce similar phases and log signals; the option names differ. See Alternative ACME Clients.
Prerequisites
Before you begin, make sure you have:
- A production ACME Directory URL with its EAB Key ID and EAB HMAC Key (not a sandbox URL).
- The DigiCert ACME Client installed and the
DigicertAcmeClientservice running. - A domain you control, with either DNS access (for DNS-01) or an HTTP listener (for HTTP-01).
- NGINX with an enabled
serverblock whoseserver_namematches the domain you are securing (required if you use the NGINX installer in Step 1).
Where things are on Linux
You'll reference these default paths in Steps 2 and 3 (log tail and on-disk certificate store):
| Item | Path |
|---|---|
| Client binary | dc-acme (on PATH after install) |
| Configuration (TOML) | /var/digicert/acme-client/config/dc-acme.toml |
| Service log | /var/digicert/acme-client/log/ |
| Default certificate store (on disk) | /etc/digicert/certificates/{timestamp}/{common-name}/ |
The three choke points
Most ACME setup failures happen at one of three stages. This page walks through each one and shows how to recognize it in the log.
- EAB authentication — your client proves it is bound to your GeoCerts account.
- Domain Control Validation (DCV) — you prove control of each domain. This is the most common failure point, especially with DNS credentials.
- Post-issuance deployment — the issued certificate is installed or handed off to your server or load balancer.
The two DCV methods
You choose one DCV challenge method per request:
- DNS-01 — proves control by publishing a TXT record at
_acme-challenge.<domain>in your DNS. It works without a public web server and is required for wildcard certificates, but it needs credentials for your DNS provider. - HTTP-01 — proves control by serving a token file at
http://<domain>/.well-known/acme-challenge/...on port 80. It needs no DNS API access, but the domain must resolve to the validating host and port 80 must be publicly reachable—DigiCert validates under MPIC from multiple regions worldwide (at least four).
This walkthrough uses DNS-01. For HTTP-01 on NGINX, see NGINX with HTTP-01.
Step 1: Run a production request
The example below requests a single-domain certificate using DNS-01 validation, since DNS credentials are the most common sticking point. This walkthrough uses AWS Route 53 as the DNS provider—the client publishes and removes the _acme-challenge TXT record automatically using your Route 53 credentials. It also installs the issued certificate into NGINX, so this one command covers all three choke points—EAB, DCV, and install—end to end (the NGINX installer is detailed in Step 4).
Route 53 is just one example. The DigiCert ACME Client supports 190+ DNS providers (it uses the Lego DNS library under the hood), each with its own handler arguments. Use the provider that hosts your domain's DNS, and replace the placeholder values with your production credentials and domain.
# Production DNS-01 request with NGINX install (replace placeholder values)
sudo dc-acme request enroll \
--directory-url "https://one.digicert.com/mpki/api/v1/acme/v2/directory" \
--email "admin@example.com" \
--eab-key "YOUR_EAB_KEY_ID" \
--eab-hmac "YOUR_EAB_HMAC_KEY" \
--auto-ari-renew=true \
--cn "example.com" \
--challenge-type "dns-01" \
--challenge-handler-name "default" \
--challenge-handler-args "DNS_PROVIDER_NAME=route53,AWS_ACCESS_KEY_ID=YOUR_AWS_ACCESS_KEY_ID,AWS_SECRET_ACCESS_KEY=YOUR_AWS_SECRET_ACCESS_KEY,AWS_REGION=us-east-1" \
--installer-handler-name "nginx" \
--installer-handler-args "identifier=example.com"
The NGINX installer needs a matching site. Because this command also installs into NGINX, an enabled server block whose server_name matches --cn must already exist. Confirm it before you run the request: sudo nginx -T 2>/dev/null | grep server_name. See Step 4 for how the installer uses it and how to verify the result. To issue without installing, drop the two --installer-handler-* flags.
Specify the DCV method: For DNS-01 you must set both --challenge-type "dns-01" and --challenge-handler-name "default". If you omit --challenge-type, the DigiCert ACME Client defaults to HTTP-01 with the standalone handler, which will not use your Route 53 credentials and will fail if there is no HTTP listener answering the challenge.
The Route 53 handler is configured through --challenge-handler-args, which accepts these comma-separated arguments:
DNS_PROVIDER_NAME=route53— selects the Route 53 challenge handler.AWS_ACCESS_KEY_ID— access key for an IAM principal allowed to modify the hosted zone.AWS_SECRET_ACCESS_KEY— the matching secret key.AWS_REGION— the AWS region (for example,us-east-1).
For other DNS providers and their required arguments, see DigiCert’s DNS-01 handler reference. That page is served as raw Markdown and may display as plain text outside the DigiCert docs portal; the same provider list, rendered, is in the Lego DNS providers documentation it is derived from.
Keep secrets off the command line. Credentials passed as flags or handler args (EAB HMAC, AWS secret key) are visible in your shell history and to anyone who can list running processes on the host. For CLI-only examples that is acceptable. Once issuance works, move EAB credentials into dc-acme.toml—see Configuration. For DNS provider secrets, prefer your provider's credential chain when available—for Route 53, an EC2 instance role, ~/.aws/credentials, or environment variables. Rotate any credentials you entered on the command line once config-based enroll is working.
Step 2: Read the DigiCert ACME Client log
The request command prints progress to your console, but the client log is the authoritative record—especially for renewals and background activity.
Tip: Open two terminal sessions side by side—run the ACME request in one and tail the log in the other. Watching the log live while the request runs makes it much easier to see exactly where a request stalls, fails, or succeeds.
On Ubuntu, the DigiCert ACME Client writes log files under /var/digicert/acme-client/log/:
# Tail the most recent log activity
tail -f /var/digicert/acme-client/log/*.log
Note: The log path above is confirmed on Ubuntu. It may differ on other Linux distributions. If the directory is not present, use the journalctl command below.
Or use the systemd journal:
sudo journalctl -u DigicertAcmeClient -n 50
As the request runs, you should see distinct phases that map to the three choke points:
- ACME account registration / EAB binding
- Order creation and authorization
- Challenge (DCV) — DNS record published, then validated
- Certificate finalization and download
- Installation / handoff
The console may hang after an error. When a request fails, the command can appear to hang—even though the log has already recorded the error. If the log shows the request has failed, press Ctrl+C to stop the command rather than waiting.
Step 3: What a successful request looks like
On a successful run, the console is brief—it validates the handler, enrolls, and returns a Request ID:
Validating handlers with server...
Handler validation successful
Initiating certificate enrollment (this may take a few minutes)...
Certificate enrollment successful. Request ID: 3
Key signals of success:
Handler validation successful— the challenge handler (here, Route 53 DNS-01) was accepted.Certificate enrollment successfulwith a Request ID — issuance completed.- No
ERRORlines in the log, and the request status is notFAILED.
The log shows the full successful flow—account, order, DNS-01 challenge, validation, finalize, and certificate storage (trimmed for readability):
INFO Account already exists, returning existing account
INFO Creating order for 1 identifiers
INFO Successfully created new ACME order with URI: .../acme/v2/order/MDUz...
INFO Starting challenge validation with type: dns-01 with handler: default
INFO Generated DNS-01 challenge to be staged - Record: _acme-challenge.example.com, Value: <redacted>
INFO: Running DNS authenticator
INFO: Challenge propagated successfully for domain: example.com
INFO Authorization completed with status: valid for identifier: example.com
INFO Successfully finalized order
INFO Writing certificate and private key to certificate directory: /etc/digicert/certificates
INFO Installing certificate and private key in: /etc/digicert/certificates/<timestamp>/example.com
INFO Processing certificate installation with handler: nginx
INFO ACME request status updated successfully - Status: COMPLETED
INFO Processing enrollment request - COMPLETED SUCCESSFULLY
Issuance and install in one request. Because the Step 1 command includes the NGINX installer (--installer-handler-name nginx), the certificate is also installed and the request finishes COMPLETED. Step 4 shows exactly what the installer did and how to verify it. Without an installer handler, the client only stores the certificate on disk (No installer preference provided - certificate installation skipped) and you deploy it yourself.
Confirm success in the client and CertCommand
Check the local request status:
sudo dc-acme request list
Look for your request’s status to be COMPLETED. A FAILED status means the request did not complete—check the log for the cause.
For a production ACME Directory URL, the issued certificate should also appear in CertCommand under Certificates > Orders. That is your account-level confirmation that issuance succeeded and the order is tracked for billing and lifecycle management.
You can also verify the issued certificate on disk. By default the client stores certificates under /etc/digicert/certificates/, in a timestamped subfolder named for the issuance time, then a folder named for the certificate’s Common Name:
/etc/digicert/certificates/<YYYY_MM_DD_HH_MM_SS>/<common-name>/
├── fullchain.pem # issued certificate plus the issuing chain
└── privkey.pem # the certificate's private key
Inspect the certificate’s validity dates:
sudo openssl x509 -in /etc/digicert/certificates/<timestamp>/example.com/fullchain.pem -noout -subject -dates
Production certificates use your product’s normal validity period—not the fixed 3-day lifetime of sandbox test certificates.
Step 4: Install the certificate to NGINX
Issuance writes the certificate to disk; installation deploys it to your web server so it serves traffic over HTTPS. The Step 1 command already included an installer handler (--installer-handler-name nginx), so issuance and installation happened in that single request—this step explains what the NGINX installer did and how to verify it.
How the NGINX installer works
The NGINX installer auto-discovers your configuration. It runs your nginx binary to find every config file, locates the server block whose server_name matches the domain you pass in identifier, then:
- Updates an existing HTTPS (
listen 443 ssl) block in place—rewriting itsssl_certificateandssl_certificate_keyto the newly issued files—or creates an HTTPS block from your port-80 block if no 443 block exists. - Reloads NGINX gracefully (
nginx -s reload).
Unlike the Windows/IIS installer, there is no one-time bootstrap: you do not need to pre-create a binding or seed a placeholder certificate.
Prerequisite: a matching server_name block must exist and be enabled. Confirm one exists before you run the request:
sudo nginx -T 2>/dev/null | grep -nE 'server_name|listen'
The NGINX installer uses identifier=<domain> (where the Windows/IIS installer uses hostname=):
--installer-handler-name "nginx" \
--installer-handler-args "identifier=example.com"
In the log, the installer reports the server block it discovered, the ssl_certificate / ssl_certificate_key lines it rewrote, and the reload (trimmed for readability):
INFO Processing certificate installation with handler: nginx
INFO Invoking install handler: nginx
Discovered Nginx server block *:80 for example.com
Found existing port 443 block for domain example.com, will update it instead of creating new
Updated ssl_certificate to: /etc/digicert/certificates/<timestamp>/example.com/fullchain.pem
Updated ssl_certificate_key to: /etc/digicert/certificates/<timestamp>/example.com/privkey.pem
Nginx installation completed successfully and restarted.
INFO ACME request status updated successfully - Status: COMPLETED
INFO Processing enrollment request - COMPLETED SUCCESSFULLY
For load balancers and similar targets, the client typically does not install directly: issuance succeeds, but deployment is your own step (a deploy hook or an API upload to the load balancer).
Verify and troubleshoot
When the log shows COMPLETED SUCCESSFULLY and the order appears in CertCommand, confirm the certificate is live over HTTPS—see Verify HTTPS is live — NGINX. Production certificates use your product’s normal validity period, not the 3-day sandbox lifetime.
If something fails, the log is the authoritative signal. See Verify and Diagnose ACME Requests for EAB, DCV, and NGINX install failure signatures. On Windows/IIS, see Installation failures — IIS.
Optional: config file
If you prefer shorter repeat enrolls or the same settings on multiple servers, see Configuration (dc-acme.toml). You do not need to re-run enroll on this certificate—--auto-ari-renew=true already registered automatic reissues and renewals.
Configuration (dc-acme.toml) »
Related topics
- Validate Your Setup on Linux with a Sandbox URL — Practice the same flow safely before production
- Create an ACME Directory URL — Production and sandbox URLs
- Install the DigiCert ACME Client
- Verify and Diagnose ACME Requests — Confirm success, verify HTTPS, and diagnose failures
- Troubleshooting Common Issues — Funding, OV, and permissions
← Back to Production CLI Examples