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) |
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.
Need DNS-01 or a wildcard? HTTP-01 cannot validate wildcard certificates. See NGINX with DNS-01 for Route 53 and other DNS providers. On Windows with IIS, see IIS with HTTP-01.
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 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
serverblock whoseserver_namematches the domain you are securing and includes arootdirective (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.
- EAB authentication — your client proves it is bound to your GeoCerts account.
- 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.
- 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"
The NGINX challenge handler needs a matching site with a root directive. The handler finds the server block whose server_name matches --cn, reads its document root, writes the token to <root>/.well-known/acme-challenge/<token>, and reloads NGINX. Confirm before you run:
sudo nginx -T 2>/dev/null | grep -nE 'server_name|root '
For installation, the same server_name block must exist—see Step 4. To issue without installing, drop the two --installer-handler-* flags.
Use the NGINX handler, not standalone: When NGINX already owns port 80, pass --challenge-type "http-01" and --challenge-handler-name "nginx". The standalone handler starts a temporary listener on port 80 and will fail with address already in use if another service is bound there. If you omit --challenge-type, the client defaults to HTTP-01 with standalone—another common first-request failure.
--challenge-handler-name "nginx"serves the HTTP-01 token through your running NGINX on port 80—do not usestandalonewhen 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
standaloneinstead (port 80 must be free). For other running servers, use their handler (apache,tomcat, oribmhttpd).
Keep secrets off the command line. Credentials passed as flags (EAB HMAC) 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. 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) — challenge token written under your NGINX document root, then validated over HTTP
- 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. For example, if you omit --challenge-handler-name "nginx", the standalone handler may fail because port 80 is already in use—yet the console keeps 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, NGINX HTTP-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, 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
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, 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) »
Related topics
- Validate Your Setup on Linux with a Sandbox URL — Practice the same flow safely before production
- NGINX with DNS-01 — Wildcards and DNS provider credentials
- 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