<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Sergio Peris</title>
    <description>The latest articles on Forem by Sergio Peris (@sertxudev).</description>
    <link>https://forem.com/sertxudev</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F253472%2Ff38f54c9-d1ce-49a0-bd76-73669ef92cc4.jpg</url>
      <title>Forem: Sergio Peris</title>
      <link>https://forem.com/sertxudev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sertxudev"/>
    <language>en</language>
    <item>
      <title>Configure static IP address on Netplan</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Tue, 31 Mar 2026 09:00:23 +0000</pubDate>
      <link>https://forem.com/sertxudev/configure-static-ip-address-on-netplan-2am1</link>
      <guid>https://forem.com/sertxudev/configure-static-ip-address-on-netplan-2am1</guid>
      <description>&lt;p&gt;I've recently set up a new Ubuntu Server 24.04 and needed to assign it a static IP address. For a server, you don't want the IP to change whenever DHCP leases expire.&lt;/p&gt;

&lt;h2&gt;
  
  
  Finding your network interface
&lt;/h2&gt;

&lt;p&gt;Before making any configuration changes, you need to know the name of your network interface. On Ubuntu Server, you'll likely see something like &lt;code&gt;ens33&lt;/code&gt; or &lt;code&gt;enp0s3&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Run this command to see all network interfaces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip &lt;span class="nb"&gt;link&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for the interface that has an IP address assigned to it. That's the one you want to configure. In my case, it was &lt;code&gt;enp0s3&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring Netplan
&lt;/h2&gt;

&lt;p&gt;Ubuntu Server 24.04 stores network configuration in &lt;code&gt;/etc/netplan/&lt;/code&gt;. There's usually a file there called something like &lt;code&gt;50-cloud-init.yaml&lt;/code&gt;. Let's check what's in that directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; /etc/netplan/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the configuration file and you will see something like this by default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi /etc/netplan/50-cloud-init.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;renderer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networkd&lt;/span&gt;
  &lt;span class="na"&gt;ethernets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enp0s3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;dhcp4&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change it to use a static IP instead. Here's what I configured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;network&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;
  &lt;span class="na"&gt;renderer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;networkd&lt;/span&gt;
  &lt;span class="na"&gt;ethernets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;enp0s3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;dhcp4&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="na"&gt;dhcp6&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="na"&gt;addresses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;192.168.1.100/24&lt;/span&gt;
      &lt;span class="na"&gt;routes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;default&lt;/span&gt;
          &lt;span class="na"&gt;via&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;192.168.1.1&lt;/span&gt;
      &lt;span class="na"&gt;nameservers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;addresses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;1.1.1.1&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;1.0.0.1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the IP address includes the CIDR notation. The CIDR &lt;code&gt;/24&lt;/code&gt; means a subnet mask of &lt;code&gt;255.255.255.0&lt;/code&gt;. I'm using explicit routes instead of the older &lt;code&gt;gateway4&lt;/code&gt; key, because Ubuntu 24.04 deprecated &lt;code&gt;gateway4&lt;/code&gt;. For DNS, I pointed to Cloudflare's public DNS servers, but you can use the DNS servers of your choice.&lt;/p&gt;

&lt;h2&gt;
  
  
  Applying the changes
&lt;/h2&gt;

&lt;p&gt;Once the file is saved, instruct Netplan to apply the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;netplan apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Verifying the changes
&lt;/h2&gt;

&lt;p&gt;Check that your static IP is now assigned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ip addr show enp0s3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It should now show your new static IP address.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>networking</category>
      <category>ubuntu</category>
      <category>linux</category>
    </item>
    <item>
      <title>Backup S3 buckets using rclone</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Tue, 10 Feb 2026 08:00:24 +0000</pubDate>
      <link>https://forem.com/sertxudev/backup-s3-buckets-using-rclone-e6p</link>
      <guid>https://forem.com/sertxudev/backup-s3-buckets-using-rclone-e6p</guid>
      <description>&lt;p&gt;Backing up our files is a crucial task that we don't consider until it's too late. Using &lt;code&gt;rclone&lt;/code&gt;, we can make a backup of all our data stored in S3 buckets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing rclone
&lt;/h2&gt;

