Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
FREEDOM251

Freedom251 › Blog › Apache

How to Set Up Free HTTPS with Let’s Encrypt on a VPS (2026 Guide)

By Freedom251 Team · · 12 min read

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

You can secure a domain on a self-managed VPS at no certificate cost by using Let’s Encrypt and Certbot. Point the domain at the VPS, make the site reachable for the selected ACME challenge, run Certbot for nginx, Apache, a webroot, or DNS validation, then verify renewal with sudo certbot renew --dry-run. Standard Let’s Encrypt certificates are valid for 90 days, so a working renewal timer is part of a complete setup—not an optional follow-up.

What you need before requesting a certificate

Let’s Encrypt validates control of a domain before issuing a certificate. On a VPS, you are responsible for the DNS records, firewall, web-server configuration, Certbot installation, and renewal service.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • A registered domain: Use the exact hostnames you want on the certificate, such as example.com and www.example.com.
  • DNS pointing to the VPS: Create an A record for an IPv4 address and, if you use IPv6, an AAAA record. Do not publish an AAAA record that points somewhere unable to answer the challenge; Let’s Encrypt may try IPv6 first.
  • A running web server or a planned DNS challenge: nginx and Apache are supported directly. A webroot, standalone listener, DNS plugin, or manual validation are alternatives.
  • Firewall access: For HTTP-01, inbound TCP port 80 must reach the VPS. HTTPS clients also need TCP port 443 after installation. Open the ports in both the VPS firewall and any provider-level security group.
  • Administrative access: You normally need root or sudo privileges to install packages, bind ports, and edit web-server configuration.

Confirm the DNS change has propagated before starting. Requesting a certificate while the hostname still resolves to an old server produces a validation failure even if the VPS itself is configured correctly.

Choose the ACME validation method first

Certbot proves domain control through an ACME challenge. The right method depends on whether the public website can receive HTTP traffic and whether you need a wildcard name.

Method Best fit Network requirement Wildcard certificates Renewal behavior
nginx or Apache installer An existing supported web server whose configuration Certbot can edit HTTP-01 normally requires inbound port 80 No; use DNS-01 for wildcards Automatic when Certbot’s timer or cron job is functioning
Webroot A running server with a document root you control HTTP-01 and reachable port 80 No Automatic with the same Certbot configuration
Standalone No usable web-server integration Certbot temporarily binds port 80 No Automatic only if the service can be stopped or coordinated during renewal
DNS-01 Port 80 is blocked, the origin is private, or a wildcard is required A DNS TXT update, usually through a DNS API Yes Automatic through a supported DNS plugin or an authentication hook
Manual A one-off or unusual validation situation You perform HTTP or DNS steps yourself Yes, when using DNS validation No automatic renewal unless an authentication hook script is added

How HTTP-01 works

With HTTP-01, Certbot creates a token file at /.well-known/acme-challenge/<TOKEN>. Let’s Encrypt retrieves that URL over ordinary HTTP and checks that the response contains the expected token. This is the most common challenge type for public websites. Redirects to HTTPS are generally workable, but the initial HTTP request must still reach the correct server and return the challenge content.

The nginx, Apache, webroot, and standalone Certbot plugins use HTTP-01. Standalone mode must bind port 80 itself, so another process listening there has to be stopped or coordinated.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

How DNS-01 works

DNS-01 proves control by requiring a TXT record beneath _acme-challenge. It is the only challenge type that can issue a wildcard certificate such as *.example.com. It is also the practical choice when a firewall, private origin, carrier-grade NAT, or policy prevents inbound port 80.

The challenge name can be delegated with a CNAME or NS record. That lets the public website remain on one DNS service while a separate validation zone is updated by Certbot. Delegation is useful when the VPS operator should not receive broad credentials for the main DNS zone.

Install Certbot on the VPS

On a self-managed VPS, you manage the Certbot installation yourself. Managed hosting plans sometimes install and operate certificate automation for you, but that is not assumed here.

