This episode manages TLS and certificates on Alpine: OpenSSL 3 as the default, installing ca-certificates and running update-ca-certificates, generating keys and CSRs, installing Let's Encrypt certificates with certbot or acme.sh, and the fundamentals of PKI.

Almost every modern service runs on TLS, and Alpine provides complete cryptographic tooling. Episode 15 covers OpenSSL 3 as Alpine's default, CA bundle management, generating keys and CSRs, issuing Let's Encrypt certificates, and the fundamentals of PKI.
In episode 11, the nginx virtual host used HTTP on port 80. This episode turns it into HTTPS: you'll install a certificate, secure the nginx configuration, and understand how the chain of trust works.
Since Alpine 3.14, OpenSSL 3 has been the default — bringing a new API and stricter security policies. The CA certificate bundle is managed via the ca-certificates package:
apk add openssl ca-certificates
openssl version
update-ca-certificatesExplanation:
openssl version shows the OpenSSL 3 version.update-ca-certificates rebuilds the CA bundle from the /usr/share/ca-certificates and /etc/ssl/certs directories.Check that the CA bundle is valid:
ls -la /etc/ssl/certs/ca-certificates.crt
getent hosts alpinelinux.orgThe ca-certificates.crt bundle is the file applications use to verify server certificates.
When you need a certificate for internal use or testing, create a key and a Certificate Signing Request (CSR):
mkdir -p /etc/ssl/private
openssl genrsa -out /etc/ssl/private/example.key 4096
openssl req -new -key /etc/ssl/private/example.key \
-out /etc/ssl/example.csr \
-subj "/CN=example.com/O=Example Org/C=ID"Then submit the CSR to an internal or public CA, and bundle the received certificate:
openssl x509 -req -in /etc/ssl/example.csr \
-signkey /etc/ssl/private/example.key \
-out /etc/ssl/example.crt -days 365openssl x509 -req -in ... -signkey ... creates a self-signed certificate for quick testing. Never use self-signed certificates in public production.
For public certificates trusted by every browser, use Let's Encrypt. Alpine provides certbot and acme.sh in its repositories:
apk add certbot certbot-nginx
certbot --nginx -d example.comcertbot --nginx -d example.com issues the certificate and configures nginx automatically. A lightweight alternative uses acme.sh:
apk add acme.sh
acme.sh --issue --standalone -d example.comThe generated certificates live in acme.sh's installation directory; then install them in nginx.
Understanding PKI (Public Key Infrastructure) helps you read TLS configurations:
Inspect the installed certificate:
openssl x509 -in /etc/ssl/example.crt -text -noout | head -20
openssl s_client -connect example.com:443 </dev/null 2>/dev/null | openssl x509 -noout -datesopenssl s_client -connect example.com:443 reads the certificate directly from the server, useful for checking validity from outside.
Update the virtual host from episode 11 with an SSL block:
server {
listen 443 ssl;
server_name example.com;
root /var/www/app;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
}Validate and reload:
nginx -t
rc-service nginx reloadMake sure automatic renewal is running — Let's Encrypt certificates are valid for 90 days:
certbot renew --dry-run
crontab -lThe certbot renew --dry-run schedule verifies that automatic renewal works.
Warning
Never share your private key. Keep it in /etc/ssl/private with root-only permissions, and make sure no other process can read that directory.
Episode 15 managed TLS and certificates on Alpine: OpenSSL 3 and ca-certificates, generating keys and CSRs, issuing Let's Encrypt certificates with certbot and acme.sh, PKI fundamentals, and applying HTTPS in nginx.
Key takeaways:
In the next episode, episode 16, we'll cover container runtimes: Docker and Podman — installing Docker on Alpine, using the daemonless Podman, building images from the alpine base, and multi-stage build techniques with apk --no-cache.