&lt;p&gt;First, we need to install &lt;code&gt;rclone&lt;/code&gt;. We'll be using Ubuntu Server, but you can use any distribution supported.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl https://rclone.org/install.sh | &lt;span class="nb"&gt;sudo &lt;/span&gt;bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we've installed it, we can verify it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rclone version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;rclone v1.72.1
 - os/version: ubuntu 24.04 (64 bit)
 - os/kernel: 6.8.0-90-generic (x86_64)
 - os/type: linux
 - os/arch: amd64
 - go/version: go1.25.5
 - go/linking: static
 - go/tags: none
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configure the remote
&lt;/h2&gt;

&lt;p&gt;To connect to our S3 storage, we must create a rclone remote.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rclone config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will prompt us to answer a few questions to configure it correctly.&lt;/p&gt;

&lt;p&gt;Some options may differ from this example, so take your time reviewing the options offered to select the one that best suits your case.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;n) New remote
name&amp;gt; s3-storage

Storage&amp;gt; s3
provider&amp;gt; Other
env_auth&amp;gt; false
access_key_id&amp;gt; ACCESS_ID_KEY
secret_access_key&amp;gt; ACCESS_SECRET_KEY
region&amp;gt; REGION
endpoint&amp;gt; http://s3.example.com
location_constraint&amp;gt;
acl&amp;gt; private
y/e/d&amp;gt; y
e/n/d/r/c/s/q&amp;gt; q
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Test the remote
&lt;/h2&gt;

&lt;p&gt;Once we've configured the remote, we need to test it. Running the following command should list all buckets available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rclone lsd s3-storage:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-1 2026-01-29 21:09:35        -1 bucket-1
-1 2026-01-29 20:05:31        -1 bucket-2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring the backup
&lt;/h2&gt;

&lt;p&gt;To back up the S3 storage, we'll create a backup script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi /usr/local/bin/s3-backup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;set&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="nv"&gt;LOG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/log/rclone-backup.log"&lt;/span&gt;
&lt;span class="nv"&gt;DEST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/backup"&lt;/span&gt;

rclone &lt;span class="nb"&gt;sync &lt;/span&gt;garage: &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DEST&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--checksum&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--fast-list&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--s3-no-check-bucket&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transfers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--checkers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;16 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--log-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--log-level&lt;/span&gt; INFO
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This script will back up all S3 buckets to the &lt;code&gt;/backup&lt;/code&gt; folder.&lt;/p&gt;

&lt;p&gt;Next, we make the script executable.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/local/bin/s3-backup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And run it to create the first backup.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;s3-backup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Set up a cron job
&lt;/h2&gt;

&lt;p&gt;To run the backup periodically, we must create a cron job.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Backup Garage S3 to QNAP daily at 02:00.
0 2 * * * /usr/local/bin/s3-backup.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This cron job will run the backup script every day at 02:00.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cli</category>
      <category>linux</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Add an NFS mount point to a Ubuntu Server</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Mon, 02 Feb 2026 09:00:24 +0000</pubDate>
      <link>https://forem.com/sertxudev/add-an-nfs-mount-point-to-a-ubuntu-server-2k9n</link>
      <guid>https://forem.com/sertxudev/add-an-nfs-mount-point-to-a-ubuntu-server-2k9n</guid>
      <description>&lt;p&gt;NFS allows us to mount a network share as a local device. This system uses the client IP address for authentication. Don't confuse it with SMB, which allows user and password authentication.&lt;/p&gt;

&lt;p&gt;In this tutorial, we'll explain how to connect an NFS share to an Ubuntu Server as a client.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install dependencies
&lt;/h2&gt;

&lt;p&gt;First, we must install the dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;apt &lt;span class="nb"&gt;install &lt;/span&gt;nfs-common
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Create a mount point
&lt;/h2&gt;

&lt;p&gt;Once we've installed the dependencies, we must ensure the mount point we want to use exists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mount &lt;span class="nt"&gt;-p&lt;/span&gt; /mnt/backups
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Add a persistent mount
&lt;/h2&gt;