Use your distribution’s current Certbot packages or the installation method documented for your operating system. On Debian- or Ubuntu-based systems, a typical package-based installation is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo apt update
sudo apt install certbot

Install the web-server plugin you intend to use as well. Common package names are:

sudo apt install python3-certbot-nginx
sudo apt install python3-certbot-apache

Package names vary by distribution and release. Verify that the executable is available before requesting a certificate:

certbot --version

Do not run two independent Certbot installations against the same certificate lineage unless you understand which one owns renewal. Duplicate timers can cause rate-limit problems and make troubleshooting harder.

Set up HTTPS on nginx

1. Check the HTTP virtual host

Before Certbot edits nginx, make sure the domain already serves the intended site over HTTP. The server_name values must match the names you plan to request, and the DNS records must resolve to this VPS.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo nginx -t
curl -I http://example.com
curl -I http://www.example.com

The first command checks syntax. The curl requests should reach this server and return a normal response, even if it is a redirect or an application status generated by your site.

2. Back up the configuration

Save the active nginx configuration before allowing an installer to modify it:

sudo cp -a /etc/nginx /etc/nginx.backup-before-certbot

Certbot documents rollback support for nginx, but a separate backup gives you a known restore point if a custom include, proxy rule, or syntax issue needs manual recovery.

3. Obtain and install in one operation

For a conventional nginx site, run the nginx installer and specify every hostname that should be covered:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo certbot --nginx -d example.com -d www.example.com

Certbot obtains the certificate and can update the matching nginx server block. It may ask whether HTTP requests should be redirected to HTTPS. Choose a redirect only after confirming that your application, health checks, webhooks, and other HTTP-dependent clients support HTTPS.

4. Test the resulting configuration

sudo nginx -t
sudo systemctl reload nginx
curl -I https://example.com

Open the HTTPS URL in a browser and inspect the certificate details and lock indicator. Check each hostname separately; a valid certificate for the apex domain does not automatically cover a different subdomain.

Set up HTTPS on Apache

1. Confirm the name-based virtual host

Apache must have a virtual host responding to the requested domain. Confirm that the HTTP site is enabled and that DNS points to the VPS before invoking Certbot.

sudo apachectl configtest
curl -I http://example.com

2. Back up Apache configuration

sudo cp -a /etc/apache2 /etc/apache2.backup-before-certbot

This is especially useful when the site uses reverse-proxy directives, custom SSL includes, or distribution-specific layout files.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

3. Obtain and install the certificate

sudo certbot --apache -d example.com -d www.example.com

The Apache plugin can request the certificate and update the virtual host. Follow the redirect prompt deliberately: force HTTPS only when all application routes and integrations are ready.

4. Reload and verify

sudo apachectl configtest
sudo systemctl reload apache2
curl -I https://example.com

Use a browser to inspect the served certificate and test both the bare domain and any www alias. A successful certificate request does not guarantee that every virtual host is serving the intended content.

Use webroot mode when the server must stay running

Webroot mode leaves nginx or Apache running and writes the challenge file into a directory that the web server already exposes. This is useful for applications behind a reverse proxy or for operators who do not want Certbot to rewrite server configuration.

1. Make the challenge directory reachable

For a site rooted at /var/www/example, create the directory and ensure the web server serves it as ordinary, non-application content:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo mkdir -p /var/www/example/.well-known/acme-challenge
sudo chown -R www-data:www-data /var/www/example/.well-known

Test with a temporary file:

echo test | sudo tee /var/www/example/.well-known/acme-challenge/check
curl http://example.com/.well-known/acme-challenge/check

The response must contain test. Remove the file after testing:

sudo rm /var/www/example/.well-known/acme-challenge/check

Do not let a framework route, authentication middleware, CDN rule, or blanket redirect replace the challenge response. The path must be retrievable as regular content.

2. Request the certificate without changing server configuration

sudo certbot certonly --webroot -w /var/www/example -d example.com -d www.example.com

