How to install Virtualmin on a Raspberry pi 4

You can install Virtualmin in Raspberry Pi with just a simple modification on to the install script.

I have my Raspberry Pi 4 installed with Pi OS Bookworm and it is based on Debian Linux 12 using the install script.

What you need to do is

1. wget
2. sudo nano
3. Find the text “get_distro”
4. Add in os_type=”debian” after get_distro

log_debug “Operating system name: $os_real”
log_debug “Operating system version: $os_version”
log_debug “Operating system type: $os_type”
log_debug “Operating system major: $os_major_version”

What this does is, it will force the script to recognize the host as a debian operating type.

Execute the script … It should install without any issues.


How to Use CloudFront to do WordPress Page Caching

Previously, we looked at WordPress page caching using a content delivery network (CDN). This is an essential tool for speeding up a WordPress site at a global scale. That said, it’s still not commonly used by a lot of WordPress hosts.

With Ymir, you get a CloudFront (Amazon’s CDN) distribution set up to do page caching on production environments by default. This is a great feature of the product. But what if you want to configure CloudFront to do page caching yourself?

Well, this isn’t talked a lot about. In my research, the only article I found was this one on an AWS blog. This article will use that article as a baseline, but will discuss in more detail how to set up CloudFront. Continue reading

Optimal Virtualmin Template Settings

Create a file in /etc/skel/public_html/index.html with the following:

