Author: Editor

  • How to Back Up a Docker Container Manually on Debian to rebuild in Minutes (Disaster Recovery Guide)

    After getting my WireGuard server working, I realised something.

    If the SSD died tomorrow, or I wanted to reinstall Debian from scratch, would I remember every change I made?

    Probably not.

    While the installation itself is documented, I wanted a quick way to recover a working WireGuard server without having to generate new keys or reconfigure every client.

    Fortunately, WireGuard stores very little state. A proper backup only needs a handful of files.


    What actually needs backing up?

    Most of the important information lives in your WireGuard project directory.

    This contains:

    • Docker Compose configuration
    • WireGuard configuration
    • Server private/public keys
    • Client keys (if you chose to keep them)
    • Peer definitions
    • IP addressing
    • Firewall rules contained within the configuration

    If these files are preserved, your clients can reconnect immediately after a rebuild because the server keeps the same identity.

    In addition to the WireGuard directory itself, I also backed up the system configuration that enables IP forwarding and my Debian network configuration.

    For my setup, that meant backing up:

    • ~/wireguard
    • /etc/sysctl.d/99-wireguard.conf
    • /etc/network/interfaces

    Creating a simple backup

    Rather than remembering every file individually, I created a small backup script.

    #!/bin/bash
    
    mkdir -p ~/backups
    
    tar czf ~/backups/wireguard-$(date +%F).tar.gz \
        ~/wireguard \
        /etc/sysctl.d/99-wireguard.conf \
        /etc/network/interfaces
    

    Running the script creates a compressed archive similar to:

    wireguard-2026-07-19.tar.gz
    

    Everything needed to rebuild the server is now stored in a single archive.


    Copying the backup off the server

    A backup isn’t much use if it lives on the same disk that could fail.

    Since I was working from Windows, I simply copied the archive using SCP.

    scp [email protected]:~/backups/wireguard-2026-07-19.tar.gz .
    

    This downloads the archive into the current directory on the Windows machine.

    From there it can be copied to another PC, NAS, cloud storage, or wherever you keep your backups.


    Why preserving the keys matters

    One of the most important files in the backup is the server’s private key.

    If you rebuild the server using the same key, every existing client (phone, laptop, tablet, etc.) will reconnect without needing to be reconfigured.

    If you generate a brand new server key instead, every client must be updated with the new public key before it can connect again.

    Keeping the original keys saves a surprising amount of work.


    Documentation is part of the backup

    A backup is only half of the recovery process.

    The other half is documentation.

    A few months from now it’s easy to forget which files were modified, where WireGuard was installed, or which configuration changes were required.

    For that reason I’m documenting every service I build.

    Eventually I want each service in my homelab to have its own recovery guide.

    For example:

    • Debian base installation
    • Docker installation
    • WireGuard recovery
    • AdGuard Home recovery
    • Nginx Proxy Manager recovery
    • Homepage recovery
    • Grafana recovery
    • Zabbix recovery

    If a machine ever fails, I should be able to reinstall Debian and have everything running again simply by following my own documentation.

    That’s one of the long-term goals of this homelab: making infrastructure reproducible instead of relying on memory.


    What I actually used

    This is the exact solution I ended up using.

    Backup script

    #!/bin/bash
    
    mkdir -p ~/backups
    
    tar czf ~/backups/wireguard-$(date +%F).tar.gz \
        ~/wireguard \
        /etc/sysctl.d/99-wireguard.conf \
        /etc/network/interfaces
    

    Copying the backup to Windows

    scp [email protected]:~/backups/wireguard-2026-07-19.tar.gz .
    

    Simple, quick, and enough for me to rebuild the WireGuard server without starting from scratch.

    I understand that there must be easier and faster ways to do all of the above, but for now this is how I’ll proceed until I come across those methods.

  • Running OPNsense as a Virtual Firewall on Proxmox Dedicated Server

    A common use case for OVH dedicated servers is running multiple virtual machines while keeping the environment securely separated behind a firewall.

    Proxmox VE is an excellent hypervisor for this, but when you want proper network segmentation, DHCP, NAT, VPN access, and firewall rules, running a dedicated firewall appliance such as OPNsense inside Proxmox makes a lot of sense.

    This guide explains how to build the following setup:

    • OVH dedicated server
    • Proxmox VE as the hypervisor
    • OPNsense running as a virtual machine
    • OVH additional/failover IP assigned to OPNsense WAN
    • Private LAN network for virtual machines
    • NAT and DHCP handled by OPNsense
    • Proxmox host remaining accessible for management

    One important OVH-specific issue is covered at the end: the “Far Gateway” problem that prevents OPNsense from reaching the OVH gateway when using routed failover IPs.


    Network Design Overview

    The final topology will look like this:

                        Internet
                           |
                      OVH Network
                           |
                  OVH Dedicated Server
                           |
            +------------------------------+
            |          Proxmox VE          |
            |                              |
            | Primary IP: a.a.a.222        |
            | vmbr0 → eno1                 |
            |                              |
            |                              |
            |       OPNsense VM            |
            |                              |
            | WAN: b.b.b.59                |
            | LAN: 10.0.0.1                |
            |                              |
            +-------------+----------------+
                          |
                        vmbr1
                          |
                  Internal VM Network
    
                  VM1 10.0.0.x
                  VM2 10.0.0.x
                  VM3 10.0.0.x
    

    The idea:

    • OVH’s original IP stays on the Proxmox host.
    • The additional OVH IP is assigned directly to the OPNsense WAN interface.
    • OPNsense becomes the router/firewall for internal VMs.
    • Internal machines never directly touch the OVH network.

    OVH Network Requirements

    You need:

    Primary OVH IP

    Example:

    IP:
    a.a.a.222
    
    Gateway:
    a.a.a.254
    
    Subnet:
    255.255.255.0 (/24)
    

    This IP belongs to the physical Proxmox host.


    Additional OVH IP

    Example:

    IP:
    b.b.b.59
    

    OVH will provide:

    • Additional/failover IP
    • Virtual MAC address

    The virtual MAC is extremely important.

    OVH uses it to identify which virtual machine should receive traffic for that IP.


    Configure Proxmox Networking

    The Proxmox host keeps the main OVH IP.

    Example:

    /etc/network/interfaces

    auto lo
    iface lo inet loopback
    
    
    auto eno1
    iface eno1 inet manual
    
    
    auto vmbr0
    iface vmbr0 inet static
        address a.a.a.222/24
        gateway a.a.a.254
        bridge-ports eno1
        bridge-stp off
        bridge-fd 0
    
    
    auto vmbr1
    iface vmbr1 inet manual
        bridge-ports none
        bridge-stp off
        bridge-fd 0
    

    Explanation:

    vmbr0

    This is the external bridge.

    vmbr0
     |
    eno1
     |
    OVH network
    

    Used for:

    • Proxmox management
    • OPNsense WAN interface

    vmbr1

    This is an internal-only bridge.

    No physical NIC is attached.

    Used for:

    • Private VM traffic
    • OPNsense LAN interface

    You can also configure this from:

    Proxmox GUI
    → System
    → Network
    

    Changes are written to:

    /etc/network/interfaces
    

    Important: Do Not Configure the Failover IP on Proxmox

    The additional OVH IP:

    b.b.b.59
    

    should NOT be added to:

    • eno1
    • vmbr0
    • Proxmox host networking

    It belongs inside the OPNsense VM.

    The OVH virtual MAC will be attached to the OPNsense WAN NIC.


    Create the OPNsense Virtual Machine

    Download the OPNsense DVD ISO.

    Upload it:

    Proxmox
    → local storage
    → ISO Images
    → Upload
    

    Create a new VM.

    Example settings (which I used this time):

    BIOS

    SeaBIOS
    

    CPU

    2 cores
    

    RAM

    4096 MB
    

    Disk

    8GB
    

    Machine

    Default i440fx
    

    Controller

    SCSI
    VirtIO SCSI single
    

    Add Network Interfaces

    The VM needs two network adapters.

    WAN Interface

    Attach to:

    vmbr0
    

    Change MAC address to the OVH virtual MAC.

    Example:

    AA:BB:CC:DD:EE:FF
    

    This is the MAC OVH assigned to:

    b.b.b.59
    

    LAN Interface

    Attach to:

    vmbr1
    

    Normal Proxmox-generated MAC is fine.


    The final VM should have:

    Net0
     |
    vmbr0
     |
    WAN
     |
    b.b.b.59
    
    
    Net1
     |
    vmbr1
     |
    LAN
     |
    10.0.0.1
    

    Install OPNsense

    Boot the VM from the ISO.

    Important:

    At the prompt do not accidentally just run the live environment using root (user) and opnsense (password).

    Instead you need to login as

    installer (and opnsense for password)
    

    Otherwise:

    root/opnsense
    

    live mode starts from the CD, and after reboot, all changes disappear.


    For filesystem:

    UFS
    

    works fine.

    ZFS is possible but usually unnecessary for a small firewall VM.

    ZFS:

    • requires more RAM
    • provides benefits mostly with larger storage setups

    Assign OPNsense Interfaces

    During first boot:

    Assign:

    WAN → vmbr0 NIC
    
    LAN → vmbr1 NIC
    

    After installation:

    Connect a VM to vmbr1 (I installed a Debian gui inside Proxmox temporarily) and access:

    https://10.0.0.1
    

    Login:

    root
    

    This is a good oppurtunity to reset the password if you didn’t already do so during the initial installation.

    Lobby
    → Password

    Once everything is completed it is good to come back around and add another user to handle standard day to day activities.


    Configure the OPNsense WAN Interface

    Go to:

    Interfaces
    → WAN
    

    Set:

    IPv4 Configuration Type:
    
    Static IPv4
    

    Enter:

    IPv4 Address:
    
    b.b.b.59
    

    Subnet:

    /32
    

    Example:

    b.b.b.59/32
    

    Why /32?

    OVH failover IPs are routed addresses.

    The IP itself does not belong to the same subnet as the gateway.

    The server gateway:

    a.a.a.254
    

    is outside:

    b.b.b.59/32
    

    This is normal.


    Configure the OVH Gateway

    Go to:

    System
    → Gateways
    → Single
    

    Create a gateway.

    Interface:

    WAN
    

    Gateway:

    a.a.a.254
    

    Enable:

    Upstream Gateway
    

    Most importantly:

    Enable:

    Far Gateway
    

    The OVH + OPNsense “Far Gateway” Problem

    This is the most common issue.

    Everything looks correct:

    • VM networking works
    • Virtual MAC is correct
    • WAN IP is correct
    • Gateway is correct

    But:

    OPNsense cannot ping OVH gateway
    

    Why?

    Because OPNsense sees:

    WAN IP:
    b.b.b.59/32
    

    Gateway:

    a.a.a.254
    

    The gateway is outside the subnet.

    Normally routers expect the gateway to be directly reachable.

    OVH’s routed setup works differently.

    The Far Gateway option tells OPNsense:

    “Yes, this gateway is outside this interface subnet. This is expected.”

    After enabling:

    Far Gateway
    

    save and apply.

    The WAN should immediately become functional.


    Configure the LAN Network

    Example:

    LAN IP:
    
    10.0.0.1/24
    

    Go to:

    Interfaces
    → LAN
    

    Set:

    IPv4:
    
    10.0.0.1/24
    

    Enable DHCP

    Go to:

    Services
    → DHCPv4
    → LAN
    

    Enable DHCP.

    Example range:

    10.0.0.50
    -
    10.0.0.200
    

    Now VMs connected to vmbr1 will automatically receive:

    IP address
    Gateway
    DNS
    

    from OPNsense.


    Configure Firewall Rules

    By default, LAN traffic may be blocked.

    Create a rule:

    Firewall
    → Rules
    → LAN
    

    Add:

    Action:
    Pass
    
    Direction:
    Out
    
    Protocol:
    Any
    
    Source:
    LAN net
    
    Destination:
    WAN net
    

    This allows:

    LAN → Internet
    

    To Check – Configure NAT

    Go to:

    Firewall
    → NAT
    → Outbound
    

    Use:

    Automatic outbound NAT
    

    OPNsense will automatically translate:

    10.0.0.x
    

    into:

    b.b.b.59
    

    when accessing the internet.


    To Check – Proxmox Firewall Considerations

    Proxmox also has its own firewall.

    For an OPNsense VM acting as the main firewall:

    Usually disable Proxmox firewall on the OPNsense NICs.

    VM settings:

    Hardware
    → Network Device
    → Firewall
    
    Disable
    

    Why?

    Because you now have:

    Internet
        |
    OPNsense firewall
        |
    VM network
    

    Adding another firewall layer can create unexpected blocking.

    A Proxmox firewall rule could prevent OPNsense from reaching the OVH gateway.


    Testing the Setup

    Test Proxmox

    SSH into Proxmox:

    ping a.a.a.254
    

    Then:

    ping 8.8.8.8
    

    Confirm the host works.


    Test OPNsense WAN

    In OPNsense:

    Interfaces / Diagnostics
    → Ping
    

    Test:

    a.a.a.254
    

    Then:

    8.8.8.8
    

    Test Internal VM

    Within the test VM:

    Network:

    vmbr1
    

    It should have already received:

    10.0.0.x
    

    Check:

    ipconfig
    

    or:

    ip addr
    

    Test:

    ping 10.0.0.1
    

    Then:

    ping 8.8.8.8
    

    Future Remote Access: WireGuard Backdoor

    A good final design is:

    Internet
     |
    Proxmox public IP
     |
    WireGuard
     |
    Private management network
     |
    OPNsense
     |
    VMs
    

    Keep the Proxmox IP:

    a.a.a.222
    

    for emergency access.

    Later:

    • restrict web access
    • disable unnecessary exposed ports
    • use WireGuard VPN for administration

    This provides a secure recovery path if OPNsense rules are accidentally misconfigured.


    Final Notes

    Running OPNsense inside Proxmox on OVH works very well, but there are a few OVH-specific details that are easy to miss:

    • Use OVH virtual MAC on the OPNsense WAN NIC
    • Keep the OVH primary IP on Proxmox
    • Use /32 for failover IPs
    • Use an internal bridge for your VM network
    • Disable Proxmox firewall on OPNsense interfaces initially
    • Enable Far Gateway in OPNsense

    That last setting is the one that usually causes hours of troubleshooting:

    OVH routed IP + OPNsense = Far Gateway required.

    Once configured correctly, OPNsense becomes a full virtual edge firewall for your Proxmox environment.

  • Create Consistent Content with AI: Turn Questions into Blog Posts

    Creating websites was never the hard part for me.

    The technical side was interesting. Learning SEO, building WordPress sites, setting up servers, experimenting with tools, and researching new ideas was exciting.

    But there was one problem I kept running into:

    I struggled to consistently create content.

    And without content, even the best website idea eventually becomes just another unfinished project.

    My Biggest Problem Wasn’t SEO

    When people talk about building niche websites, they usually focus on:

    • Finding profitable keywords
    • Writing articles
    • Building backlinks
    • Ranking on Google
    • Optimising pages for SEO

    I assumed those would be my biggest challenges.

    They weren’t.

    My biggest obstacle was much simpler:

    Creating content consistently.

    Why Traditional Content Creation Felt Difficult

    Writing a blog post from a blank page felt overwhelming.

    Recording podcast episodes felt unnatural.

    Taking photos for social media felt forced.

    Even replying to forum posts made me overthink every sentence.

    Every new project would start with excitement:

    “This is going to be great.”

    Then eventually the same thing happened.

    The ideas stayed. The motivation disappeared. The project stalled.

    The Realisation: I Wasn’t Running Out of Ideas

    After thinking about why I struggled, I noticed something important.

    I actually had no shortage of ideas.

    I was constantly curious.

    I was always asking questions.

    • Should I use subdomains or subdirectories?
    • How do 301 redirects actually work?
    • How do I find profitable niches?
    • How should I structure a homelab?
    • When should I use Nginx?
    • How do I properly secure WireGuard?

    I Naturally Learn Through Questions

    I realised something about myself:

    I don’t naturally sit down and think:

    “Today I am going to write a 2,500-word article.”

    That approach feels forced.

    Instead, I learn by asking questions.

    I explore a problem. I research solutions. I test ideas. I make mistakes. I improve.

    And then I realised:

    Maybe the conversations themselves are the content.

    Conversations Already Contain the Structure of a Blog Post

    A useful article usually contains:

    • A problem
    • A beginner’s perspective
    • Research and explanation
    • Common mistakes
    • Lessons learned
    • A final solution

    A good conversation already has those elements.

    Instead of staring at a blank document trying to create an article from nothing, I can start with genuine curiosity.

    I can ask questions, learn something valuable, and then transform that discussion into a useful resource for others.

    But Is AI Content Good Enough for SEO?

    This was my biggest concern.

    Would search engines reject content created with AI?

    The real question is:

    Does the content actually help people?

    There is a huge difference between:

    “Write me a generic article about VPNs.”

    and:

    “I am trying to secure my own WireGuard setup. Explain what I am doing wrong and help me understand the problem.”

    AI Isn’t the Author — It’s the Editor

    The way I see it now:

    I provide:

    • The curiosity
    • The questions
    • The goals
    • The decisions
    • The real-world experience

    AI helps with:

    • Structure
    • Clarity
    • Formatting
    • Editing
    • Readability

    AI is not replacing the thinking.

    It is helping communicate the thinking.

    The Best Content Comes From Real Problems

    The biggest advantage comes after actually doing something.

    Once I build, test, or experiment with something, I can add details that generic AI content cannot provide.

    • Mistakes I made
    • Solutions that failed
    • Commands that caused problems
    • Screenshots from my own setup
    • Performance results
    • Lessons learned

    These details transform an average article into something genuinely useful.

    My New Content Creation Workflow

    Instead of trying to become a professional writer, I am going to focus on something simpler:

    Learning in public.

    1. Ask genuine questions.
      Start with real problems I actually want to solve.
    2. Learn and experiment.
      Research solutions and test them.
    3. Turn the conversation into an article.
      Organise the discussion into something useful.
    4. Add personal experience.
      Include screenshots, mistakes, results, and lessons.
    5. Publish.
      Share the knowledge instead of keeping it hidden.

    Final Thoughts

    The thing stopping me from building websites was never SEO.

    It wasn’t keyword research.

    It wasn’t backlinks.

    It wasn’t even technical knowledge.

    The biggest obstacle was believing every article had to start as a perfectly written piece of content.

    It doesn’t.

    Sometimes the best content starts with a simple question.

    A question someone else might be searching for too.

    Every genuine problem I solve today could become the article that helps someone else tomorrow.