NGINX with HTTP-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 whose A record points at this host and whose port 80 is publicly reachable from multiple regions worldwide under MPIC requirements (at least four global vantage points).
  • NGINX with an enabled server block whose server_name matches the domain you are securing and includes a root directive (the HTTP-01 handler writes the challenge token under that document root).

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. For HTTP-01, the most common failures are port 80 reachability, firewall rules, and a missing or wrong document root.
  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:

  • 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).
  • 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.

This walkthrough uses HTTP-01. For DNS-01 on NGINX, see NGINX with DNS-01.


Step 1: Run a production request

The example below requests a single-domain certificate using HTTP-01 validation through your running NGINX and installs the issued certificate into NGINX—so this one command covers all three choke points (EAB, DCV, and install). The NGINX installer is detailed in Step 4.

# Production HTTP-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 "http-01" \
  --challenge-handler-name "nginx" \
  --installer-handler-name "nginx" \
  --installer-handler-args "identifier=example.com"
  • --challenge-handler-name "nginx" serves the HTTP-01 token through your running NGINX on port 80—do not use standalone when NGINX already owns port 80.
  • Port 80 must be publicly reachable. DigiCert validates under MPIC from multiple network vantage points around the world—at least four global regions, not just North America. A firewall or geo-restriction that only allows traffic from one country or region will cause validation to fail. See SSL Domain Validation (DCV) Rules Have Changed .
  • If no web server is running on the host, use standalone instead (port 80 must be free). For other running servers, use their handler (apache, tomcat, or ibmhttpd).

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) — challenge token written under your NGINX document root, then validated over HTTP
  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, NGINX HTTP-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, HTTP-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: http-01 with handler: nginx
   INFO: Challenge token placed at /var/www/html/.well-known/acme-challenge/<token>
   INFO: Nginx reloaded successfully
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, HTTP-01 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