<!DOCTYPE html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Under Construction</title>
<link href=",400" rel="stylesheet">
<style media="screen" type="text/css">
html {
body {
color: #fff; 
margin: 0;
font-family: "Montserrat", sans-serif;
font-style: normal;
font-size: 14px;
line-height: 22px;
height: 100%; 
background-color: #fff;
h1 {
margin-top: 20px;
font-size: 50px;
opacity: 1;
@media all and (max-width: 980px) {
h1 {
font-size: 35px;
.under-construction p {
font-size: 20px;
@media all and (max-width: 767px) {
h1 {
font-size: 28px;
.under-construction p {
font-size: 16px;
h2 {
font-style: normal;
font-size: 14px;
line-height: 22px;
margin: 0;
.wrap {
height: auto; 
min-height: 100%; 
background-color: #3B4251;
.domain {
position: absolute; 
text-align: center; 
width: 100%; 
margin-left: -50%; 
top: 42.5%;
left: 50%;

.footer {
text-align: center;
padding:15px 20px 18px 20px;
font-size: 12px;
line-height: 22px;
p {
margin: 0;

.footer a {
p.description {
padding-top: 10px;
font-size: 18px;
.uh-logo {
margin: 20px;
max-width: 40px;
.under-construction {
position: absolute; 
text-align: center; 
width: 100%; 
bottom: 5%;
font-size: 24px;
line-height: 1; 
font-weight: 300;
img {
filter: brightness(0) invert(1);

<div class="wrap">
<a href=""><img class="uh-logo" src="" alt=" logo"></a>
<div class="domain">
<h1 id="site_domain"></h1>
<div class="under-construction">
<p>We're just getting ready... Check back soon!</p>
document.getElementById("site_domain").innerHTML = window.location.hostname;

Go to System Settings -> Server Templates -> Default Settings -> Website for Domain and paste the above in the text field labeled ‘Disabled Website HTML’. Then check the box labeled ‘Redirect all HTTP requests to HTTPS’ and click on the ‘Save’ button.

Now go to System Settings -> Server Templates -> Default Settings -> PHP Options

In the section labeled ‘PHP configuration variables for scripts’, add the following:

memory_limit at least 128M
post_max_size at least 256M
upload_max_filesize at least 256M

How to Set Inotify Limit PERMANENTLY on a Synology Diskstation

Go to Control Panel -> Task Scheduler. Create a New Task -> Triggered Task -> User-defined script.

In General Settings tab: give it a name (e.g. “Syncthing Sysctl Inotify Fix”) and Event = Boot-up.

In the Task Settings tab: enter this in the Run Command box:

sh -c '(sleep 90 && echo 204800 > /proc/sys/fs/inotify/max_user_watches)&'

The sleep is to delay the setting to (hopefully) skip past any initialization that Synology does at boot time.

Click OK to close the task dialog, then enable the task and hit the Save button.


How To Resize a Cloud Server File System

This guide explains how to expand the file system on a Vultr cloud server instance. If you have upgraded your cloud server to a plan with a larger disk or need to expand a partition while preserving data, follow these steps. A cloud server instance is sometimes called a Virtual Private Server or VPS.

This guide uses Ubuntu 20.04 as an example but applies to any Linux distribution with the fdisk and resize2fs tools. The example server has a 10 GB virtual disk with two partitions:

The virtual disk vda is 10 GB.

The first partition vda1 is 6 GB.

The second partition vda2 is 4 GB.

# lsblk
vda 252:0 0 10G 0 disk
├─vda1 252:1 0 6G 0 part /
└─vda2 252:2 0 4G 0 part

As an example, this guide will remove the second partition (vda2), then expand the first partition (vda1) to fill the virtual disk. This will preserve all data on vda1 and delete all data on vda2.
Use this example as a general guide for your particular situation. Continue reading

How to Install Nextcloud on a Synology the Easy Way

Begin by installing a package called “Container Manager”. This should have created a new folder in your drive volume called ‘docker’. Create a new folder within this folder called “nextcloud”. Then create 7 new folders inside the nextcloud folder called “config”, “db”, “custom_apps”, “themes”, “html”, “redis”, and “data”. Now right click on the nextcloud folder that you have just created and click Properties. Go to the Permission tab then click Advanced options. From the drop-down menu choose “Make inherited permissions explicit“. Select Everyone then click the Edit tab. Check all Read and Write Permissions and click on Done. After you click Done check “Apply to this folder, sub-folders and files“ then click on Save. Now open up the “Container Manager” package and click on “Project”. Name it “nextcloud” and select “/docker/nextcloud” for the project path. Choose “Create docker-compose.yml” for source and add the following:

version: '3.9'
    image: mariadb:latest
    container_name: Nextcloud-DB
      - no-new-privileges:true
    user: 1026:100
    command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-read-only-compressed=OFF
      - ./db:/var/lib/mysql:rw
      - ./db:/etc/mysql/conf.d:rw
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - TZ=America/Los_Angeles
    restart: on-failure:5
    image: redis:latest
    container_name: Nextcloud-REDIS
    hostname: nextcloudredis
    user: 1026:100
     test: ["CMD-SHELL", "redis-cli ping || exit 1"]
      - ./redis:/data:rw
      TZ: America/Los_Angeles
    restart: on-failure:5
    image: nextcloud:latest
    container_name: Nextcloud
      - 9333:80
       condition: service_started
       condition: service_healthy
      - REDIS_HOST=nextcloudredis
      - MYSQL_DATABASE=nextcloud
      - MYSQL_USER=nextcloud
      - MYSQL_HOST=mariadb
     test: curl -f http://localhost:80/ || exit 1
      - ./html:/var/www/html:rw
      - ./custom_apps:/var/www/html/custom_apps:rw
      - ./config:/var/www/html/config:rw
      - ./data:/var/www/html/data:rw
      - ./themes:/var/www/html/themes:rw
    restart: on-failure:5
   image: nextcloud:apache
   container_name: Nextcloud-CRON
   restart: always
     - ./config:/var/www/html/config:rw
     - ./html:/var/www/html:rw
     - ./custom_apps:/var/www/html/custom_apps:rw
     - ./data:/var/www/html/data:rw
   entrypoint: /
       condition: service_started
       condition: service_started

Replace [PASSWORD] with unique strong passwords and [DOMAIN] with your own domain name. Continue to build the project. Once completed, you should be able to access the Nextcloud UI by typing “https://[SYNOLOGY_IP]:9333” in your web browser. Go ahead and create an admin user. Once installed, you will be logged in. If you are using LDAP you can enable the “LDAP user and group backend” app and configure it with uid=root,cn=users,dc=[SUBDOMAIN],dc=[DOMAIN],dc=[DOMAINSUFFIX] for the User DN. Now we just need to create a reverse proxy so that we don’t have to access Nextcloud with an IP address and port number. This can be done by going to Control Panel -> Login Portal -> Advanced in your Synology and clicking on the “Reverse Proxy” button. Enter your domain name for source and the IP address of your Synology for the destination. Be sure to specify port 9333 for the destination. Last, there is a file that needs to be modified. This might be fixed in a future version, but for now open up the .htaccess file in the html folder and look for the following lines:

RewriteRule ^\.well-known/carddav /remote.php/dav/ [R=301,L]
RewriteRule ^\.well-known/caldav /remote.php/dav/ [R=301,L]

Change it to the following replacing [DOMAIN] with your own domain name:

RewriteRule ^\.well-known/carddav https://[DOMAIN]/remote.php/dav/ [R=301,L]
RewriteRule ^\.well-known/caldav https://[DOMAIN]/remote.php/dav/ [R=301,L]

That’s it! Now you should be able to access Nextcloud with your domain name.


How to create a 3-in-1 bootable usb drive on Linux

A usb drive with only 1 partition to load grub2 on usb-bootable machines with Legacy BIOS, 64bit UEFI or 32bit UEFI.

Note: due to the maximum size of a file inside an EFI system partition, files (such as ISO disk images) of 4 GiB or larger must be placed on another partition. That second partition can be of type ext4, for instance.

Partition the drive and install grub2

Warning: the usb drive will be formatted, save your data before proceeding!

First of all, on you current installation, check if the folder /usr/lib/grub/ exists and is not empty. If it is empty or does not exist, make sure the package grub-common (or equivalent for your distribution) version 2 or higher is installed. Depending on the system, /usr/lib/grub/ will contain one or more of the following folders: x86_64-efi, x86_64-efi-signed, i386-pc, i386-efi, …

The x86_64-efi, i386-pc and i386-efi folders need to be present in order to install the corresponding bootloader on the usb drive.

Install them using the package manager, for instance on Ubuntu :

sudo apt install grub-pc-bin grub-efi-ia32-bin grub-efi-amd64-bin

Now, find the device file for your usb drive. Here, the file is /dev/sdX. Replace X with the appropriate lower case letter(s) in the commands.

Make sure it’s the right drive! (check the capacity and the partitions) :

sudo fdisk -l /dev/sdX

Open fdisk :

sudo fdisk /dev/sdX


o <enter> # Create a new empty DOS partition table

n <enter> # Create a new partition

p <enter> # Select primary partition type

1 <enter> # Set partition number to 1

<enter> # Start partition at the first possible sector (default)

<enter> # Set partition end to the last possible sector (default)

Note: if fdisk (newer versions only) asks whether the partition signature should be deleted, then answer yes.

t <enter> # Change partition type

e f <enter> # Set partition type to EFI (FAT-12/16/32)

a <enter> # Enable the bootable flag on partition 1

w <enter> # Write the partition table

Create a fresh filesystem in the newly created partition :

sudo mkfs.fat -F32 /dev/sdX1

Mount the filesystem :

sudo mount -o umask=000 /dev/sdX1 /mnt

Write the MBR and install the grub files required for legacy BIOS boot on the drive :

sudo grub-install --no-floppy --boot-directory=/mnt/boot --target=i386-pc /dev/sdX

Install /EFI/BOOT/BOOTX64.EFI and other grub files required to load grub from a 64-bit UEFI firmware :

sudo grub-install --removable --boot-directory=/mnt/boot --efi-directory=/mnt --target=x86_64-efi /dev/sdX

Install /EFI/BOOT/BOOTIA32.EFI and other grub files required for 32-bit UEFI :

sudo grub-install --removable --boot-directory=/mnt/boot --efi-directory=/mnt --target=i386-efi /dev/sdX

Create a grub.cfg file :

touch /mnt/boot/grub/grub.cfg

Example grub.cfg with Xubuntu 22.04 Live

Notes :

  • Skip this part if you already have a working grub.cfg for the usb drive.
  • Other examples can be found in this repository’s grub.cfg file.
Create a folder for cd images :

mkdir /mnt/isos

Download an Ubuntu CD image (for example: Xubuntu 22.04 64-bit) :

Note: make sure there is enough space on the usb drive.

wget --directory-prefix=/mnt/isos

Edit grub.cfg :

nano /mnt/boot/grub/grub.cfg

Write or paste something like this :
menuentry 'Xubuntu 22.04 amd64' {
	#rmmod tpm #uncomment if grub version is >=2.04 in UEFI mode (see
	set isofile="/isos/xubuntu-22.04.3-desktop-amd64.iso"
	#search --set=root --file $isofile #uncomment if the bootloader and OS files are on different partitions
	loopback isoloop $isofile
	linux (isoloop)/casper/vmlinuz locale=fr_FR console-setup/layoutcode=fr boot=casper iso-scan/filename=$isofile quiet --
	initrd (isoloop)/casper/initrd
Or something like this :
menuentry 'LMDE 6 Cinnamon 64bit (Live)' {
	set isofile="/isos/lmde-6-cinnamon-64bit.iso"
	loopback loop (hd0,1)$isofile
	linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=$isofile noprompt noeject
	initrd (loop)/casper/initrd.lz

Notes :

  • Remove or change the value of the locale parameter to set the language of the live system.
  • Remove or change the value of the console-setup/layoutcode parameter to change the keyboard layout.
Save grub.cfg (in nano) and exit :





Unmount the filesystem :

sudo umount /mnt


Raspberry Pi PXE Boot – Network booting a Pi 4 without an SD card

Install Raspbian on an SD card and install needed tools

Let’s start configuring your client system for netboot. This is the Raspberry Pi that will eventually boot without a micro SD card installed.

  • Download PiOS Lite. For this tutorial I used the Bullseye release.
  • Copy the Bullseye image onto an SD card. I suggest using the PiOS Imager. Warning! This will overwrite data on the device specified. Triple check you are writing to the SD card and not your laptop drive!
  • Put the SD card in your client Raspberry Pi 4 and boot it. Using the lite version of raspbian give you a text console only. If you want a graphical console you can use the full version and it should work. I have not tested this workflow with the full version.
  • Log in via the console using the login you created with the Imager.
  • Connect your Raspberry Pi to the internet via an ethernet cable.
  • Update PiOS via apt-get and install the rpi-config program:

Continue reading

How to Backup IMAP Mailboxes and Nextcloud Calendars, Contacts, and Notes

To backup all IMAP mailboxes for a user account, first download Rick Sander’s IMAP tools and save them somewhere on your system. Next, create a cron job and have it execute the following command:

mkdir -p /tmp/IMAP_$(date +%Y-%m-%d) && /path/to/imapdump/ -S -f /tmp/IMAP_$(date +%Y-%m-%d) && cd /tmp/IMAP_$(date +%Y-%m-%d) && zip -r /backup/path/user@example.com_$(date +'%m-%d-%Y').zip && chown user:user /backup/path/user@example.com_$(date +'%m-%d-%Y').zip && rm -Rf /tmp/IMAP_$(date +%Y-%m-%d)/ && find /backup/path -type f -mtime +90 -delete

To backup Nextcloud calendars and contacts, create a cron job running as root and have it execute the following command:

wget --directory-prefix=/tmp/nc-backup --user=ncuser --password=ncpassword --timestamping && mv /tmp/nc-backup/personal-1?export /backup/path/calendar_$(date +'%m-%d-%Y').ics && mv /tmp/nc-backup/contacts?export /backup/path/contacts_$(date +'%m-%d-%Y').vcf && find /backup/path -type f -mtime +90 -delete

For Notes, do the same thing as above but execute the following instead:

mkdir -p /tmp/nc-backup && cd /nextcloud/path/k4hjd9n3-k3ns-9385-9k2n-l3kjs9fk4b9z/files && zip -r /tmp/nc-backup/notes_$(date +'%m-%d-%Y').zip Notes && chown user:user /tmp/nc-backup/notes_$(date +'%m-%d-%Y').zip && mv /tmp/nc-backup/notes_$(date +'%m-%d-%Y').zip /backup/path