How to Set Up a Custom Domain and HTTPS/SSL for Koha on AWS

Step-by-step guide to pointing a custom domain at your Koha server and enabling free HTTPS/SSL certificates with Let's Encrypt. Covers DNS setup, the koha-setup-domains command, and common pitfalls.

Overview

Whether you can use a custom domain and HTTPS depends on your KohaSupport tier:

Tier Custom Domain HTTPS/SSL
Free Not supported Not supported (HTTP only, port 8080/8090)
Standard Supported Free Let’s Encrypt certificates
Enterprise Supported Free Let’s Encrypt certificates

Free tier instances are accessible via their public IP address on port 8080 (OPAC) and port 8090 (staff). There is no mechanism to attach a custom domain or SSL certificate on Free tier.

Standard and Enterprise tiers include a static Elastic IP and the koha-setup-domains script, which configures Apache virtual hosts and obtains free SSL certificates from Let’s Encrypt automatically. This guide covers that setup process.


Prerequisites

Before you begin, make sure you have all of the following:

  • A registered domain name you control (e.g. mylibrary.org)
  • Access to your domain’s DNS settings — through your registrar or a DNS provider such as Cloudflare, Amazon Route 53, GoDaddy, Namecheap, or similar
  • Your server’s Elastic IP address — a permanent public IP assigned to your instance (see Step 1 below)
  • A running Koha stack — deployed via CloudFormation and accessible via HTTP before you begin

Step 1 — Find Your Elastic IP

Your Koha server is assigned a static Elastic IP when the CloudFormation stack is created. This IP does not change when the instance is stopped and started, which makes it safe to point DNS records at it.

To find it:

  1. Open the AWS CloudFormation console
  2. Click on your Koha stack
  3. Click the Outputs tab
  4. Find the key named ElasticIP — copy that value

It will look like 54.123.45.67. You will use this address for all DNS records in the next step.


Step 2 — Configure DNS Records

Add DNS A records at your DNS provider pointing your chosen subdomains to the Elastic IP. You need records for both your public OPAC (library catalogue) and your staff interface.

Typical setup (two subdomains):

Record type Name Value
A library.yourdomain.com (your Elastic IP)
A staff.yourdomain.com (your Elastic IP)

Both subdomains point to the same Elastic IP — Apache on the server distinguishes between them using the Host header.

You can choose any subdomain names that suit your organisation. Common patterns include:

  • catalog.yourdomain.com / staff.yourdomain.com
  • koha.yourdomain.com / koha-staff.yourdomain.com
  • library.yourdomain.com / library-admin.yourdomain.com

Tip: Set the TTL (Time To Live) to 60 seconds while you are getting set up. A low TTL means DNS changes propagate faster. You can raise it to 3600 (1 hour) once everything is working.

If you use Cloudflare: Make sure the DNS records are set to DNS only (grey cloud), not proxied (orange cloud), during SSL setup. Let’s Encrypt needs to reach your server directly for its HTTP-01 challenge. You can enable the Cloudflare proxy after SSL is working if you wish, but it is not required.

Critical Warning: DNS Must Propagate Before Running SSL Setup

Let’s Encrypt validates that you control your domain by making an HTTP request to your server. If your DNS records have not propagated yet when you run the setup script, the certificate request will fail.

Do not skip ahead. Wait at least 5–15 minutes after creating DNS records and verify propagation before proceeding to Step 4.


Step 3 — Verify DNS Propagation

Use nslookup or dig from your local machine to confirm that your subdomains resolve to your Elastic IP:

nslookup library.yourdomain.com
dig library.yourdomain.com +short

Both commands should return your Elastic IP address. If they return nothing, or return a different IP, DNS has not propagated yet — wait a few more minutes and check again.

You can also use a web-based tool such as dnschecker.org to verify propagation from multiple locations around the world.

Do not proceed until both subdomains resolve correctly.


Step 4 — Connect to Your Server

You need SSH or SSM access to your Koha server to run the domain setup command.

See How to Connect to Your Koha EC2 Server for detailed instructions on both connection methods. SSM Session Manager (no SSH key required) is the recommended approach for Standard and Enterprise tier instances.


Step 5 — Run koha-setup-domains

Once you are connected to your server, run the following command:

sudo koha-setup-domains \
  --opac-domain library.yourdomain.com \
  --staff-domain staff.yourdomain.com \
  --ssl-email [email protected] \
  --enable-ssl

Replace the placeholder values with your actual domains and email address.

Parameter reference:

Parameter Required Description
--opac-domain Yes The subdomain for your public library catalogue (OPAC)
--staff-domain No The subdomain for the staff interface. If omitted, the staff interface remains on port 8080 over HTTP
--ssl-email Yes (with --enable-ssl) Email address Let’s Encrypt uses to send certificate expiry warnings. Use an address you actually monitor.
--enable-ssl No Triggers Let’s Encrypt certificate issuance. Without this flag, the script configures virtual hosts over HTTP only.