certonly obtains the certificate but does not install it into nginx or Apache. Configure the server to use the resulting files under /etc/letsencrypt/live/<certificate-name>/, then reload the server after each successful renewal if your setup requires a reload hook.

Use standalone mode when no web-server plugin fits

Standalone mode starts a temporary Certbot listener on port 80. Stop the existing service first, request the certificate, and start the service again:

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo systemctl stop nginx
sudo certbot certonly --standalone -d example.com
sudo systemctl start nginx

Use the equivalent service commands for Apache. This method fails if another process still owns port 80, if a firewall blocks the port, or if a load balancer sends the challenge to a different machine. Renewal must repeat the stop-and-start coordination, so webroot or a server plugin is usually less fragile for a continuously running site.

Use DNS-01 for wildcards or blocked port 80

Wildcard certificates

HTTP-01 cannot issue *.example.com. A wildcard request must use DNS-01, and the apex domain is a separate name. If you need both, request both explicitly:

sudo certbot certonly --manual --preferred-challenges dns -d example.com -d '*.example.com'

Manual DNS validation asks you to create a TXT record under _acme-challenge.example.com. Wait until the TXT record is visible from public DNS before continuing. Manual mode is appropriate for a one-time certificate, but it does not renew automatically unless it is combined with an authentication hook script.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Automated DNS plugins

A DNS plugin can create and remove TXT records through your provider’s API. Configure the provider credentials in a root-readable file, use the narrowest permissions available, and keep the credential off the public web directory. A compromise of broad DNS credentials could let an attacker redirect domains or issue certificates for many names. Let’s Encrypt recommends narrowly scoped credentials or a separate validation server when possible.

The exact plugin package, credential format, and command differ by DNS provider. Follow that provider’s current plugin documentation and test the complete renewal path rather than assuming that a successful first issuance proves automation is working.

Delegated challenge zones

If the VPS team should not control the primary DNS account, delegate _acme-challenge with a CNAME or NS record to a small validation zone. Certbot then updates the delegated zone while the main application DNS remains protected under separate credentials.

Understand certificate files and server installation

After issuance, Certbot maintains a certificate lineage and places stable references in /etc/letsencrypt/live/. The usual files are:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • cert.pem: the leaf certificate for your names.
  • chain.pem: the issuing chain.
  • fullchain.pem: the leaf certificate plus chain, normally used by web servers.
  • privkey.pem: the private key, which must remain confidential and readable only by the service that needs it.

For nginx, the TLS directives commonly point to fullchain.pem and privkey.pem. Apache uses the same certificate material, although directive names and file layout depend on the distribution. Never copy the private key into a public document root or commit it to a source-control repository.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Verify HTTPS before considering the setup finished

Check every requested hostname

Visit each name in a browser and with command-line requests. Confirm that the certificate subject or SAN list includes the hostname, the page loads the expected content, and HTTP redirects do not create loops.

curl -I http://example.com
curl -I https://example.com
curl -I https://www.example.com

Mixed-content warnings are separate from certificate issuance: update hard-coded HTTP image, script, stylesheet, and API URLs in the application.

Check the local service configuration

sudo nginx -t
sudo systemctl status nginx
sudo apachectl configtest
sudo systemctl status apache2

Run only the commands for the server you use. A valid certificate can still be unavailable if the service failed to reload or a different virtual host is answering.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Make renewal automatic and test it

Standard Let’s Encrypt certificates last 90 days. Let’s Encrypt explains that this lifetime is intended to encourage automation while remaining practical for manual work: “We chose 90-day lifetimes for our initial offering because ninety days was short enough to strongly encourage automation, but long enough to make it possible to do things manually.” A separate short-lived profile is approximately six days, according to Let’s Encrypt’s published 2026 figures.

Certbot’s renew action examines all previously obtained certificates and renews only those close to expiry. It is designed to run unattended:

sudo certbot renew

Most package installations create either a cron entry or a systemd timer. Inspect the timer and its recent logs:

