Certbot
what is the difference between running certbot with –nginx vs –webroot?
https://grok.com/c/d50b69ef-d55c-4e15-b38e-53e3bf66edd1?rid=64adda4a-61ed-4173-8732-d40794c0d0ba
The main difference is:
--nginx= Authenticator + Installer (fully automatic for Nginx)--webroot= Only Authenticator (manual configuration required for Nginx)
1. --nginx (Nginx plugin)
This is the easiest and most automated option when you’re using Nginx.
-
What it does:
- Automatically modifies your Nginx config files to handle the ACME HTTP-01 challenge (serves the validation files).
- Obtains the certificate.
- Automatically installs the certificate (adds
ssl_certificate,ssl_certificate_key, etc. to your server blocks). - Reloads Nginx.
-
Pros:
- Very convenient — one command does everything.
- Great for simple setups.
-
Cons:
- It edits your Nginx configuration (makes backups, but still modifies files).
- Less flexible if you have complex Nginx setups (reverse proxies, multiple includes, Docker, etc.).
- Can sometimes produce less clean config than hand-written.
Typical command:
sudo certbot --nginx -d example.com -d www.example.com
2. --webroot (Webroot authenticator)
This is the most flexible method.
-
What it does:
- Places a temporary validation file in a directory you specify (
-w /path/to/webroot). - You must configure Nginx yourself to serve that directory at
/.well-known/acme-challenge/. - Only gets the certificate (
certonlymode by default) — does not install it into Nginx.
- Places a temporary validation file in a directory you specify (
-
Pros:
- Doesn’t touch your Nginx config.
- Works great with complex setups, Docker, reverse proxies, CDNs, etc.
- More predictable and controllable.
- Preferred by many advanced users and in containers.
-
Cons:
- You have to manually configure Nginx to serve the challenge files.
- You have to manually install the certificate into your Nginx config.
Typical command:
sudo certbot certonly --webroot \
-w /var/www/html \
-d example.com \
-d www.example.com
Comparison Table
| Feature | --nginx |
--webroot |
|---|---|---|
| Modifies Nginx config | Yes (automatic) | No |
| Needs manual Nginx setup | No | Yes (for .well-known/acme-challenge) |
| Certificate installation | Automatic | Manual |
| Best for | Simple setups | Complex, Docker, reverse proxies |
| Flexibility | Lower | Higher |
| Renewal | Works automatically | Works automatically |
Recommendation
- Use
--nginxif your setup is straightforward and you want maximum convenience. - Use
--webrootif you:- Have a complex Nginx config
- Run Nginx in Docker
- Want full control
- Are behind a CDN/reverse proxy
Many experienced users prefer --webroot even on standard servers because it keeps Certbot from touching their carefully crafted Nginx configurations.
This is what happens exactly when you use --webroot.
Consider:
sudo certbot certonly --cert-name your-domain.com --webroot -w /some/path -d comma-separated-domains -v --dry-run
- Step 1. For each domain,
certbotclient running on your computer is going to place a random file under/some/path. - Step 2. The certbot service will then attempt to read this file e.g.:
https://your-domain/.well-known/acme-challenge/BG2yBJEAsS1FwvRFgSLp6zeH05G7bGShSpSkVX6gXj8 - Step 3. If the service is able to read the file (200 OK), you are authenticated and the service will issue a certificate.
This means your NGINX must be configured as follows:
server {
server_name your-domain;
location /.well-known/acme-challenge/ {
root /some/path;
try_files $uri =404;
}
}
If you do not explicitly specify the root e.g. our NGINX config uses:
# Allow standard well-known endpoints
location ^~ /.well-known/ { try_files $uri =404; }
NGINX will fallback to the root with which it was compiled. This can be found by running:
$ nginx -V 2>&1 | grep --color 'prefix='
Look for --prefix= — the default root is {prefix}/html. If you installed NGINX using apt-get then --prefix=/usr/share/nginx
and so you should use -w /use/share/nginx/html in arguments to certbot.
The catch – if there is no server block for the domain, NGINX will fallback to the default server block and with the factory-installed
config that comes with NGINX the root is set to /var/www/html so this is what happens when you run:
certbot -w /use/share/nginx/html ...
with a domain that is NOT explicitly covered by a server block:
- Step 1. The client places the file under
/use/share/nginx/html. This is the directory you gave tocertbotunder-wargument. - Step 2. The remote service tries to read the file
https://your-domain/.well-known/acme-challenge - Step 3. There is no server block in your NGINX covering
your-domainso NGINX falls back to the default server - Step 4. NGINX tries to serve the file from
/var/www/html. This is therootin the default server block. - Step 5. The file is not found and NGINX returns 404
- Step 6. The verification fails
Migrating sites from one server to another
The problem: How to migrate a site from one server to another and install TLS certificate on new server before switching the DNS
Solution: Proxy request from old server to new one so certbot verification can complete. Insert this block on the old server:
# 1. Catch the Let's Encrypt challenge and proxy it to the new server
location /.well-known/acme-challenge/ {
proxy_pass http://IP-ADDRESS-OF-NEW-SERVER;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}