diff --git a/letsencrypt/CHANGELOG.md b/letsencrypt/CHANGELOG.md
index 2dd8792e95f..ed6667b0a61 100644
--- a/letsencrypt/CHANGELOG.md
+++ b/letsencrypt/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## 5.3.0
+
+- Add Loopia DNS support
+
## 5.2.3
- Fix syntax error in run script
diff --git a/letsencrypt/DOCS.md b/letsencrypt/DOCS.md
index 02ae30d4c09..da8ec988a58 100644
--- a/letsencrypt/DOCS.md
+++ b/letsencrypt/DOCS.md
@@ -59,6 +59,7 @@ dns-infomaniak
dns-ionos
dns-joker
dns-linode
+dns-loopia
dns-luadns
dns-njalla
dns-noris
@@ -118,6 +119,8 @@ joker_password: ''
joker_domain: ''
linode_key: ''
linode_version: ''
+loopia_username: ''
+loopia_password: ''
luadns_email: ''
luadns_token: ''
njalla_token: ''
@@ -567,6 +570,33 @@ To use this addon with Linode DNS, first [create a new API/access key](https://w
+
+ Loopia
+
+To use this addon with Loopia DNS, first [create a new API user](https://customerzone.loopia.com/api/), with the following minimum required permissions:
+
+- `addZoneRecord` - Required to create DNS records
+- `getZoneRecords` - Required to verify DNS records
+- `removeZoneRecord` - Required to clean up DNS records
+- `removeSubdomain` - Required for complete cleanup
+
+Example configuration in YAML edit mode:
+
+```yaml
+email: you@mailprovider.com
+domains:
+ - ha.yourdomain.com
+certfile: fullchain.pem
+keyfile: privkey.pem
+challenge: dns
+dns:
+ provider: dns-loopia
+ loopia_username: example@loopiaapi
+ loopia_password: supersecretpasswordhere
+```
+
+
+
DirectAdmin
@@ -1075,6 +1105,7 @@ dns-hetzner
dns-infomaniak
dns-ionos
dns-linode
+dns-loopia
dns-luadns
dns-njalla
dns-noris
diff --git a/letsencrypt/Dockerfile b/letsencrypt/Dockerfile
index 896ae5fb921..a9f15441c5a 100644
--- a/letsencrypt/Dockerfile
+++ b/letsencrypt/Dockerfile
@@ -21,6 +21,7 @@ ARG \
CERTBOT_DNS_INWX_VERSION \
CERTBOT_DNS_IONOS_VERSION \
CERTBOT_DNS_JOKER_VERSION \
+ CERTBOT_DNS_LOOPIA_VERSION \
CERTBOT_DNS_NAMECHEAP_VERSION \
CERTBOT_DNS_NORISNETWORK_VERSION \
CERTBOT_DNS_SIMPLY_VERSION \
@@ -70,6 +71,7 @@ RUN \
certbot-dns-ionos==${CERTBOT_DNS_IONOS_VERSION} \
certbot-dns-joker==${CERTBOT_DNS_JOKER_VERSION} \
certbot-dns-linode==${CERTBOT_VERSION} \
+ certbot-dns-loopia==${CERTBOT_DNS_LOOPIA_VERSION} \
certbot-dns-luadns==${CERTBOT_VERSION} \
certbot-dns-njalla==${CERTBOT_NJALLA_VERSION} \
certbot-dns-norisnetwork==${CERTBOT_DNS_NORISNETWORK_VERSION} \
diff --git a/letsencrypt/build.yaml b/letsencrypt/build.yaml
index 5b5088eb0d6..40958868ec9 100644
--- a/letsencrypt/build.yaml
+++ b/letsencrypt/build.yaml
@@ -25,6 +25,7 @@ args:
CERTBOT_DNS_INWX_VERSION: 2.2.0
CERTBOT_DNS_IONOS_VERSION: 2024.1.8
CERTBOT_DNS_JOKER_VERSION: 1.1.0
+ CERTBOT_DNS_LOOPIA_VERSION: 1.0.1
CERTBOT_DNS_NAMECHEAP_VERSION: 1.0.0
CERTBOT_DNS_NORISNETWORK_VERSION: 0.2.1
CERTBOT_DNS_TRANSIP_VERSION: 0.5.2
diff --git a/letsencrypt/config.yaml b/letsencrypt/config.yaml
index 17afa8fdea8..88181e4ca84 100644
--- a/letsencrypt/config.yaml
+++ b/letsencrypt/config.yaml
@@ -1,5 +1,5 @@
---
-version: 5.2.3
+version: 5.3.0
slug: letsencrypt
name: Let's Encrypt
description: Manage certificate from Let's Encrypt
@@ -75,6 +75,8 @@ schema:
ionos_endpoint: str?
linode_key: str?
linode_version: str?
+ loopia_username: str?
+ loopia_password: str?
luadns_email: email?
luadns_token: str?
joker_username: str?
@@ -103,7 +105,7 @@ schema:
provider: "list(dns-azure|dns-cloudflare|dns-cloudns|dns-desec|\
dns-digitalocean|dns-directadmin|dns-dnsimple|dns-dnsmadeeasy|\
dns-duckdns|dns-dynu|dns-gehirn|dns-godaddy|dns-google|\
- dns-hetzner|dns-infomaniak|dns-ionos|dns-joker|dns-linode|dns-luadns|dns-njalla|dns-nsone|\
+ dns-hetzner|dns-infomaniak|dns-ionos|dns-joker|dns-linode|dns-loopia|dns-luadns|dns-njalla|dns-nsone|\
dns-porkbun|dns-ovh|dns-rfc2136|dns-route53|dns-sakuracloud|\
dns-namecheap|dns-netcup|dns-simply|dns-gandi|dns-transip|dns-inwx|dns-dreamhost|\
dns-he|dns-easydns|dns-domainoffensive|dns-websupport|dns-noris|dns-plesk)?"
diff --git a/letsencrypt/rootfs/etc/cont-init.d/file-structure.sh b/letsencrypt/rootfs/etc/cont-init.d/file-structure.sh
index 42c5c1390dc..c06ebfcbb76 100755
--- a/letsencrypt/rootfs/etc/cont-init.d/file-structure.sh
+++ b/letsencrypt/rootfs/etc/cont-init.d/file-structure.sh
@@ -33,6 +33,8 @@ echo -e "dns_desec_token = $(bashio::config 'dns.desec_token')\n" \
"dns_plesk_api_url = $(bashio::config 'dns.plesk_api_url')\n" \
"dns_linode_key = $(bashio::config 'dns.linode_key')\n" \
"dns_linode_version = $(bashio::config 'dns.linode_version')\n" \
+ "dns_loopia_username = $(bashio::config 'dns.loopia_username')\n" \
+ "dns_loopia_password = $(bashio::config 'dns.loopia_password')\n" \
"dns_luadns_email = $(bashio::config 'dns.luadns_email')\n" \
"dns_luadns_token = $(bashio::config 'dns.luadns_token')\n" \
"dns_namecheap_username = $(bashio::config 'dns.namecheap_username')\n" \
diff --git a/letsencrypt/rootfs/etc/services.d/lets-encrypt/run b/letsencrypt/rootfs/etc/services.d/lets-encrypt/run
index 6cb87e7b46d..193562fbb45 100755
--- a/letsencrypt/rootfs/etc/services.d/lets-encrypt/run
+++ b/letsencrypt/rootfs/etc/services.d/lets-encrypt/run
@@ -164,6 +164,16 @@ elif [ "${CHALLENGE}" == "dns" ] && [ "${DNS_PROVIDER}" == "dns-joker" ]; then
bashio::config.require 'dns.joker_password'
PROVIDER_ARGUMENTS+=("--authenticator" "${DNS_PROVIDER}" "--${DNS_PROVIDER}-credentials" "/data/dnsapikey" "--${DNS_PROVIDER}-propagation-seconds" "${PROPAGATION_SECONDS}")
+# Loopia
+elif [ "${CHALLENGE}" == "dns" ] && [ "${DNS_PROVIDER}" == "dns-loopia" ]; then
+ bashio::config.require 'dns.loopia_username'
+ bashio::config.require 'dns.loopia_password'
+ if (( PROPAGATION_SECONDS < 900 )); then
+ bashio::log.info "Increasing DNS propagation limit for Loopia to at least 900 seconds due to caching issues."
+ PROPAGATION_SECONDS=900
+ fi
+ PROVIDER_ARGUMENTS+=("--authenticator" "${DNS_PROVIDER}" "--${DNS_PROVIDER}-credentials" "/data/dnsapikey" "--${DNS_PROVIDER}-propagation-seconds" "${PROPAGATION_SECONDS}")
+
# Plesk
elif [ "${CHALLENGE}" == "dns" ] && [ "${DNS_PROVIDER}" == "dns-plesk" ]; then
bashio::config.require 'dns.plesk_username'