{"id":59,"date":"2026-10-18T17:29:30","date_gmt":"2026-10-18T17:29:30","guid":{"rendered":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/?p=59"},"modified":"2026-10-18T17:29:31","modified_gmt":"2026-10-18T17:29:31","slug":"how-to-install-a-free-ssl-on-a-server","status":"publish","type":"post","link":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/how-to-install-a-free-ssl-on-a-server\/","title":{"rendered":"How to install a free SSL on a server"},"content":{"rendered":"\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"775\" height=\"337\" src=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/image7.png\" alt=\"\" class=\"wp-image-60\" srcset=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/image7.png 775w, https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/image7-300x130.png 300w, https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/image7-766x333.png 766w\" sizes=\"auto, (max-width: 775px) 100vw, 775px\" \/><figcaption class=\"wp-element-caption\"><strong>The \u201cNot secure\u201d warning before installing SSL<\/strong><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">What exactly is an SSL?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">An SSL certificate is basically a small file that sits on your server and lets your website load over HTTPS instead of HTTP. In simple terms, it locks the connection between your website and the person visiting it, so nobody can read or change what passes between them.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your website doesn\u2019t have one, browsers like Chrome show a \u201cNot secure\u201d warning next to your domain name. Visitors see it before they see anything else on your site, and it usually leads to most leaving before a single page even loads.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your hosting comes with cPanel, adding an SSL is easy. You literally just click a button and it\u2019s done. But if you\u2019re running your own server without a control panel, there\u2019s no button to click. You have to set it up yourself from the command line.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That sounds harder than it is. In this post, I\u2019ll show you exactly how I did it for my own website, step by step, using a free certificate from Let\u2019s Encrypt.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">What you need before you start<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before you run any command, make sure you have these five things in place. If one is missing, the certificate will fail.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>A server you own (a VPS or a dedicated server).<\/strong> This guide is for servers without a control panel, so you need a VPS or dedicated server where you have full control. If you don\u2019t have one yet, you can buy one from Hostinger or TK webhosts.<\/li>\n\n\n\n<li><strong>A server with SSH access.<\/strong> You should be able to log in and run commands with sudo. In this post I\u2019m using a Debian server, and the same commands work on Ubuntu.<\/li>\n\n\n\n<li><strong>A web server that\u2019s already running.<\/strong> I\u2019m using Apache, and my website was already loading over http before I started. If your site doesn\u2019t load at all yet, fix that first.<\/li>\n\n\n\n<li><strong>A domain pointing to your server.<\/strong> The domain\u2019s A record must point to your server\u2019s IP address. Let\u2019s Encrypt checks this before it gives you a certificate. If the domain isn\u2019t pointing to the server, the process will fail.<\/li>\n\n\n\n<li><strong>Ports 80 and 443 open.<\/strong> Port 80 is used to verify your domain, and port 443 is what HTTPS runs on. Most servers have them open by default, but if you set up a firewall, check them.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">An easy way to check items 3 to 5 is to type your domain into a browser first. If your site loads (even with the \u201cNot secure\u201d warning), it means that your domain, web server and port 80 are working.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">Step 1: Connect to your server from PowerShell<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You don\u2019t need to install anything to connect to your server if you\u2019re on Windows 10 or 11. PowerShell already has an SSH client built in.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Search for PowerShell in the Start menu and open it.<\/li>\n\n\n\n<li>Type this command and press Enter:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh username@your-server-ip<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Replace <code>username<\/code> with your server username and <code>your-server-ip<\/code> with your server\u2019s IP address. Your hosting provider usually sends these to you.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If it\u2019s your first time connecting, PowerShell will ask if you trust the server. Type <code>yes<\/code> and press Enter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Enter your password when it asks. You won\u2019t see anything as you type, not even dots. That\u2019s normal, just type it and press Enter.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"104\" src=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-2.png\" alt=\"\" class=\"wp-image-65\" srcset=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-2.png 512w, https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-2-300x61.png 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><figcaption class=\"wp-element-caption\"><strong>Logged in to the server from PowerShell<\/strong><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">Step 2: Update your server and install Certbot<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Certbot is the free tool that gets the SSL certificate from Let\u2019s Encrypt and installs it for you. Before installing it, update your server\u2019s package list so you get the latest version.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Run this first:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When it finishes, install Certbot and its Apache plugin:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install certbot python3-certbot-apache -y<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>-y<\/code> at the end just answers \u201cyes\u201d to any question the installer asks, so you don\u2019t have to type it yourself.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The Apache plugin is what lets Certbot edit your Apache settings for you, so you don\u2019t have to do it by hand. If you\u2019re using Nginx, you\u2019d install <code>python3-certbot-nginx<\/code> instead.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The installation prints a lot of text, so don\u2019t worry if your screen fills up. Scroll to the bottom and look for a line that mentions <code>certbot.timer<\/code>. That\u2019s the automatic renewal setup, and it means your certificate will renew itself later without you doing anything.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full is-resized\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"77\" src=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-1-1.png\" alt=\"\" class=\"wp-image-66\" style=\"width:501px;height:auto\" srcset=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-1-1.png 512w, https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-1-1-300x45.png 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">Step 3: Check your Apache virtual host<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Certbot needs to know which website the certificate is for. It finds this in your Apache virtual host file, so check that it\u2019s set up properly before you run it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">First, list the sites Apache is serving:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ls \/etc\/apache2\/sites-enabled\/<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see a file named after your site, like <code>yourdomain.conf<\/code>. Open it with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cat \/etc\/apache2\/sites-enabled\/yourdomain.conf<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Look for these lines:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&lt;VirtualHost *:80&gt;\n    ServerName yourdomain.com\n    ServerAlias www.yourdomain.com\n    DocumentRoot \/var\/www\/yourdomain\n&lt;\/VirtualHost&gt;<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">What matters here:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>ServerName<\/code> must be your exact domain.<\/li>\n\n\n\n<li><code>ServerAlias<\/code> should be the www version of your domain. Without it, the certificate won\u2019t cover www.<\/li>\n\n\n\n<li><code>&lt;VirtualHost *:80&gt;<\/code> means the site is listening on port 80, which is where Certbot starts from.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">If the ServerName is wrong or the file doesn\u2019t exist, fix that first. Certbot can\u2019t guess it for you.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>NB:<\/strong> mine is tbtutors.ng, yours will be different.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"78\" src=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-2-1.png\" alt=\"\" class=\"wp-image-67\" srcset=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-2-1.png 512w, https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-2-1-300x46.png 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><figcaption class=\"wp-element-caption\"><strong>The<\/strong> <strong>certbot.timer<\/strong> <strong>line confirms auto-renewal is set up&nbsp;<\/strong><br><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">Step 4: Check that your domain points to your server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s Encrypt only gives a certificate to a domain that actually points to your server. So before you run Certbot, confirm your domain is pointing to the right IP address.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The tool for this is <code>dig<\/code>, but it doesn\u2019t come installed on a fresh Debian server. If you type <code>dig<\/code> and see \u201ccommand not found\u201d, install it with:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt install dnsutils -y<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now check what IP your domain points to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>dig +short yourdomain.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then check your server\u2019s own public IP:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>curl -4 ifconfig.me<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Both should show the same IP address. If they match, you\u2019re good to go.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If <code>dig<\/code> shows nothing, don\u2019t panic yet. Open your domain in a browser. If your website loads, the DNS is working, and you can also check it on a site like whatsmydns.net. If the site doesn\u2019t load, go to wherever you manage your domain and add an A record pointing to your server\u2019s IP, then wait a little for it to update before you continue.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"67\" src=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-4.png\" alt=\"\" class=\"wp-image-68\" srcset=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-4.png 512w, https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-4-300x39.png 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><figcaption class=\"wp-element-caption\"><strong>The<\/strong> <strong>dig<\/strong> <strong>error on a fresh server<\/strong><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">Step 5: Run Certbot<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is the step that gets your certificate. Run this command, and replace the domain with yours:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot --apache -d yourdomain.com -d www.yourdomain.com<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>-d<\/code> flag tells Certbot which domains the certificate is for. Add one for the main domain and one for the www version.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Certbot will then ask you a few questions:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Email address.<\/strong> This is where Let\u2019s Encrypt sends a warning if your certificate is about to expire and fails to renew. Use an email you check.<\/li>\n\n\n\n<li><strong>Terms of Service.<\/strong> Type <code>Y<\/code> and press Enter to agree. You can\u2019t continue without it.<\/li>\n\n\n\n<li><strong>Share your email with the EFF (optional).<\/strong> You can type <code>N<\/code> if you don\u2019t want their updates.<\/li>\n\n\n\n<li><strong>Redirect HTTP to HTTPS.<\/strong> If it asks, choose the redirect option, so anyone who opens the http version of your site is sent to the https version automatically.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">After a few seconds, you\u2019ll see a message saying the certificate was successfully deployed for both domains. It also shows the date the certificate expires. Mine expires on 23 December 2026, which is about 90 days, and Certbot renews it before then.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"86\" src=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-5.png\" alt=\"\" class=\"wp-image-69\" srcset=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-5.png 512w, https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-5-300x50.png 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><figcaption class=\"wp-element-caption\"><strong>Running the Certbot command<\/strong><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">Step 6: Check that HTTPS is working<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Certbot said the certificate was installed, but it\u2019s worth checking for yourself.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Open your site in a browser.<\/strong> Type <code>https:\/\/yourdomain.com<\/code> in the address bar. You should see a padlock icon next to the domain, and the \u201cNot secure\u201d warning should be gone. Click the padlock to see the certificate details, including who issued it (Let\u2019s Encrypt) and when it expires.<\/li>\n\n\n\n<li><strong>Check the www version too.<\/strong> Open <code>https:\/\/www.yourdomain.com<\/code>. You asked for both in the Certbot command, so both should show the padlock.<\/li>\n\n\n\n<li><strong>Check the certificate from the server.<\/strong> Go back to your PowerShell window and run:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot certificates<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This lists every certificate on your server, the domains it covers, and the expiry date. Mine shows tbtutors.ng and www.tbtutors.ng, valid until 23 December 2026.<\/p>\n\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li><strong>Check what happens on http.<\/strong> Open <code>http:\/\/yourdomain.com<\/code> (without the s). If it jumps to https on its own, the redirect is working. If it stays on http, don\u2019t worry, we\u2019ll fix that in the next step.<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"36\" src=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-6.png\" alt=\"\" class=\"wp-image-70\" srcset=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-6.png 512w, https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-6-300x21.png 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><figcaption class=\"wp-element-caption\"><strong>Checking the certificate from the server\u00a0<\/strong><br><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">Step 7: Force HTTPS and update WordPress<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This step is only for WordPress sites. If your site isn\u2019t on WordPress, you can skip to Step 8.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Even with the certificate installed, WordPress may still think your site lives at the http address. Update that so every page loads over https.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>1. Change your site URLs.<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Log in to wp-admin and go to <strong>Settings &gt; General<\/strong>.<\/li>\n\n\n\n<li>Change both <strong>WordPress Address (URL)<\/strong> and <strong>Site Address (URL)<\/strong> from <code>http:\/\/<\/code> to <code>https:\/\/<\/code>.<\/li>\n\n\n\n<li>Click <strong>Save Changes<\/strong>. You\u2019ll be logged out, so log back in.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>2. Make sure http goes to https.<\/strong> Open <code>http:\/\/yourdomain.com<\/code> in a browser. If it jumps to https, you\u2019re done with this part. If it stays on http, install the free Really Simple SSL plugin, activate it, and click the button it shows to enable SSL. It adds the redirect for you.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>3. Look out for mixed content.<\/strong> Sometimes a page loads over https but still pulls an image or script from an old http link. The browser then shows a warning or removes the padlock. Open your main pages (home, blog, contact) and check that the padlock is still there. Really Simple SSL fixes most of these for you. For the rest, edit the page and change the <code>http:\/\/<\/code> link to <code>https:\/\/<\/code>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"70\" src=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-7.png\" alt=\"\" class=\"wp-image-71\" srcset=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-7.png 512w, https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-7-300x41.png 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><figcaption class=\"wp-element-caption\"><strong>Both URLs now start with https<\/strong><\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">Step 8: Test automatic renewal<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s Encrypt certificates only last 90 days. You don\u2019t have to renew them by hand, because Certbot set up a timer when you installed it. It checks twice a day and renews the certificate when it\u2019s close to expiring.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can test this without changing your real certificate. Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo certbot renew --dry-run<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This does a practice run of the renewal. At the end, you should see a message saying all simulated renewals succeeded. If you see that, your certificate will renew by itself when the time comes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you want to confirm the timer is running, use:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>systemctl list-timers | grep certbot<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see <code>certbot.timer<\/code> listed with the time of its next run.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s all for renewal. You don\u2019t need to do anything else, but it\u2019s a good idea to use an email address you check, since Let\u2019s Encrypt sends a warning there if a renewal ever fails.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"512\" height=\"92\" src=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-8.png\" alt=\"\" class=\"wp-image-72\" srcset=\"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-8.png 512w, https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-content\/uploads\/sites\/3\/2026\/10\/unnamed-8-300x54.png 300w\" sizes=\"auto, (max-width: 512px) 100vw, 512px\" \/><figcaption class=\"wp-element-caption\"><strong>The dry run passes<\/strong><\/figcaption><\/figure>\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">Common mistakes and how to fix them<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">These are the problems I ran into, plus a few others to watch for.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:clamp(15.747px, 0.984rem + ((1vw - 3.2px) * 0.96), 24px);font-weight:600\">1. dig: command not found<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>dig<\/code> doesn\u2019t come installed on a fresh Debian server. Install it with <code>sudo apt install dnsutils -y<\/code>, then run the command again.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:clamp(15.747px, 0.984rem + ((1vw - 3.2px) * 0.96), 24px);font-weight:600\">2. The output looks wrong or empty<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When I pasted several commands at once, the results ran together and it looked like my domain had no DNS record. It didn\u2019t. Paste and run one command at a time, so each result shows on its own line.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:clamp(15.747px, 0.984rem + ((1vw - 3.2px) * 0.96), 24px);font-weight:600\">3. Certbot skips a question or you answer it too fast<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Certbot asks for your email and for you to agree to the terms. If you hit Enter too quickly, it may skip the email. You can\u2019t continue without agreeing to the terms, so type <code>Y<\/code> when asked. To add or change your email later, run <code>sudo certbot update_account --email you@example.com<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:clamp(15.747px, 0.984rem + ((1vw - 3.2px) * 0.96), 24px);font-weight:600\">4. Certbot says it can\u2019t verify your domain<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This usually means your domain isn\u2019t pointing to your server yet, or port 80 is blocked. Go back to Step 4 and make sure your domain points to your server\u2019s IP. Then check that your firewall allows ports 80 and 443.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:clamp(15.747px, 0.984rem + ((1vw - 3.2px) * 0.96), 24px);font-weight:600\">5. Certbot can\u2019t find your site<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This happens when there\u2019s no virtual host with your domain as the ServerName. Go back to Step 3 and check your config file.<\/p>\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">Common mistakes and how to fix them<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">These are the problems I ran into, plus a few others to watch for.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:clamp(15.747px, 0.984rem + ((1vw - 3.2px) * 0.96), 24px);font-weight:600\">1. dig: command not found<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\"><code>dig<\/code> doesn\u2019t come installed on a fresh Debian server. Install it with <code>sudo apt install dnsutils -y<\/code>, then run the command again.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:clamp(15.747px, 0.984rem + ((1vw - 3.2px) * 0.96), 24px);font-weight:600\">2. The output looks wrong or empty<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">When I pasted several commands at once, the results ran together and it looked like my domain had no DNS record. It didn\u2019t. Paste and run one command at a time, so each result shows on its own line.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:clamp(15.747px, 0.984rem + ((1vw - 3.2px) * 0.96), 24px);font-weight:600\">3. Certbot skips a question or you answer it too fast<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Certbot asks for your email and for you to agree to the terms. If you hit Enter too quickly, it may skip the email. You can\u2019t continue without agreeing to the terms, so type <code>Y<\/code> when asked. To add or change your email later, run <code>sudo certbot update_account --email you@example.com<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:clamp(15.747px, 0.984rem + ((1vw - 3.2px) * 0.96), 24px);font-weight:600\">4. Certbot says it can\u2019t verify your domain<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This usually means your domain isn\u2019t pointing to your server yet, or port 80 is blocked. Go back to Step 4 and make sure your domain points to your server\u2019s IP. Then check that your firewall allows ports 80 and 443.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:clamp(15.747px, 0.984rem + ((1vw - 3.2px) * 0.96), 24px);font-weight:600\">5. Certbot can\u2019t find your site<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">This happens when there\u2019s no virtual host with your domain as the ServerName. Go back to Step 3 and check your config file.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" style=\"font-size:clamp(15.747px, 0.984rem + ((1vw - 3.2px) * 0.96), 24px);font-weight:600\">6. The padlock disappears on some pages<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s mixed content, an old <code>http:\/\/<\/code> link on the page. Check Step 7 for the fix.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" style=\"font-size:clamp(20px, 1.25rem + ((1vw - 3.2px) * 1.395), 32px);font-weight:700\">Conclusion<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">That\u2019s all it takes to add a free SSL to a server without cPanel. You connected to your server, installed Certbot, checked your Apache setup and domain, ran one command to get the certificate, and tested that it renews itself.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Your website now loads over HTTPS, the \u201cNot secure\u201d warning is gone, and you don\u2019t have to touch the certificate again for about 90 days. After that, Certbot takes care of it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To be sure everything is set up properly, run your domain through a free SSL checker like SSL Labs. It tests the certificate and tells you if anything is wrong.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If you got stuck at any point, check the common mistakes section above. And if you have a question, leave it in the comments.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>What exactly is an SSL? An SSL certificate is basically a small file that sits on your server and lets your website load over&hellip;<\/p>\n","protected":false},"author":8,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-59","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-json\/wp\/v2\/posts\/59","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-json\/wp\/v2\/comments?post=59"}],"version-history":[{"count":1,"href":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-json\/wp\/v2\/posts\/59\/revisions"}],"predecessor-version":[{"id":73,"href":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-json\/wp\/v2\/posts\/59\/revisions\/73"}],"wp:attachment":[{"href":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-json\/wp\/v2\/media?parent=59"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-json\/wp\/v2\/categories?post=59"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tkwebhosts.com\/ng\/tutorials\/wp-json\/wp\/v2\/tags?post=59"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}