&lt;p&gt;Using the mount command, we can temporarily mount the NFS share. However, we'll modify the &lt;code&gt;/etc/fstab&lt;/code&gt; file to make the mount persistent.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;192.168.1.10:/Backups /mnt/backups nfs defaults,_netdev 0 0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To apply the changes we've made at &lt;code&gt;/etc/fstab&lt;/code&gt; we must run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mount &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can check that the NFS mount is working as expected.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Filesystem                     Size  Used Avail Use% Mounted on
/dev/sda2                       30G  6.9G   21G  25% /
192.168.1.10:/Backups          916G  594G  322G  65% /mnt/backups
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>tutorial</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>Remove local and local-lvm from Proxmox</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Mon, 26 Jan 2026 09:00:24 +0000</pubDate>
      <link>https://forem.com/sertxudev/remove-local-and-local-lvm-from-proxmox-37i6</link>
      <guid>https://forem.com/sertxudev/remove-local-and-local-lvm-from-proxmox-37i6</guid>
      <description>&lt;p&gt;Proxmox, by default, configures two storage volumes on the disk where the Proxmox OS resides: one named &lt;code&gt;local-lvm&lt;/code&gt; for storing the disk images and containers, and another named &lt;code&gt;local&lt;/code&gt; for storing the ISO images, container templates, and backups.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;local-lvm&lt;/code&gt;, as its name suggests, is a LVM thin-provisioned.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;local&lt;/code&gt; is simply a directory stored at &lt;code&gt;/var/lib/vz&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's common to have more than one disk in a Proxmox host, so the best approach is to separate the Proxmox OS from the disk images. For example, a node with one 480GB disk for the Proxmox OS and two 960GB disks in RAID 0 for storing the disk images and containers.&lt;/p&gt;

&lt;p&gt;To remove the &lt;code&gt;local-lvm&lt;/code&gt; and &lt;code&gt;local&lt;/code&gt; storage volumes, follow the steps below.&lt;/p&gt;

&lt;p&gt;Using the Proxmox GUI, navigate to &lt;strong&gt;Datacenter&lt;/strong&gt; &amp;gt; &lt;strong&gt;Storage&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There, select the &lt;code&gt;local-lvm&lt;/code&gt; storage volume and remove it. Next, select the &lt;code&gt;local&lt;/code&gt; storage volume and edit it to disable it, as this storage volume cannot be deleted.&lt;/p&gt;

&lt;p&gt;Now, open a shell on your node, as you will run a few commands.&lt;/p&gt;

&lt;p&gt;First, you should remove the logical volume:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lvremove /dev/pve/data
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, you're going to reclaim the free space that is left unused in the logical volume:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;lvresize &lt;span class="nt"&gt;-l&lt;/span&gt; +100%FREE /dev/pve/root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, you must expand the disk format to be able to use the newly added space:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;resize2fs /dev/mapper/pve-root
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these steps, you've successfully removed the local storage volumes from your Proxmox.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>proxmox</category>
    </item>
    <item>
      <title>Registry CRUD actions on Windows Group Policy</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Wed, 21 Jan 2026 09:00:24 +0000</pubDate>
      <link>https://forem.com/sertxudev/registry-crud-actions-on-windows-group-policy-3nji</link>
      <guid>https://forem.com/sertxudev/registry-crud-actions-on-windows-group-policy-3nji</guid>
      <description>&lt;p&gt;Using Group Policies, you can modify the registry of all computers joined to the domain.&lt;/p&gt;

&lt;p&gt;When you create a new GPO, one of the parameters you're required to configure is the action that will be performed. These are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create&lt;/li&gt;
&lt;li&gt;Update&lt;/li&gt;
&lt;li&gt;Replace&lt;/li&gt;
&lt;li&gt;Delete&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But do you know what each action entails?&lt;/p&gt;

&lt;h3&gt;
  
  
  Create action
&lt;/h3&gt;

&lt;p&gt;This action will create the registry key if it doesn't exist. If it already exists, it will do nothing, even if the actual registry value doesn't match the value set in the GPO.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update action
&lt;/h3&gt;

&lt;p&gt;This is the default action. It updates the registry value to the one set in the GPO. If the registry key doesn't exist, it will also be created.&lt;/p&gt;

&lt;h3&gt;
  
  
  Replace action
&lt;/h3&gt;

&lt;p&gt;This action will delete the registry key if it already exists and then recreate it. If it doesn't exist, it will be created. This is similar to the update action but more aggressive, because it will delete the registry key every time it is applied. This action is rarely used.&lt;/p&gt;

&lt;h3&gt;
  
  
  Delete action
&lt;/h3&gt;

&lt;p&gt;This action will delete the registry key if it's present.&lt;/p&gt;