What the command does:

  1. Writes Apache virtual host configuration files for your OPAC and staff domains
  2. Reloads Apache to apply the HTTP virtual hosts
  3. Calls certbot to request SSL certificates from Let’s Encrypt for both domains
  4. Rewrites the virtual hosts to redirect HTTP → HTTPS and serve over port 443
  5. Installs a cron job (or systemd timer) for automatic certificate renewal

The command typically completes in 1–3 minutes. You will see certbot output as it contacts Let’s Encrypt and validates your domains.


Step 6 — Verify Your Setup

After the command completes successfully:

Check the OPAC: Visit https://library.yourdomain.com in your browser. You should see the Koha public catalogue with a padlock icon in the address bar.

Check the staff interface: Visit https://staff.yourdomain.com. You should see the Koha staff login page.

Inspect the certificate: Click the padlock icon in your browser’s address bar, then click Certificate (or Connection is secure → Certificate is valid). The issuer should show Let’s Encrypt and the expiry date should be approximately 90 days from today.

Confirm auto-renewal is configured: Let’s Encrypt certificates expire every 90 days. The setup script installs automatic renewal — certificates are renewed when they are within 30 days of expiry, so in practice they renew roughly every 60 days. You do not need to do anything manually.

To test that renewal would succeed without actually renewing:

sudo certbot renew --dry-run

A successful dry run means auto-renewal is working correctly.


Using Only One Domain (OPAC-only SSL)

If your library does not need a publicly accessible staff interface, or you prefer to keep the staff interface on the internal port, you can set up SSL for the OPAC only:

sudo koha-setup-domains \
  --opac-domain library.yourdomain.com \
  --ssl-email [email protected] \
  --enable-ssl

Omitting --staff-domain leaves the staff interface accessible on HTTP at port 8080. This is a valid and simpler configuration for many smaller libraries where staff access the system from the same network or via VPN.


CloudFormation SSL Parameters vs. Manual Setup

The KohaSupport CloudFormation template includes EnableSSL, OPACDomain, and StaffDomain parameters. When provided at stack launch time and DNS is already configured, these automate the SSL setup as part of the initial boot sequence.

If you did not fill in those parameters at launch time, or if the automated setup failed (most commonly because DNS was not ready yet when the instance first booted), use the manual koha-setup-domains approach described in this guide — the result is identical.

Do Not Update the Stack to Enable SSL

Warning: Do not update your running CloudFormation stack to change SSL-related parameters after the instance is already running.

Updating the ImageId parameter or other instance-level parameters triggers a stack update that replaces the EC2 instance. This means:

  • Your Elastic IP is retained
  • Data on the data volume (including library records) is preserved
  • But your SSL certificates and any manual configuration changes will need to be re-applied after the new instance boots

If you need to enable SSL on a running instance, always use the koha-setup-domains command over SSH or SSM — never a stack parameter update.


Troubleshooting

“Failed authorization procedure” or “certbot: error: Failed authorization”

Let’s Encrypt could not verify that you control the domain. This almost always means DNS has not propagated yet.

Fix: Wait 15 minutes, verify with nslookup or dig that your domains resolve to your Elastic IP, then re-run the koha-setup-domains command.

Also check that your Cloudflare proxy (if applicable) is disabled — set records to “DNS only” (grey cloud) during SSL setup.

“Connection refused” on port 443

Your server’s EC2 security group may not have port 443 open.

Fix:

  1. Go to the EC2 console → your instance → Security tab
  2. Click the security group name
  3. Check Inbound rules — you should see a rule allowing HTTPS (TCP port 443) from 0.0.0.0/0
  4. If the rule is missing, add it: Type = HTTPS, Protocol = TCP, Port range = 443, Source = 0.0.0.0/0

After updating the security group, retry the koha-setup-domains command.

“Certificate has expired” / HTTPS stops working

Auto-renewal failed. This is usually caused by a temporary network issue or a DNS change that blocked the renewal challenge.

Diagnose:

sudo certbot renew --dry-run

Check the output for error messages. The full log is at:

sudo cat /var/log/letsencrypt/letsencrypt.log

Common causes include: port 80 blocked by security group, domain no longer resolving to the server, or Cloudflare proxy enabled (which intercepts the HTTP-01 challenge). Fix the underlying issue, then run:

sudo certbot renew

“I lost my SSL certificate after the instance was replaced”

On Standard and Enterprise tiers, SSL certificates are stored on the persistent data volume at /kohadata/ssl/. When the instance is replaced (e.g. due to a stack update or AMI upgrade), the new instance mounts the same data volume and should restore the certificates automatically on boot.

If the certificates did not restore, re-run koha-setup-domains with your domain parameters — it will obtain fresh certificates from Let’s Encrypt. The process takes under 2 minutes and does not affect your library data.

Redirect loop or “too many redirects”

This can occur when Cloudflare’s SSL mode is set to “Flexible” while your server also enforces HTTPS. Cloudflare in Flexible mode makes HTTP requests to your origin while presenting HTTPS to browsers — your server sees HTTP and redirects back to HTTPS, creating a loop.

Fix: In Cloudflare’s SSL/TLS settings, change the encryption mode from Flexible to Full (or Full (strict)).

Next Steps

More in AWS & Deployment

Was this article helpful?

Thanks for your feedback!