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)

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 DigicertAcmeClient service running.
  • A domain you control, with either DNS access (for DNS-01) or an HTTP listener (for HTTP-01).
  • NGINX with an enabled server block whose server_name matches 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.

  1. EAB authentication — your client proves it is bound to your GeoCerts account.
  2. Domain Control Validation (DCV) — you prove control of each domain. This is the most common failure point, especially with DNS credentials.
  3. 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).

# 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 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.


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.

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

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:

  1. ACME account registration / EAB binding
  2. Order creation and authorization
  3. Challenge (DCV) — DNS record published, then validated
  4. Certificate finalization and download
  5. Installation / handoff

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 successful with a Request ID — issuance completed.
  • No ERROR lines in the log, and the request status is not FAILED.

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

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 its ssl_certificate and ssl_certificate_key to 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.

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) »


← Back to Production CLI Examples