&lt;p&gt;Now that you understand how each action works, you can begin configuring the GPO on your domain controller.&lt;/p&gt;

</description>
      <category>windows</category>
    </item>
    <item>
      <title>Disabling Fast Boot via Windows Registry</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Mon, 19 Jan 2026 09:00:23 +0000</pubDate>
      <link>https://forem.com/sertxudev/disabling-fast-boot-via-windows-registry-23hi</link>
      <guid>https://forem.com/sertxudev/disabling-fast-boot-via-windows-registry-23hi</guid>
      <description>&lt;p&gt;Fast Boot allows us to boot our computer faster by performing a deep hibernation instead of completely powering it off.&lt;/p&gt;

&lt;p&gt;If you have startup scripts, you should disable Fast Boot because it will prevent running the scripts, as your computer will not be "starting up".&lt;/p&gt;

&lt;p&gt;In a domain-controlled environment, you can set a Group Policy that disables Fast Boot for all your computers by modifying the Registry.&lt;/p&gt;

&lt;p&gt;You should configure the following Registry key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Power\HiberbootEnable
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With the value &lt;code&gt;0&lt;/code&gt; as a &lt;code&gt;DWORD&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;With this Registry key, your computer will skip the Fast Boot and perform a complete power-off and startup cycle.&lt;/p&gt;

</description>
      <category>windows</category>
    </item>
    <item>
      <title>Trust any proxy in Laravel</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Mon, 12 Jan 2026 09:00:23 +0000</pubDate>
      <link>https://forem.com/sertxudev/trust-any-proxy-in-laravel-501n</link>
      <guid>https://forem.com/sertxudev/trust-any-proxy-in-laravel-501n</guid>
      <description>&lt;p&gt;It's a common practice to deploy Laravel apps behind load balancers, aka proxy.&lt;/p&gt;

&lt;p&gt;But doing this requires you to change the middleware settings so Laravel trusts your load balancer.&lt;/p&gt;

&lt;p&gt;If you don't change it, some side effects may occur, such as hitting rate limiters on for all users at once instead of per IP address.&lt;/p&gt;

&lt;p&gt;In your &lt;code&gt;bootstrap/app.php&lt;/code&gt; file, you need to add the following inside the &lt;code&gt;-&amp;gt;withMiddleware&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$middleware&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;trustProxies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'*'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The asterisk &lt;code&gt;*&lt;/code&gt; will trust any load balancer.&lt;/p&gt;

&lt;p&gt;Please note that it's recommended to narrow down the allowed proxies, because any user can tamper with the header used to determine the real user IP.&lt;/p&gt;

&lt;p&gt;If you only have one load balancer and you know the IP address, you can set the IP address like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$middleware&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;trustProxies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'10.0.0.2'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have multiple load balancers, you can provide an array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$middleware&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;trustProxies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="s1"&gt;'10.0.0.2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'10.0.1.2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or even a CIDR for the IP addresses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$middleware&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;trustProxies&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;at&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'10.0.0.0/8'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In some cases, the load balancer adds its IP address to the right side of the &lt;code&gt;X-Forwarded-For&lt;/code&gt; standard header, maintaining the leftmost IP address as the actual user IP.&lt;/p&gt;

&lt;p&gt;To ensure Laravel obtains the correct IP address for the user's IP, you may need to set it to &lt;code&gt;0.0.0.0/0&lt;/code&gt;, allowing any load balancer to discard all IP addresses in this header except the leftmost one.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Trust proxy with Traefik in K8s</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Mon, 05 Jan 2026 09:00:22 +0000</pubDate>
      <link>https://forem.com/sertxudev/trust-proxy-with-traefik-in-k8s-582k</link>
      <guid>https://forem.com/sertxudev/trust-proxy-with-traefik-in-k8s-582k</guid>
      <description>&lt;p&gt;Traefik, by default, will not trust the standard &lt;code&gt;Forwarding&lt;/code&gt; headers Load Balancers usually populate with the client and proxy IPs.&lt;/p&gt;

&lt;p&gt;If your apps don’t need to know the user’s real IP, you don’t need to change any configuration.&lt;br&gt;
However, if you want to use the &lt;code&gt;X-Forwarded-For&lt;/code&gt; header, some changes are required.&lt;/p&gt;

