# Custom actions with Virtualmin's Letsencypt renewals?

**URL:** <https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248>\
**Category:** Virtualmin\
**Created:** [December 24, 2024, 9:18pm UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248 "2024-12-24T21:18:45Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Brook](https://cdn.forum.virtualmin.com/letter_avatar_proxy/v4/letter/b/41988e/32.png) [@Brook](https://forum.virtualmin.com/u/Brook)\
**Post date:** [December 24, 2024, 9:18pm UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/1 "2024-12-24T21:18:45Z")

</div>

Are there any guides or threads with details on how to configure Virtualmin’s Letsencypt script to run custom commands when any certs are renewed?

I just need to copy the certs to:

```plaintext
	DOMAIN='NAMEHERE.com' sudo -E bash -c 'cat /etc/letsencrypt/live/$DOMAIN/fullchain.pem /etc/letsencrypt/live/$DOMAIN/privkey.pem > /etc/haproxy/certs/$DOMAIN.pem'
	systemctl restart haproxy

```

Or should I just look-up the standard letsencrypt guides and then Virtualmin will automatically pick up those commands?

---

<div class="post-metadata">

**Author:** ![Joe](https://cdn.forum.virtualmin.com/user_avatar/forum.virtualmin.com/joe/32/9_2.png) [@Joe](https://forum.virtualmin.com/u/Joe)\
**Post date:** [December 24, 2024, 10:09pm UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/2 "2024-12-24T22:09:51Z")

</div>

> [@Brook](#):
>
> Or should I just look-up the standard letsencrypt guides and then Virtualmin will automatically pick up those commands?

Definitely not this. Virtualmin calls `certbot`, and then does stuff with the resulting certs, not the other way around.

[Virtualmin has pre and post hooks](https://www.virtualmin.com/docs/development/domain-management-api/), though, so you can write scripts in whatever language you like (including bash shell scripts) to run before or after changes. Renewing certs is a change, and the hook runs. To know if it’s a TLS cert change, you’d check for `SSL_DOMAIN`.

There’s an example of copying certs for a service not supported directly by Virtualmin here: [Domain Management API | Virtualmin — Open Source Web Hosting Control Panel](https://www.virtualmin.com/docs/development/domain-management-api/#update-ssl-certificate-for-prosody)

So, you could base your post script on that, and then configure Virtualmin to run it in Virtualmin Configuration-\>Actions upon server and user creation-\>Command to run after making changes to a server

---

<div class="post-metadata">

**Author:** ![Brook](https://cdn.forum.virtualmin.com/letter_avatar_proxy/v4/letter/b/41988e/32.png) [@Brook](https://forum.virtualmin.com/u/Brook)\
**Post date:** [December 25, 2024, 12:22am UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/3 "2024-12-25T00:22:13Z")

</div>

Thanks Joe!

So to confirm I’d need to:

Create script `copy-cert-to-haproxy.sh`:

```auto
#!/bin/bash
if ["$VIRTUALSERVER_ACTION" = "SSL_DOMAIN"] || ["$VIRTUALSERVER_ACTION" = "CREATE_DOMAIN"]; then
  /usr/bin/cat "/home/$VIRTUALSERVER_DOM/ssl.combined" "/home/$VIRTUALSERVER_DOM/ssl.key" > "/etc/haproxy/certs/$VIRTUALSERVER_DOM.pem"
  /usr/bin/systemctl restart haproxy.service
fi

```

Or:

```auto
#!/bin/bash
if ["$VIRTUALSERVER_ACTION" = "SSL_DOMAIN"] || ["$VIRTUALSERVER_ACTION" = "CREATE_DOMAIN"]; then
  /usr/bin/cp -f "/home/$VIRTUALSERVER_DOM/ssl.everything" "/etc/haproxy/certs/$VIRTUALSERVER_DOM.pem"
  /usr/bin/systemctl restart haproxy.service
fi

```

Upload it to my usual scripts directory, and then in `System Settings > Virtualmin Configuration` put the path `. /home/mymaindomain.com/scripts/copy-cert-to-haproxy.sh` into `Command to run after making changes to a server`?

If so that’s much easier than I thought it would be! ☺

---

<div class="post-metadata">

**Author:** ![Joe](https://cdn.forum.virtualmin.com/user_avatar/forum.virtualmin.com/joe/32/9_2.png) [@Joe](https://forum.virtualmin.com/u/Joe)\
**Post date:** [December 25, 2024, 12:58am UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/4 "2024-12-25T00:58:11Z")

</div>

You need a shebang (e.g. `#!/bin/sh` or `#!/bin/bash` or whatever), but otherwise looks fine.

I’d probably also recommend wrapping anything with a variable in double quotes. I need to fix that example. I don’t know who wrote it, but I try to make all my examples pass shellcheck, so it couldn’t have been me. See some of the other examples for better practice in terms of using variables in shell scripts. (And, use `shellcheck` to get good advice about safer and more reliable shell scripting.)

---

<div class="post-metadata">

**Author:** ![Brook](https://cdn.forum.virtualmin.com/letter_avatar_proxy/v4/letter/b/41988e/32.png) [@Brook](https://forum.virtualmin.com/u/Brook)\
**Post date:** [December 25, 2024, 3:28am UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/5 "2024-12-25T03:28:18Z")

</div>

Thanks Joe, I’ve edited my post above yours with the updated snippet - do you mean like that?

Unfortunately it did not work. I created a new `test.domain.com` virtualserver and Virtualmin set it up as usual, it fetched the letsencrypt script and ran `copy-cert-to-haproxy.sh` - however the resulting file is empty:

```auto
-rw-r--r-- 1 root root 0 Dec 25 03:20 test.domain.com.pem

```

I changed `System Settings > Virtualmin Configuration` \> `Command to run after making changes to a server?` to `bash /home/mymaindomain.com/scripts/copy-cert-to-haproxy.sh` (added `bash` to the start) as I was getting permission denied without it, but something is still amiss.

Any idea what might be wrong here?

---

<div class="post-metadata">

**Author:** ![Joe](https://cdn.forum.virtualmin.com/user_avatar/forum.virtualmin.com/joe/32/9_2.png) [@Joe](https://forum.virtualmin.com/u/Joe)\
**Post date:** [December 25, 2024, 3:37am UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/6 "2024-12-25T03:37:08Z")

</div>

> [@Brook](#):
>
> - do you mean like that?

No, I mean wrap the whole string in quotes. Substitution happens anywhere within with double quotes.

e.g.

```auto
 /usr/bin/cat "/etc/ssl/virtualmin/$VIRTUALSERVER_ID/$VIRTUALSERVER_DOM.combined" "/etc/ssl/virtualmin/$VIRTUALSERVER_ID/$VIRTUALSERVER_DOM.key" > "/etc/haproxy/certs/$VIRTUALSERVER_DOM.pem"

```

---

<div class="post-metadata">

**Author:** ![Joe](https://cdn.forum.virtualmin.com/user_avatar/forum.virtualmin.com/joe/32/9_2.png) [@Joe](https://forum.virtualmin.com/u/Joe)\
**Post date:** [December 25, 2024, 3:40am UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/7 "2024-12-25T03:40:31Z")

</div>

> [@Brook](#):
>
> as I was getting permission denied without it, but something is still amiss.
> 
> Any idea what might be wrong here?

Are you still getting permission denied, or something else?

You need to make the file executable, if you haven’t already. You can test your script by setting the variables you use in the script before you run it. e.g.:

```auto
# export VIRTUALSERVER_ACTION='SSL_DOMAIN'
# export VIRTUALSERVER_DOM='domain.tld'
# export VIRTUALSERVER_ID='domain ID'
# ./copy-cert-to-haproxy.sh

```

---

<div class="post-metadata">

**Author:** ![verne](https://cdn.forum.virtualmin.com/letter_avatar_proxy/v4/letter/v/dbc845/32.png) [@verne](https://forum.virtualmin.com/u/verne)\
**Post date:** [December 25, 2024, 4:01am UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/8 "2024-12-25T04:01:07Z")

</div>

speaking in general, is it possible to adjust the software package to look in `/etc/letsencrypt/live/$DOMAIN/` and directly use the certs from that location?

---

<div class="post-metadata">

**Author:** ![Brook](https://cdn.forum.virtualmin.com/letter_avatar_proxy/v4/letter/b/41988e/32.png) [@Brook](https://forum.virtualmin.com/u/Brook)\
**Post date:** [December 25, 2024, 9:18pm UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/9 "2024-12-25T21:18:02Z")

</div>

Nice idea, however HAProxy only allows you to specify a directory, so they’d all need to in there (for each domain) plus I’d still need to restart HAProxy. Think the inbuilt hooks Joe mentioned is probably the best option for this case 😃

---

<div class="post-metadata">

**Author:** ![Brook](https://cdn.forum.virtualmin.com/letter_avatar_proxy/v4/letter/b/41988e/32.png) [@Brook](https://forum.virtualmin.com/u/Brook)\
**Post date:** [December 25, 2024, 9:28pm UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/10 "2024-12-25T21:28:31Z")

</div>

I updated the script to:

```auto
if ["$VIRTUALSERVER_ACTION" = "SSL_DOMAIN"]; then
  /usr/bin/cat "/home/$VIRTUALSERVER_DOM/ssl.combined" "/home/$VIRTUALSERVER_DOM/ssl.key" > "/etc/haproxy/certs/$VIRTUALSERVER_DOM.pem"
  /usr/bin/systemctl restart haproxy.service
fi

```

And it works when I do this via terminal:

> [@Joe](#):
>
> ```auto
> # export VIRTUALSERVER_ACTION='SSL_DOMAIN'
> # export VIRTUALSERVER_DOM='domain.tld'
> # export VIRTUALSERVER_ID='domain ID'
> # ./copy-cert-to-haproxy.sh
> 
> ```

But not when I create a new [test.domain.com](http://test.domain.com) - Virtualmin reports it has created everything successfully but nothing gets copied over to `/etc/haproxy/certs/` - the domain creation page does not report a fault:

```plaintext
Creating administration group test.domain.com ..
.. done

Creating administration user test.domain.com ..
.. done

Creating aliases for administration user ..
.. done

Adding administration user to groups ..
.. done

Creating home directory ..
.. done

Creating mailbox for administration user ..
.. done

Adding new DNS zone ..
.. done

Adding new virtual website ..
.. done

Adding webserver user apache to server's group ..
.. done

Performing other Apache configuration ..
.. done

Creating SSL certificate and private key ..
.. done

Adding new SSL virtual website ..
.. done

Saving server details ..
.. done

Re-starting DNS server ..
.. done

Applying web server configuration ..
.. done

Re-starting Webmin ..
.. done

Re-starting Usermin ..
.. done

Requesting a certificate for test.domain.com, www.test.domain.com from Let's Encrypt ..
.. request was successful!

Creating initial website index page ..
.. done

Applying web server configuration ..
.. done

Re-starting Webmin ..
.. done

Re-starting Usermin ..
.. done

```

In the field for `Command to run after making changes to a server` I have tried both:

`bash /home/mydomain/scripts/copy-cert-to-haproxy.sh`  
as well as without `bash` at the start:  
`/home/mydomain/scripts/copy-cert-to-haproxy.sh`

But neither of these seem to work.

Summary: testing via the command line works, but not when virtualmin creates the account. Any ideas what to try next?

---

<div class="post-metadata">

**Author:** ![Joe](https://cdn.forum.virtualmin.com/user_avatar/forum.virtualmin.com/joe/32/9_2.png) [@Joe](https://forum.virtualmin.com/u/Joe)\
**Post date:** [December 25, 2024, 10:00pm UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/11 "2024-12-25T22:00:09Z")

</div>

Hmm…I’m not sure how to troubleshoot that.

Maybe watch the Webmin actions log when you renew a certificate. Just `tail -f /var/webmin/webmin.log`

---

<div class="post-metadata">

**Author:** ![Brook](https://cdn.forum.virtualmin.com/letter_avatar_proxy/v4/letter/b/41988e/32.png) [@Brook](https://forum.virtualmin.com/u/Brook)\
**Post date:** [December 25, 2024, 10:19pm UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/12 "2024-12-25T22:19:25Z")

</div>

Doesn’t appear to be any clues in the log Joe:

```plaintext
1735161898.12567.0 [25/Dec/2024 21:24:58] - - - webmin letsencrypt-dns.pl "letsencryptdns" "-" "test.domain.com"
1735161912.12783.0 [25/Dec/2024 21:25:12] - - - webmin letsencrypt-dns.pl "letsencryptdns" "-" "www.test.domain.com"
1735161920.13019.0 [25/Dec/2024 21:25:20] - - - webmin letsencrypt-cleanup.pl "letsencryptcleanup" "-" "test.domain.com"
1735161923.13060.0 [25/Dec/2024 21:25:23] - - - webmin letsencrypt-cleanup.pl "letsencryptcleanup" "-" "www.test.domain.com"
1735161936.11219.0 [25/Dec/2024 21:25:36] root 803a9a09bf581082ed80daadf3484676 102.22.83.84 virtual-server domain_setup.cgi "create" "domain" "test.domain.com" alias='' alias_mode='0' aliasdomslimit='*' aliaslimit='' aliasmail='' allowedscripts='' auto_letsencrypt='1' bw_limit='' cgi_bin_dir='cgi-bin' cgi_bin_path='/home/test.domain.com/cgi-bin' created='1735161868' creator='root' crypt_enc_pass='IRrSQZzFN/Qh2' db='test_domain_com' db_mysql='' db_postgres='' dbslimit='' defip='1' digest_enc_pass='f275d1687cd464cebf2466bb4852d0de' dir='1' dns='1' dns_ip='3.11.102.75' dom='test.domain.com' domslimit='*' edit_admins='1' edit_aliases='1' edit_allowedhosts='1' edit_backup='1' edit_catchall='1' edit_dbs='1' edit_delete='1' edit_disable='1' edit_dnsip='1' edit_domain='1' edit_forward='1' edit_ip='1' edit_mail='1' edit_passwd='1' edit_phpmode='1' edit_phpver='1' edit_records='1' edit_redirect='1' edit_restore='1' edit_sched='1' edit_scripts='1' edit_sharedips='1' edit_spam='1' edit_spf='1' edit_ssl='1' edit_users='1' email='' emailto='test.domain.com@root.server.com' emailto_addr='test.domain.com@root.server.com' emailto_src='test.domain.com@root.server.com' enc_pass='$6$3516186d0$66/Mhv6rR9xbjpGSGzweUNMj7TaleaeDC6WdDSE5B/bm7kYXSoggt4b1n1PKPzSpf.bBebd37.dvF2xv4EnJ.' forceunder='0' ftp='0' gid='1043' group='test.domain.com' hashpass='1' home='/home/test.domain.com' id='173513385911219' ip='3.11.102.75' ip6='' ipfollow='' lastsave='1735161932' letsencrypt_dname='' letsencrypt_dwild='0' letsencrypt_last='1735161930' letsencrypt_renew='1' limit_dir='1' limit_dns='1' limit_ftp='0' limit_logrotate='0' limit_mail='0' limit_mysql='0' limit_postgres='0' limit_spam='0' limit_ssl='1' limit_unix='1' limit_virt='0' limit_virus='0' limit_web='1' limit_webalizer='0' limit_webmin='0' logrotate='0' mail='0' mailboxlimit='' md5_enc_pass='$1$35161860$Pjft0K7.LbB7.iz/kq5PZ.' migrate='1' mongrelslimit='' mysql='0' mysql_module='' mysql_pass='rEChAwM14rK9JSs' name='1' name6='1' netmask='' netmask6='' nodbname='0' norename='0' owner='' parent='' plan='0' postgres='0' prefix='test.domain.com' proxy_pass='' proxy_pass_mode='0' public_html_dir='public_html' public_html_path='/home/test.domain.com/public_html' quota='' realdomslimit='*' reseller='' safeunder='0' source='domain_setup.cgi' spam='0' ssl='1' ssl_cert='/home/test.domain.com/ssl.cert' ssl_cert_expiry='1742934412' ssl_chain='/home/test.domain.com/ssl.ca' ssl_combined='/home/test.domain.com/ssl.combined' ssl_everything='/home/test.domain.com/ssl.everything' ssl_key='/home/test.domain.com/ssl.key' ssl_pass='' subdom='' subprefix='' template='0' ugid='1043' ugroup='test.domain.com' uid='1060' unix='1' uquota='' user='test.domain.com' virt='0' virt6='' virt6already='' virtalready='0' virus='0' web='1' web_port='8080' web_sslport='4443' web_urlport='' web_urlsslport='' webalizer='0' webmin='0'

```

I am guessing there are no variables available to the script, as previously I had taken out the `if ["$VIRTUALSERVER_ACTION" = "SSL_DOMAIN"]; then` conditional and that’s when it was giving me an empty file. Either that or `$VIRTUALSERVER_ACTION" = "SSL_DOMAIN"` is not being set on domain creation?

Only other thing I can think of is the command to run the script might need to be different, so far I have tried all of the below:

```plaintext
/home/mymaindomain.com/scripts/copy-cert-to-haproxy.sh
. /home/mymaindomain.com/scripts/copy-cert-to-haproxy.sh
bash /home/mymaindomain.com/scripts/copy-cert-to-haproxy.sh

```

I know that `bash /home/mymaindomain.com/scripts/copy-cert-to-haproxy.sh` definitely runs the script as when I removed the condition that’s when I was getting an empty file - so I think it’s either the variable isn’t available or the correct one (SSL\_DOMAIN) is not being set on domain creation?

---

<div class="post-metadata">

**Author:** ![Joe](https://cdn.forum.virtualmin.com/user_avatar/forum.virtualmin.com/joe/32/9_2.png) [@Joe](https://forum.virtualmin.com/u/Joe)\
**Post date:** [December 25, 2024, 11:28pm UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/13 "2024-12-25T23:28:45Z")

</div>

So, check all the variables you’re expecting by logging the env when it runs and then exit. Modify your script to have this at the beginning, just after the shebang:

```auto
env >> /home/domain.tld/copy-cert-to-haproxy.log
exit

```

Then see what shows up in that log. Make sure all the variables are set how you think. (There will probably be other unrelated stuff in there, but you can search for the variables you want.)

---

<div class="post-metadata">

**Author:** ![Brook](https://cdn.forum.virtualmin.com/letter_avatar_proxy/v4/letter/b/41988e/32.png) [@Brook](https://forum.virtualmin.com/u/Brook)\
**Post date:** [December 26, 2024, 1:06am UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/14 "2024-12-26T01:06:16Z")

</div>

Thanks Joe!

The problem was `VIRTUALSERVER_ACTION=CREATE_DOMAIN` so I changed the conditional to:

```auto
if ["$VIRTUALSERVER_ACTION" = "SSL_DOMAIN"] || ["$VIRTUALSERVER_ACTION" = "CREATE_DOMAIN"]; then

```

If `VIRTUALSERVER_ACTION` is always `SSL_DOMAIN` on cert renewal then the updated script should ensure it will always works - or do I need to look for other possible variants for `VIRTUALSERVER_ACTION` as well?

---

<div class="post-metadata">

**Author:** ![Brook](https://cdn.forum.virtualmin.com/letter_avatar_proxy/v4/letter/b/41988e/32.png) [@Brook](https://forum.virtualmin.com/u/Brook)\
**Post date:** [December 26, 2024, 2:32am UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/15 "2024-12-26T02:32:22Z")

</div>

Another related question:

If we go to Virtualmin (domain/account) \> `Server Configuration > SSL Certificate` and request or renew a certificate should this also trigger the `Command to run after making changes to a server` action?

Asking because I just did that and it did not. It’s renewed the certificate but not copied it over to `/etc/haproxy/certs/` - so doesn’t appear to have run the `Command to run after making changes to a server`.

---

<div class="post-metadata">

**Author:** ![Joe](https://cdn.forum.virtualmin.com/user_avatar/forum.virtualmin.com/joe/32/9_2.png) [@Joe](https://forum.virtualmin.com/u/Joe)\
**Post date:** [December 26, 2024, 2:55am UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/16 "2024-12-26T02:55:56Z")

</div>

That may be a bug. It should run after renewals, too.

I thought I traced through the code to confirm actions run on all TLS events, but I may have misunderstood the execution path.

@Jamie, shouldn’t that hook run after a Let’s Encrypt renewal, too?

---

<div class="post-metadata">

**Author:** ![Brook](https://cdn.forum.virtualmin.com/letter_avatar_proxy/v4/letter/b/41988e/32.png) [@Brook](https://forum.virtualmin.com/u/Brook)\
**Post date:** [December 26, 2024, 3:20am UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/17 "2024-12-26T03:20:35Z")

</div>

If it’s any help this is what I did:

```plaintext
certbot certificates (to view certs)
sudo certbot delete --cert-name domain.tld (to remove the cert I want Virtualmin to handle)
domain.tld > Edit Virtual Server > Check: Apache SSL website enabled? > Save (and when that did not work I did the below)

domain.tld/Server Configuration > SSL Certificate > Request Certificate

```

---

<div class="post-metadata">

**Author:** ![Jamie](https://cdn.forum.virtualmin.com/user_avatar/forum.virtualmin.com/jamie/32/8589_2.png) [@Jamie](https://forum.virtualmin.com/u/Jamie)\
**Post date:** [December 26, 2024, 6:28am UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/18 "2024-12-26T06:28:31Z")

</div>

> [@Joe](#):
>
> @Jamie, shouldn’t that hook run after a Let’s Encrypt renewal, too?

Yes it should do, although until the most recent 7.30.x series release of Virtualmin there was a bug where post-domain actions weren’t run in this case.

---

<div class="post-metadata">

**Author:** ![Brook](https://cdn.forum.virtualmin.com/letter_avatar_proxy/v4/letter/b/41988e/32.png) [@Brook](https://forum.virtualmin.com/u/Brook)\
**Post date:** [December 26, 2024, 9:50pm UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/19 "2024-12-26T21:50:44Z")

</div>

> [@Jamie](#):
>
> Yes it should do, although until the most recent 7.30.x series release of Virtualmin there was a bug where post-domain actions weren’t run in this case.

That explains it - this server is still on 6.x.

Will post-actions still run (even pre 7.30.x) after the virtualmin renewal script runs? (i.e if `Automatically renew certificate?` has been checked in Virtualmin \> `Server Configuration > SSL Certificate > Let's Encrypt`) or will it not work at even for that for anything prior to 7.30?

---

<div class="post-metadata">

**Author:** ![Joe](https://cdn.forum.virtualmin.com/user_avatar/forum.virtualmin.com/joe/32/9_2.png) [@Joe](https://forum.virtualmin.com/u/Joe)\
**Post date:** [December 26, 2024, 9:59pm UTC](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248/20 "2024-12-26T21:59:41Z")

</div>

> [@Brook](#):
>
> That explains it - this server is still on 6.x.

🤯

Why!?

[Next page](https://forum.virtualmin.com/t/custom-actions-with-virtualmins-letsencypt-renewals/131248.md?page=2)