systemctl list-timers | grep -i certbot
sudo systemctl status certbot.timer
sudo journalctl -u certbot.timer --since "7 days ago"

The decisive test is a dry run, which exercises the renewal workflow without replacing the live certificate:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo certbot renew --dry-run

Run this after initial setup and whenever you change DNS, firewall rules, web-server routing, or DNS API credentials. A successful dry run confirms more than a first issuance: it checks that the stored renewal parameters, challenge path, and plugin can still work.

Reload the web server after renewal when required

Certbot may renew files without an already running service noticing the new certificate. If your configuration does not automatically reload, add a deploy hook that reloads only after a successful renewal. For nginx, test the command manually before automating it:

sudo systemctl reload nginx

Use the corresponding Apache reload command for Apache. Avoid restarting a production service unnecessarily; a graceful reload normally replaces certificate data without dropping established connections.

Troubleshoot the common validation failures

“Timeout during connect” or connection refused

  • Confirm the domain resolves to the VPS from an external network.
  • Open TCP port 80 in the VPS firewall and provider security group.
  • Check that nginx, Apache, or standalone Certbot is listening on the public interface, not only 127.0.0.1.
  • Remove an incorrect AAAA record or configure IPv6 to serve the same challenge.

“Invalid response” for the challenge URL

  • Request the exact path shown by Certbot with curl.
  • Check that a reverse proxy, CDN, authentication rule, or application router is not replacing the token file.
  • Verify that the webroot passed with -w matches the document root for that hostname.
  • Ensure all load-balanced origin servers can serve the same challenge.

Standalone cannot bind port 80

Find and stop the process already listening on port 80, or use webroot mode instead:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo ss -ltnp '( sport = :80 )'

If you keep standalone mode, arrange a controlled stop before every renewal and a start afterward.

DNS-01 TXT record is not found

  • Check the exact owner name, including the _acme-challenge prefix.
  • Wait for authoritative DNS servers to publish the change; local resolver caches can show stale data.
  • Remove obsolete TXT values only when your DNS provider and any concurrent validation attempts permit it.
  • For delegated challenges, verify the CNAME or NS delegation and the target zone’s authority.

The certificate is valid but the browser still warns

Inspect which certificate the server actually sends. Common causes are an old certificate loaded until a reload, a different virtual host selected by SNI, an incomplete chain, or a hostname not included in the certificate. Confirm the live service points to the current fullchain.pem and private key, then perform a graceful reload.

Security and operational practices

  • Use least-privilege DNS API tokens limited to the zone and actions required to manage ACME TXT records.
  • Keep DNS credentials outside web roots and protect credential files with restrictive ownership and permissions.
  • Back up nginx or Apache configuration before installer changes and keep a tested rollback procedure.
  • Monitor renewal logs and certificate expiry; do not rely solely on a browser check performed once.
  • Keep port 80 reachable when using HTTP-01, even if every normal visitor is redirected to HTTPS.
  • Use DNS-01 rather than exposing a private origin solely to satisfy HTTP validation.
  • Do not use manual challenges for a certificate that must renew unattended unless you have implemented and tested an authentication hook.

A minimal decision path

  1. If the public site is on nginx or Apache and port 80 reaches the VPS, use the matching installer plugin.
  2. If the server must remain untouched by Certbot, use certonly --webroot and configure the certificate paths yourself.
  3. If no web server can answer and you can briefly claim port 80, use standalone mode with service stop/start coordination.
  4. If port 80 is unavailable, the origin is private, or you need a wildcard, use DNS-01 with an automated, narrowly scoped DNS credential.
  5. After issuance, verify every hostname, run sudo certbot renew --dry-run, and confirm the renewal timer and reload behavior.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

ApacheCertbotDNS-01HTTPSLet’s EncryptNGINXSSL/TLSVPS

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Recommended PC Tool
Recommended PC Tool
Outdated Drivers Are Slowing You DownFree scan - exact matches
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.