&lt;p&gt;In your Traefik’s yaml configuration, you need to add the following argument with all the IP CIDRs from your Load Balancers. For example, if your Load Balancer is at &lt;code&gt;10.0.0.3&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--entryPoints.web.forwardedHeaders.trustedIPs=10.0.0.3/32
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you use MicroK8s, the arguments are in the Traefik daemonset resource.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you don’t know the Load Balancer IPs, you can use &lt;code&gt;0.0.0.0/0&lt;/code&gt; to trust all IPs, but this is not recommended, as any user can fake this header to bypass security features, such as IP-based rate limiters.&lt;/p&gt;

&lt;p&gt;Trusting all IPs at Traefik requires validating the &lt;code&gt;X-Forwarded-For&lt;/code&gt; header inside the application.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>kubernetes</category>
      <category>microk8s</category>
    </item>
    <item>
      <title>MicroK8s upgrade ingress from NGINX to Traefik</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Mon, 29 Dec 2025 09:00:25 +0000</pubDate>
      <link>https://forem.com/sertxudev/microk8s-upgrade-ingress-from-nginx-to-traefik-mn8</link>
      <guid>https://forem.com/sertxudev/microk8s-upgrade-ingress-from-nginx-to-traefik-mn8</guid>
      <description>&lt;p&gt;The Kubernetes nginx-ingress is scheduled to be retired in March 2026, so Canonical’s MicroK8s team replaced Nginx with Traefik for its ingress addon.&lt;/p&gt;

&lt;p&gt;If you’re running a MicroK8s cluster with the Nginx ingress, you may want to upgrade it.&lt;/p&gt;

&lt;p&gt;First, you need to disable the ingress addon to remove the old Nginx ingress.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;microk8s disable ingress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, you should update the core addons repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;microk8s addons repo update core
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, you can enable the new Traefik ingress.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;microk8s &lt;span class="nb"&gt;enable &lt;/span&gt;ingress
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The Traefik ingress is compatible with your previous Nginx configuration, so all your sites and services should work fine.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>linux</category>
      <category>kubernetes</category>
      <category>microk8s</category>
    </item>
    <item>
      <title>Passing Laravel route to Maizzle button</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Mon, 08 Dec 2025 09:00:26 +0000</pubDate>
      <link>https://forem.com/sertxudev/passing-laravel-route-to-maizzle-button-57</link>
      <guid>https://forem.com/sertxudev/passing-laravel-route-to-maizzle-button-57</guid>
      <description>&lt;p&gt;Maizzle is a framework that helps us quickly build HTML emails with Tailwind CSS. We can integrate it into our Laravel project to create beautiful emails.&lt;/p&gt;

&lt;p&gt;By default, Maizzle provides us with a button component which can be used as a CTA button in our emails, like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;x-button&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://maizzle.com"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-slate-950 hover:bg-slate-800"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Verify email&lt;span class="nt"&gt;&amp;lt;/x-button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Laravel, it's common to use the helper &lt;code&gt;route&lt;/code&gt; to create links to different routes of the project.&lt;/p&gt;

&lt;p&gt;For a "Verify email" button like the previous, we might modify it to something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;x-button&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"route('auth.verify-email')"&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"bg-slate-950 hover:bg-slate-800"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Verify email&lt;span class="nt"&gt;&amp;lt;/x-button&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we generate the email with this code, Maizzle will output this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"route('dns-check.results', [$check-&amp;gt;project, $check])"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, the URL will not work as it was placed without being interpreted.&lt;/p&gt;

&lt;p&gt;We might try to add the curly brackets to allow the &lt;code&gt;route&lt;/code&gt; helper to be interpreted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;x-button&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ route('auth.verify-email') }}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But Maizzle will generate this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ route(&amp;amp;amp;#039;auth.verify-email&amp;amp;amp;#039;) }}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ok, that's not working, maybe we need to add &lt;code&gt;@&lt;/code&gt; to escape the content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;x-button&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"@{{ route('auth.verify-email') }}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With these, Maizzle will generate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ route(&amp;amp;#039;auth.verify-email&amp;amp;#039;]) }}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, this is not working.&lt;/p&gt;

&lt;p&gt;The solution is to escape the content within the button component, not outside.&lt;/p&gt;

&lt;p&gt;So we will use the button as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;x-button&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"route('auth.verify-email')"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the &lt;code&gt;button.html&lt;/code&gt; component should be modified from:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;attributes&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{{ href }}}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;attributes&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"@{{ {{{ href }}} }}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we try it again, Maizzle will generate this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"{{ route('auth.verify-email') }}"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, when we send the email from our Laravel app, the button will have the correct link.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>tutorial</category>
      <category>maizzle</category>
    </item>
    <item>
      <title>Merge video with audio using FFMPEG</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Mon, 10 Nov 2025 09:00:25 +0000</pubDate>
      <link>https://forem.com/sertxudev/merge-video-with-audio-using-ffmpeg-62b</link>
      <guid>https://forem.com/sertxudev/merge-video-with-audio-using-ffmpeg-62b</guid>
      <description>&lt;p&gt;If you have two files, one with audio and one with video, you can use FFMPEG to merge them without re-encoding.&lt;/p&gt;

&lt;p&gt;For this example, the video file will be &lt;code&gt;video.mp4&lt;/code&gt; and the audio will be &lt;code&gt;audio.mp4&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;To merge both files, you should use the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ffmpeg &lt;span class="nt"&gt;-i&lt;/span&gt; video.mp4 &lt;span class="nt"&gt;-i&lt;/span&gt; audio.mp4 &lt;span class="nt"&gt;-c&lt;/span&gt;:v copy &lt;span class="nt"&gt;-c&lt;/span&gt;:a copy output.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once finished, the &lt;code&gt;output.mp4&lt;/code&gt; file will contain both audio and video together.&lt;/p&gt;

</description>
      <category>tutorial</category>
      <category>ffmpeg</category>
    </item>
    <item>
      <title>Solve Dovecot error "Unknown section name: plugin"</title>
      <dc:creator>Sergio Peris</dc:creator>
      <pubDate>Fri, 24 Oct 2025 09:00:25 +0000</pubDate>
      <link>https://forem.com/sertxudev/solve-dovecot-error-unknown-section-name-plugin-39bd</link>
      <guid>https://forem.com/sertxudev/solve-dovecot-error-unknown-section-name-plugin-39bd</guid>
      <description>&lt;p&gt;If you use Dovecot as your mail server, upgrading from 2.3 to 2.4 can cause some issues.&lt;/p&gt;

&lt;p&gt;It's always recommended to carefully read the &lt;a href="https://doc.dovecot.org/2.4.1/installation/upgrade/2.3-to-2.4.html" rel="noopener noreferrer"&gt;upgrade guide&lt;/a&gt; before upgrading a a neewer version, but if you use Plesk like me, the upgrade can happen automatically.&lt;/p&gt;

&lt;p&gt;If you're getting the following error:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;doveconf: Fatal: Error in configuration file /etc/dovecot/conf.d/37-custom-global-sieve.conf line 2: Unknown section name: plugin&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You need to modify the &lt;code&gt;37-custom-global-sieve.conf&lt;/code&gt; file to the new syntax.&lt;/p&gt;

&lt;p&gt;Until version 2.3, this was the syntax you'll probably have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi /etc/dovecot/conf.d/37-custom-global-sieve.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight systemd"&gt;&lt;code&gt;&lt;span class="err"&gt;plugin&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
       &lt;span class="c"&gt;# Make sure to run "sievec" on this:&lt;/span&gt;
       &lt;span class="nt"&gt;sieve_after &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt; /etc/dovecot/conf.d/custom-sieve/global_after.sieve
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since version 2.4, in new syntax the &lt;code&gt;plugin&lt;/code&gt; section no longer exists, and &lt;code&gt;sieve_after&lt;/code&gt; also has changed. To achieve the same functionality as before, you should update the file content to the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi /etc/dovecot/conf.d/37-custom-global-sieve.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight systemd"&gt;&lt;code&gt;&lt;span class="err"&gt;sieve_script&lt;/span&gt; &lt;span class="err"&gt;after&lt;/span&gt; &lt;span class="err"&gt;{&lt;/span&gt;
  &lt;span class="nt"&gt;sieve_script_path &lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt; /etc/dovecot/conf.d/custom-sieve/global_after.sieve
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After this change, you can run the following command to check if there's any other syntax error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;doveconf &lt;span class="nt"&gt;-n&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it displays the whole Dovecot configuration, you're ready to go.&lt;/p&gt;

&lt;p&gt;Restart your server and everything should work as expected.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>help</category>
      <category>linux</category>
    </item>
  </channel>
</rss>
