Author: Andrzej Majewski

  • Build Your Own Fort Knox: The Complete Guide to Vaultwarden on a Private VPS

    Build Your Own Fort Knox: The Complete Guide to Vaultwarden on a Private VPS

    Introduction: Your Passwords Are Weak – change that and protect yourself from criminals

    Have you ever been treated by a website like a rookie in a basic training camp? “Your password is weak. Very weak.” The system claims you can’t use it because it’s under 20 characters, doesn’t contain a lowercase or uppercase letter, 5 special characters and 3 digits. And on top of that, it can’t be a dictionary word. Or, even worse, you’ve fallen into a loop of absurdity: you type in a password you are absolutely convinced is correct. The system says it’s not. You request a reset. You get a code you have to enter in 16 seconds, 3 of which have already passed. You type a new password. “You cannot use a password that is your current password.” The one the system just rejected. It’s a digital comedy of errors that no one finds funny.

    This daily struggle with authentication systems drives us to the brink of despair. It gets to the point where, like in a certain anecdote, the only way to meet security requirements is to change the name of your cat to “CapitalK97Yslash&7”. This is funny until we realise that our digital lives are based on similarly outlandish and impossible-to-remember constructions. The problem is that human memory is fallible. Even seemingly simple passwords, like “ODORF”, which a father once set as the admin password, can slip your mind at the least opportune moment, leading to blocked access to the family computer.

    In the face of these difficulties, many of us take shortcuts. We use the same, easy-to-remember passwords across dozens of services. We create simple patterns, like the name of a building with zeros instead of the letter “O”, which in one doctor’s office protected patient data and was known by 18 people. Such practices are an open invitation to cybercriminals. The problem, however, doesn’t lie solely in our laziness. It’s the systems with terrible user interfaces and frustrating requirements that actively discourage us from caring about security. Since current methods fail, there must be a better way. A way that is both secure, convenient, and doesn’t require memorising 64-character passwords.

    Digital Safe on Steroids: Why a Password Manager is Your New Best Mate

    Before we dive into the world of self-hosting, it’s crucial to understand why a dedicated password manager is a fundamental tool for anyone who navigates the internet. It’s a solution that fundamentally changes the user’s relationship with digital security – from an antagonistic fight to a symbiotic partnership. Instead of being a problem, passwords become something that works in the background, without our effort.

    One Ring to Rule Them All (One Master Password)

    The basic concept of a password manager is brilliant in its simplicity: you only need to remember one, very strong master password (or, even better, a long phrase). This password acts as the key to an encrypted safe (called a “vault”), which stores all your other credentials. No more memorising dozens of logins.

    An Unbreakable Generator

    The greatest weakness of human passwords is their predictability. Password managers eliminate this problem by having a built-in random password generator. Want to set a random password of 100 characters that is a random string of letters, numbers and special characters? With a single click, it can create a long, complicated, and completely random password, such as X@Ln@x9J@&u@5n##BhfRe5^67gFdr. The difference in security between Kitty123!” and such a random string of characters is astronomical – it’s like comparing a plywood door to the vault door of a bank.

    Convenience and Productivity (Autofill)

    Security that makes life difficult is rarely used. That’s why password managers focus on convenience. Their most important function is autofilling login forms in browsers and applications. When you visit a bank’s website, the manager automatically detects the login fields and offers to fill them with your saved data. This not only saves time but also eliminates the risk of typos. These minutes saved each day add up, genuinely increasing productivity.

    Device Syncing

    Your digital world isn’t limited to one device. A password manager ensures you have access to your vault from anywhere – on your laptop at work, on your tablet at home, and on your smartphone while travelling. All your data is synchronised, so a password saved on one device is immediately available on the others.

    Protection Against Phishing and Attacks

    Password managers offer a subtle but powerful protection against phishing. The autofill function is tied to the specific URL of a website. If a cybercriminal sends you a link to a fake bank website that looks identical to the real one, the password manager won’t offer to autofill, because the URL will be different. This is an immediate warning sign. It also protects against “credential stuffing” attacks, where hackers test passwords stolen from one service on dozens of others. With a password manager, you can easily create separate passwords for each website, each bank, each social media portal, email account, etc. Even if someone steals data from Facebook, if you used that password exclusively for Facebook, the criminals won’t be able to log in to your bank or other services or portals with it.

    Security Audit

    Modern password managers act as a personal security auditor. They regularly scan your vault for weak, reused, or compromised passwords that have appeared in public data breaches. This allows you to proactively react and change threatened credentials.

    By automating the most difficult tasks – creating and remembering unique, strong passwords – a password manager removes the cognitive load and frustration. As a result, applying the best security practices becomes effortless, leading to a dramatic increase in your overall level of protection.

    Introducing Vaultwarden: Bitwarden for DIYers with a Heart for Privacy

    Now that we know what a powerful tool a password manager is, it’s time to choose the right one. There are many players on the market, but for privacy enthusiasts and DIYers, one project stands out in particular: Vaultwarden.

    Vaultwarden is an unofficial but fully functional server implementation of the popular Bitwarden password manager. It was written from scratch in the Rust programming language, and its main goal was to create an alternative that is incredibly lightweight and efficient. While the official, self-hosted version of Bitwarden requires 11 separate Docker containers to run and has significant hardware requirements, Vaultwarden runs in one neat container and consumes minimal resources. This means you can easily run it on a cheap mini-computer like a Raspberry Pi, an old laptop, or the smallest virtual machine in the cloud.

    Most importantly, Vaultwarden is fully compatible with all official Bitwarden client applications – browser plugins, desktop applications, and mobile apps for Android and iOS. This means you get a polished and convenient user interface while maintaining full control over your server.

    However, the real “icing on the cake” and the reason the self-hosting community has fallen in love with Vaultwarden is the fact that it unlocks all of Bitwarden’s premium features for free. Choosing Vaultwarden is not just about saving money, but a conscious decision that perfectly fits the ethos of independence and control. It’s not a “worse substitute”, but for many conscious users, simply a better choice, because its features and distribution model are fully aligned with the values of the open-source world.

    The table below shows what you get by choosing Vaultwarden.

    FeatureBitwarden (Free Plan)Bitwarden (Premium Plan sim10/year)Vaultwarden (Self-hosted)
    Unlimited passwords & devicesYesYesYes
    Secure sharing (2 users)YesYesYes
    Basic 2FA (TOTP, Email)YesYesYes
    Advanced 2FA (YubiKey, FIDO2)NoYesYes
    Integrated Authenticator (TOTP)NoYesYes
    File attachments (up to 1GB)NoYesYes
    Emergency AccessNoYesYes
    Vault health reportsNoYesYes
    Additional users (e.g. for family)NoNoYes

    Of course, this freedom comes with responsibility. Vaultwarden is a community project, which means there is no official technical support. In case of problems, you rely on documentation and help from other users on forums. There may also be a short delay in compatibility after major updates to official Bitwarden clients before Vaultwarden developers adapt the code. You are your own administrator – that’s the price for complete control.

    The Power of Self-Hosting

    The decision to use Vaultwarden is inseparably linked to a broader concept: self-hosting. It’s an idea that shifts the paradigm from being a passive consumer of digital services to being their active owner. This is a fundamental change in the balance of power between the user and the technology provider.

    Full Data Control – Digital Sovereignty

    The main and most important advantage of self-hosting is absolute control over your own data. When you use a cloud service, your passwords, notes, and other sensitive information are stored on servers belonging to a corporation. In the case of self-hosting, your password vault physically resides on hardware that you control – whether it’s a server at home or a rented virtual machine. No one else has access to it. You are the guardian of your data, which is the essence of digital sovereignty.

    No More Vendor Lock-in

    By using cloud services, you are dependent on their provider. A company can raise prices, change its terms of service, limit functionality, or even go bankrupt, leaving you with a data migration problem. Self-hosting frees you from this “ecosystem lock-in.” Your service works for as long as you want, on your terms.

    Privacy

    In today’s digital economy, data is the new oil. Providers of free services often earn money by analysing user data, selling it to advertisers, or using it to train artificial intelligence models. When you self-host services, this problem disappears. Your data is not a commodity. You set the rules and you can be sure that no one is looking at your information for commercial purposes.

    Long-Term Savings

    The subscription model has become the standard in the software world. Although a single fee may seem low, the sum of annual costs for all services can be significant. Self-hosting requires an initial investment in hardware (you can often use an old computer or a cheap Raspberry Pi) and is associated with electricity costs, but it eliminates recurring subscription fees. In the long run, it is a much more economical solution.

    Customisation and Learning Opportunities

    Self-hosting is not only about practical benefits, but also a fantastic opportunity to learn and grow. It gives you full flexibility in configuring and customising services to your own specific needs. It is a satisfying journey that allows you to better understand how the technologies we use every day work.

    For a person concerned about the state of privacy on the internet, self-hosting is not a technical curiosity. It’s a logical and necessary step to regain control over your digital life.

    An Impenetrable Fortress: How a VPN Creates a Private Bridge to Your Password Vault

    Self-hosting Vaultwarden gives you control over your data, but how do you ensure secure access to it from outside your home? The simplest solution seems to be exposing the service to a public IP address and securing it with a so-called reverse proxy (e.g., Nginx Proxy Manager). This is a popular and good solution, but it has one drawback: your service is visible to the entire world. This means it is constantly being scanned by bots for vulnerabilities and weaknesses.

    However, there is a much more secure architecture that changes the security model from “defending the fortress” to “hiding the fortress”. It involves placing Vaultwarden behind a VPN server.

    What is a VPN and how does it work?

    A VPN, or Virtual Private Network, creates a secure, encrypted “tunnel” through the public internet. When your laptop or smartphone connects to your home VPN server (e.g., using the popular and modern WireGuard protocol), it virtually becomes part of your home local network. All communication is encrypted and invisible to anyone else, including your internet service provider or the operator of the public Wi-Fi network in a café.

    “VPN-Only” Architecture

    In this configuration, the server running Vaultwarden has no ports open to the public internet. From the perspective of the global network, it is completely invisible. The only publicly accessible element is the VPN server, which listens on one specific port.

    To access your password vault, you must first connect to the VPN server. After successful authorisation, your device is “inside” your private network and can freely communicate with the Vaultwarden server, just as if both devices were standing next to each other.

    Layers of Security

    This approach creates three powerful layers of protection:

    1. Invisibility: This is the most important advantage. Cybercriminals and automated scanners cannot attack a service they cannot see. By eliminating the public access point to Vaultwarden, you reduce the attack surface by over 99%.
    2. VPN Encryption: All communication between your device and the server is protected by strong VPN encryption. This is an additional layer of security, independent of the HTTPS encryption used by the Vaultwarden application itself.
    3. Bitwarden End-to-End Encryption: Even in the extremely unlikely scenario that someone manages to break through the VPN security and listen in on network traffic, your vault data remains secure. It is protected by end-to-end encryption (E2EE), which means it is encrypted on your device using your master password before it is even sent to the server. An attacker would only see a useless, encrypted “blob” of data.

    For the hobbyist administrator, this is a huge simplification. Instead of worrying about securing every single hosted application, you focus on maintaining the security of one, solid entry point – the VPN server. This makes advanced security achievable without having to be a cybersecurity expert.

    More Than You Think: What You Can Store in Your Vaultwarden Vault

    The true power of Vaultwarden extends far beyond storing passwords for websites. Thanks to its flexible structure and support for various data types, it can become your single, trusted “source of truth” for practically any sensitive information in your life. It’s not a password manager, it’s a secret manager.

    Standard Data Types

    Vaultwarden, just like Bitwarden, offers several predefined entry types to help you organise your data:

    • Logins: The obvious foundation – they store usernames, passwords, and also codes for two-factor authentication (TOTP). Although when it comes to TOTP, I am a strong opponent of keeping them in the same application as logins and passwords. I’ll explain why in a moment.
    • Cards: A secure place for credit and debit card details. This makes online shopping easier, eliminating the need to manually enter card numbers and CVV codes.
    • Identities: Used to store personal data such as full name, addresses (billing, shipping), phone numbers, and email addresses. Ideal for quickly filling out registration forms.
    • Secure Notes: An encrypted text field for any information you want to protect.

    Creative Uses of Secure Notes and Custom Fields

    The real magic begins when we start creatively using secure notes, custom fields, and – crucially – file attachments (a premium feature in Bitwarden that is free in Vaultwarden). Your vault can become a digital “survival pack”, containing:

    • Software license keys: No more searching through old emails for your Windows or Office key.
    • Wi-Fi network passwords: Store passwords for your home network, work network, or a friend’s network.
    • Hardware information: Serial numbers, purchase dates, and warranty information for your electronics – invaluable in case of a breakdown or theft.
    • Medical and insurance data: Policy numbers, contact details for your insurer, a list of medications you take.
    • Answers to “security questions”: Instead of providing real data (which can often be found on the internet), generate random answers to questions like “What was your mother’s maiden name?” and save them in the manager.
    • Document data: Passport numbers, ID card numbers, driving license numbers.
    • Hardware configurations: Notes on the configuration of your router, home server, or other network devices.
    • Encrypted attachments: This is a game-changer. You can securely store scans of your most important documents: passport, birth certificate, employment contracts, and even your will. In case of a fire, flood, or theft, you have instant access to digital copies.

    Comparing this to the popular but dangerous practice of keeping passwords in a notes app (even an encrypted one), the advantage of Vaultwarden is crushing. Notes apps do not offer browser integration, a password generator, a security audit, or phishing protection. They are simply a digital notepad, while Vaultwarden is a specialised, fortified fortress.

    Magic at Your Fingertips: Browser Plugins and Mobile Apps

    All this powerful, secure server infrastructure would be useless if using it every day were cumbersome. Fortunately, the ecosystem of Bitwarden clients makes interacting with your private Vaultwarden server smooth, intuitive, and practically invisible. It is this seamless client integration that is the bridge between advanced security and everyday convenience.

    Configuration for Self-hosting: The First Step

    Before you start, you must tell each client application where your server is located. This is a crucial step. In both the browser plugin and the mobile app, before logging in, you need to go into the settings (usually under the cogwheel icon) and in the “Server URL” or “Self-hosted environment” field, enter the address of your Vaultwarden instance (e.g., [podejrzany link usunięto]). Remember that for this to work from outside your home, you must first configure your subdomain, or be connected to the VPN server.

    Browser Plugins: Your Personal Assistant

    The Bitwarden plugin, which you will use to connect to your Vaultwarden server (for Edge, Chrome, Firefox, Safari, and others) is the command centre in your browser.

    • Autofill in practice: When you go to a login page, a small Bitwarden icon will appear on the form fields, and the plugin’s icon in the toolbar will show the number of credentials saved for that site. Clicking on it allows you to fill in the login and password with one motion.
    • Password generator at hand: When creating a new account, you can click the plugin icon, go to the generator, create a strong password, and immediately paste it into the appropriate fields on the site.
    • Automatic saving: When you log in to a site using credentials that you don’t yet have in your vault, the plugin will display a discreet bar at the top of the screen asking if you want to save them.
    • Full access to the vault: From the plugin, you can view and edit all your entries, copy passwords, 2FA codes, and also manage folders without having to open a separate website.

    Mobile Apps (Android & iOS): Security in Your Pocket

    Bitwarden mobile apps transfer all functionality to smartphones, integrating deeply with the operating system.

    • Biometric login: Instead of typing a long master password every time, you can unlock your vault with your fingerprint or a face scan (Face ID).
    • Integration with the autofill system: Both Android and iOS allow you to set Bitwarden as the default autofill service. This means that when you open a banking app, Instagram, or any other app that requires a login, a suggestion to fill in the data directly from your vault will appear above the keyboard.
    • Offline access: Your encrypted vault is also stored locally on the device. This means you have access to it even without an internet connection (and without a VPN connection). You can view and copy passwords. Synchronisation with the server will happen automatically as soon as you regain a connection.

    After the initial effort of configuring the server, daily use becomes pure pleasure. All the complexity of the backend – the server, containers, VPN – disappears, and you only experience the convenience of logging in with a single click or a tap of your finger. This is the ultimate reward for taking back control.

    Storing TOTP Codes Directly in Vaultwarden and Why It’s a Bad Idea

    One of the tempting premium features that Vaultwarden provides for free is the ability to store two-factor authentication (TOTP) codes directly in the same entry as the login and password. At first glance, this seems incredibly convenient – all the data needed to log in is in one place. The browser plugin can automatically fill in not only the password but also copy the current 2FA code to the clipboard, shortening the entire process to a few clicks. No more reaching for your phone and rewriting six digits under time pressure.

    However, this convenience comes at a price, and that price is the weakening of the fundamental principle on which two-factor authentication is based. The idea of 2FA is to combine two different types of security: something you know (your password) and something you have (your phone with the code-generating app). By storing both of these elements in the same digital safe, which is Vaultwarden, you reduce them to a single category: things you know (or can find out by breaking the master password). This creates a single point of failure. If an attacker manages to get your master password to the manager in any way, they get immediate access to both authentication factors. The security barrier that was supposed to require compromising two separate systems is reduced to one.

    Therefore, although storing TOTP codes in a password manager is still much better than not using 2FA at all, from the point of view of maximum security, it is recommended to use a separate, dedicated application for this purpose (such as Aegis Authenticator, Authy, or Google Authenticator) installed on another device – most often a smartphone. This way, even if your password vault is compromised, your accounts will still be protected by a second, physically separate layer of security.

    Configuring the Admin Panel

    Regardless of whether you are the captain of a Docker container ship or a traditionalist who nurtures system services, at some point you will want to look behind the scenes of your Vaultwarden. This is what the admin panel is for – a secret command centre from which you can manage users, view diagnostics, and configure global server settings. By default, however, it is disabled, because like any good fortress, it doesn’t open its gates to just anyone. And after attempting to enter the panel, you will get an error message:

    “The admin panel is disabled, please configure the ‘ADMIN TOKEN’ variable to enable it”

    To activate it, you must set a special “key” – the administrator token.

    Scenario 1: Docker Lord

    If you ran Vaultwarden using Docker Compose (which is the most popular and convenient method), you set the admin panel key using the ADMIN_TOKEN environment variable. However, for security reasons, you should not use plain, open text there. Instead, you generate a secure Argon2 hash for the chosen password, which significantly increases the level of protection.

    Here is the complete and correct process:

    1. Generate the Password Hash First, come up with a strong password that you will use to log in to the admin panel. Then, using the terminal on the server, execute the command built into Vaultwarden to create its secure hash:
    docker exec -it vaultwarden /vaultwarden hash

    After entering the password twice, copy the entire generated string that starts with $argon2id$.

    1. Update the docker-compose.yml file Now add the prepared hash to the docker-compose.yml file. There are two critical rules here:
    • Every dollar sign $ in the hash must be doubled (e.g., $argon2id$ becomes $$argon2id$$) to avoid errors in Docker Compose.
    • To automatically correct the token, use the command:
    echo '$argon2id$v=1...REMAINDER_OF_TOKEN' | sed 's#\$#\$\$#g'

    The value of ADMIN_TOKEN cannot be in any apostrophes or quotes.

    Correct configuration:

    services:
      vaultwarden:
        image: vaultwarden/server:latest
        container_name: vaultwarden
        restart: unless-stopped
        volumes:
          - ./data:/data
        ports:
          - "8080:80"
        environment:
          # Example of a hashed and prepared token:
          - ADMIN_TOKEN=$$argon2id$$v=19$.....
    
    1. Apply Changes and Log In After saving the file, stop and rebuild the container with the command:

    docker-compose down
    docker-compose up -d

    Your admin panel, available at https://your.domain.com/admin, will now ask for a password. To log in, type the password you chose in the first step, not the generated hash.

    Scenario 2: Traditionalist with a system service (systemd)

    If you decided to install Vaultwarden as a native system service, for example using systemd, the configuration looks a bit different, but the idea remains the same. Instead of the docker-compose.yml file, environment variables are most often stored in a dedicated configuration file. This is usually an .env file or similar, which is pointed to by the service file.

    For example, you can create a file /etc/vaultwarden.env and put your token in it:

    ADMIN_TOKEN=your_other_very_secure_token

    Then you must make sure that the vaultwarden.service service file (usually located in /etc/systemd/system/) contains a line that loads this file with variables: EnvironmentFile=/etc/vaultwarden.env. After making the changes, you must reload the systemd daemon configuration (sudo systemctl daemon-reload), and then restart the Vaultwarden service itself (sudo systemctl restart vaultwarden). From now on, the admin panel at https://your.domain.com/admin will be active and secured with your new, shiny token.

    Summary: Why Vaultwarden on a VPN Server is Your Personal Fort Knox

    We have analysed the journey from the frustration of weak passwords to building your own digital fortress. The solution presented here is based on three powerful pillars that in synergy create a system far superior to the sum of its parts:

    1. The Power of a Password Manager: It frees you from the obligation of creating and remembering dozens of complicated passwords. It provides convenience with autofill and strength with randomly generated, unique credentials for each service.
    2. The Control of Self-Hosting: It gives you absolute sovereignty over your most valuable data. You are the owner, administrator, and guardian of your digital safe, free from corporate regulations, subscriptions, and privacy concerns.
    3. The Invisibility of a VPN: It elevates security to the highest level, making your service invisible to the public internet. Instead of building ever-higher walls around a visible fortress, you simply hide it from the sight of potential attackers.

    The combination of Vaultwarden, with its lightness and free premium features, and an architecture based on a VPN, creates a solution that is not only more secure and private than most commercial cloud services but also extremely flexible and satisfying to manage.

    It’s true, it requires some effort and a willingness to learn. But the reward is priceless: regaining full control over your digital security and privacy. It’s time to stop changing your cat’s name. It’s time to build your own Fort Knox.

  • WordPress and the “A scheduled event has failed” error

    WordPress and the “A scheduled event has failed” error

    Every WordPress site administrator knows that feeling. You log into the dashboard, and there’s a message waiting for you: “A scheduled event has failed”. Your heart stops for a moment. Is the site down? Is it a serious crash?

    Calm down! Before you start to panic, take a deep breath. This error, although it sounds serious, rarely means disaster. Most often, it’s simply a signal that the internal task scheduling mechanism in WordPress isn’t working optimally.

    In this article, we’ll explain what this error is, why it appears, and how to fix it professionally in various server configurations.

    What is WP-Cron?

    WordPress needs to perform cyclical background tasks: publishing scheduled posts, creating backups, or scanning the site for viruses (as in the case of the wf_scan_monitor error from the Wordfence plugin). To handle these operations, it uses a built-in mechanism called WP-Cron.

    The problem is that WP-Cron is not a real cron daemon known from Unix systems. It’s a “pseudo-cron” that has a fundamental flaw: it only runs when someone visits your website.

    • On sites with low traffic: If no one visits the site, tasks aren’t performed on time, which leads to errors.
    • On sites with high traffic: WP-Cron is called on every page load, which generates unnecessary server load.

    In both cases, the solution is the same: disable the built-in WP-Cron and replace it with a stable, system-level cron job.

    Scenario 1: A Single WordPress Site

    This is the most basic and common configuration. The solution is simple and comes down to two steps.

    Step 1: Disable the built-in WP-Cron mechanism

    Edit the wp-config.php file in your site’s main directory and add the following line:

    define(‘DISABLE_WP_CRON’, true);

    Step 2: Configure a system cron

    Log into your server via SSH and type crontab -e to edit the list of system tasks. Then, add one of the following lines, which will properly call the WordPress cron mechanism every 5 minutes.

    • wget method: */5 * * * * wget -q -O – https://yourdomain.co.uk/wp-cron.php?doing_wp_cron >/dev/null 2>&1
    • curl method: */5 * * * * curl https://yourdomain.co.uk/wp-cron.php?doing_wp_cron >/dev/null 2>&1

    Remember to replace yourdomain.co.uk with your actual address. From now on, tasks will be executed regularly, regardless of site traffic.

    Scenario 2: Multiple Sites on a Standard Server

    If you manage multiple sites, adding a separate line in crontab for each one is impractical and difficult to maintain. A better solution is to create a single script that will automatically find all WordPress installations and run their tasks.

    Step 1: Create the script file

    Create a file, e.g., /usr/local/bin/run_all_wp_crons.sh, and paste the following content into it. The script searches the /var/www/ directory for wp-config.php files.

    #!/bin/bash
    #
    # Script to run cron jobs for all WordPress sites
    # Optimised for ISPConfig directory structure
    # The main directory where the ACTUAL site files are located in ISPConfig
    SITES_ROOT=”/var/www/clients/”

    # Path to the PHP interpreter (may need to be adjusted)
    PHP_EXECUTABLE=”/usr/bin/php”

    # Logging (optional, but useful for debugging)
    LOG_FILE=”/var/log/wp_cron_runner.log”

    echo “Starting cron jobs (ISPConfig): $(date)” >> $LOG_FILE

    # Find all wp-config.php files and run wp-cron.php for them
    find “$SITES_ROOT” -name “wp-config.php” -print | while IFS= read -r -d ” config_file; do

        # Extract the directory where WordPress is located
        WP_DIR=$(dirname “$config_file”)

        # Extract the user name (e.g., web4) from the path
        # It’s the sixth element in the path /var/www/clients/client4/web4/web/
        WP_USER=$(echo “$WP_DIR” | awk -F’/’ ‘{print $6}’)

        if [ -z “$WP_USER” ]; then
            echo “-> WARNING: Failed to determine user for: $WP_DIR” >> $LOG_FILE
            continue
        fi

        # Check if the wp-cron.php file exists in this directory
        if [ -f “$WP_DIR/wp-cron.php” ]; then
            echo “-> Running cron for: $WP_DIR as user: $WP_USER” >> $LOG_FILE
            # Run wp-cron.php using PHP CLI, switching to the correct user
            su -s /bin/sh “$WP_USER” -c “(cd ‘$WP_DIR’ && ‘$PHP_EXECUTABLE’ wp-cron.php)”
        else
            echo “-> WARNING: Found wp-config, but no wp-cron.php in: $WP_DIR” >> $LOG_FILE
        fi
    done

    echo “Finished: $(date)” >> $LOG_FILE
    echo “—” >> $LOG_FILE

    Step 2: Grant the script execution permissions

    chmod +x /usr/local/bin/run_all_wp_crons.sh

    Step 3: Create a single cron job to manage everything

    Now your crontab can contain just one line:

    */5 * * * * /usr/local/bin/run_all_wp_crons.sh >/dev/null 2>&1

    Scenario 3: Multiple Sites with ISPConfig Panel

    The ISPConfig panel uses a specific directory structure with symlinks, e.g., /var/www/yourdomain.co.uk points to /var/www/clients/client1/web1/. Using the script above could cause tasks to be executed twice.

    To avoid this, you need to modify the script to search only the target clients directory.

    Step 1: Create a script optimised for ISPConfig

    Create the file /usr/local/bin/run_ispconfig_crons.sh. Note the change in the SITES_ROOT variable.

    #!/bin/bash
    # Script to run cron jobs for all WordPress sites
    # Optimised for ISPConfig directory structure
    # We only search the directory with the actual site files
    SITES_ROOT=”/var/www/clients/”

    # Path to the PHP interpreter
    PHP_EXECUTABLE=”/usr/bin/php”

    # Optional log file to track progress
    LOG_FILE=”/var/log/wp_cron_runner.log”

    echo “Starting cron jobs (ISPConfig): $(date)” >> $LOG_FILE

    find “$SITES_ROOT” -name “wp-config.php” -print0 | while IFS= read -r -d $’\0′ config_file; do
        WP_DIR=$(dirname “$config_file”)
        if [ -f “$WP_DIR/wp-cron.php” ]; then
            echo “-> Running cron for: $WP_DIR” >> $LOG_FILE
            (cd “$WP_DIR” && “$PHP_EXECUTABLE” wp-cron.php)
        fi
    done

    echo “Finished: $(date)” >> $LOG_FILE
    echo “—” >> $LOG_FILE

    Steps 2 and 3 are analogous to Scenario 2: give the script execution permissions (chmod +x) and add a single line to crontab -e, pointing to the new script file.

    Summary

    The “A scheduled event has failed” error is not a reason to panic, but rather an invitation to improve your infrastructure. It’s a chance to move from the unreliable, built-in WordPress mechanism to a solid, professional system solution that guarantees stability and performance.

    Regardless of your server configuration, you now have the tools to sleep soundly, knowing that your scheduled tasks are running like clockwork.

  • OpenLiteSpeed (OLS) with Redis. Fast Cache for WordPress Sites.

    OpenLiteSpeed (OLS) with Redis. Fast Cache for WordPress Sites.

    Managing a web server requires an understanding of the components that make up its architecture. Each element plays a crucial role in delivering content to users quickly and reliably. This article provides an in-depth analysis of a modern server configuration based on OpenLiteSpeed (OLS), explaining its fundamental mechanisms, its collaboration with the Redis caching system, and its methods of communication with external applications.

    OpenLiteSpeed (OLS) – The System’s Core

    The foundation of every website is the web server—the software responsible for receiving HTTP requests from browsers and returning the appropriate resources, such as HTML files, CSS, JavaScript, or images.

    What is OpenLiteSpeed?

    OpenLiteSpeed (OLS) is a high-performance, lightweight, open-source web server developed by LiteSpeed Technologies. Its key advantage over traditional servers, such as Apache in its default configuration, is its event-driven architecture.

    • Process-based model (e.g., Apache prefork): A separate process or thread is created for each simultaneous connection. This model is simple, but with high traffic, it leads to significant consumption of RAM and CPU resources, as each process, even if inactive, reserves resources.
    • Event-driven model (OpenLiteSpeed, Nginx): A single server worker process can handle hundreds or thousands of connections simultaneously. It uses non-blocking I/O operations and an event loop to manage requests. When a process is waiting for an operation (e.g., reading from a disk), it doesn’t block but instead moves on to handle another connection. This architecture provides much better scalability and lower resource consumption.

    Key Features of OpenLiteSpeed

    OLS offers a set of features that make it a powerful and flexible tool:

    • Graphical Administrative Interface (WebAdmin GUI): OLS has a built-in, browser-accessible admin panel that allows you to configure all aspects of the server—from virtual hosts and PHP settings to security rules—without needing to directly edit configuration files.
    • Built-in Caching Module (LSCache): One of OLS’s most important features is LSCache, an advanced and highly configurable full-page cache mechanism. When combined with dedicated plugins for CMS systems (e.g., WordPress), LSCache stores fully rendered HTML pages in memory. When the next request for the same page arrives, the server delivers it directly from the cache, completely bypassing the execution of PHP code and database queries.
    • Support for Modern Protocols (HTTP/3): OLS natively supports the latest network protocols, including HTTP/3 (based on QUIC). This provides lower latency and better performance, especially on unstable mobile connections.
    • Compatibility with Apache Rules: OLS can interpret mod_rewrite directives from .htaccess files, which is a standard in the Apache ecosystem. This significantly simplifies the migration process for existing applications without the need to rewrite complex URL rewriting rules.

    Redis – In-Memory Data Accelerator

    Caching is a fundamental optimisation technique that involves storing the results of costly operations in a faster access medium. In the context of web applications, Redis is one of the most popular tools for this task.

    What is Redis?

    Redis (REmote Dictionary Server) is an in-memory data structure, most often used as a key-value database, cache, or message broker. Its power comes from the fact that it stores all data in RAM, not on a hard drive. Accessing RAM is orders of magnitude faster than accessing SSDs or HDDs, as it’s a purely electronic operation that bypasses slower I/O interfaces.

    In a typical web application, Redis acts as an object cache. It stores the results of database queries, fragments of rendered HTML code, or complex PHP objects that are expensive to regenerate.

    How Do OpenLiteSpeed and Redis Collaborate?

    The LSCache and Redis caching mechanisms don’t exclude each other; rather, they complement each other perfectly, creating a multi-layered optimisation strategy.

    Request flow (simplified):

    1. A user sends a request for a dynamic page (e.g., a blog post).
    2. OpenLiteSpeed receives the request. The first step is to check the LSCache.
      • LSCache Hit: If an up-to-date, fully rendered version of the page is in the LSCache, OLS returns it immediately. The process ends here. This is the fastest possible scenario.
      • LSCache Miss: If the page is not in the cache, OLS forwards the request to the appropriate external application (e.g., a PHP interpreter) to generate it.
    3. The PHP application begins building the page. To do this, it needs to fetch data from the database (e.g., MySQL).
    4. Before PHP executes costly database queries, it first checks the Redis object cache.
      • Redis Hit: If the required data (e.g., SQL query results) are in Redis, they are returned instantly. PHP uses this data to build the page, bypassing communication with the database.
      • Redis Miss: If the data is not in the cache, PHP executes the database queries, fetches the results, and then saves them to Redis for future requests.
    5. PHP finishes generating the HTML page and returns it to OpenLiteSpeed.
    6. OLS sends the page to the user and, at the same time, saves it to the LSCache so that subsequent requests can be served much faster.

    This two-tiered strategy ensures that both the first and subsequent visits to a page are maximally optimised. LSCache eliminates the need to run PHP, while Redis drastically speeds up the page generation process itself when necessary.

    Delegating Tasks – External Applications in OLS

    Modern web servers are optimised to handle network connections and deliver static files (images, CSS). The execution of application code (dynamic content) is delegated to specialised external programmes. This division of responsibilities increases stability and security.

    OpenLiteSpeed manages these programmes through the External Applications system. The most important types are described below:

    • LSAPI Application (LiteSpeed SAPI App): The most efficient and recommended method of communication with PHP, Python, or Ruby applications. LSAPI is a proprietary, optimised protocol that minimises communication overhead between the server and the application interpreter.
    • FastCGI Application: A more universal, standard protocol for communicating with external application processes. This is a good solution for applications that don’t support LSAPI. It works on a similar principle to LSAPI (by maintaining permanent worker processes), but with slightly more protocol overhead.
    • Web Server (Proxy): This type configures OLS to act as a reverse proxy. OLS receives a request from the client and then forwards it in its entirety to another server running in the background (the “backend”), e.g., an application server written in Node.js, Java, or Go. This is crucial for building microservices-based architectures.
    • CGI Application: The historical and slowest method. A new application process is launched for each request and is closed after returning a response. Due to the huge performance overhead, it’s only used for older applications that don’t support newer protocols.

    OLS routes traffic to the appropriate application using Script Handlers, which map file extensions (e.g., .php) to a specific application, or Contexts, which map URL paths (e.g., /api/) to a proxy type application.

    Communication Language – A Comparison of SAPI Architectures

    SAPI (Server Application Programming Interface) is an interface that defines how a web server communicates with an application interpreter (e.g., PHP). The choice of SAPI implementation has a fundamental impact on the performance and stability of the entire system.

    The Evolution of SAPI

    1. CGI (Common Gateway Interface): The first standard. Stable, but inefficient due to launching a new process for each request.
    2. Embedded Module (e.g., mod_php in Apache): The PHP interpreter is loaded directly into the server process. This provides very fast communication, but at the cost of stability (a PHP crash causes the server to crash) and security.
    3. FastCGI: A compromise between performance and stability. It maintains a pool of independent, long-running PHP processes, which eliminates the cost of constantly launching them. Communication takes place via a socket, which provides isolation from the web server.
    4. LSAPI (LiteSpeed SAPI): An evolution of the FastCGI model. It uses the same architecture with separate processes, but the communication protocol itself was designed from scratch to minimise overhead, which translates to even higher performance than standard FastCGI.

    SAPI Architecture Comparison Table

    FeatureCGIEmbedded Module (mod_php)FastCGILiteSpeed SAPI (LSAPI)
    Process ModelNew process per requestShared process with serverPermanent external processesPermanent external processes
    PerformanceLowVery highHighHighest
    Stability / IsolationExcellentLowHighHigh
    Resource ConsumptionVery highModerateLowVery low
    OverheadHigh (process launch)Minimal (shared memory)Moderate (protocol)Low (optimised protocol)
    Main AdvantageFull isolationCommunication speedBalanced performance & stabilityOptimised performance & stability
    Main DisadvantageVery low performanceInstability, security issuesMore complex configurationTechnology specific to LiteSpeed

    Comparison of Communication Sockets

    Communication between processes (e.g., OLS and Redis, or OLS and PHP processes) occurs via sockets. The choice of socket type affects performance.

    FeatureTCP/IP Socket (on localhost)Unix Domain Socket (UDS)
    AddressingIP Address + Port (e.g., 127.0.0.1:6379)File path (e.g., /var/run/redis.sock)
    ScopeSame machine or over a networkSame machine only (IPC)
    Performance (locally)LowerHigher
    OverheadHigher (goes through the network stack)Minimal (bypasses the network stack)
    Security ModelFirewall rulesFile system permissions

    For local communication, UDS is a more efficient solution because it bypasses the entire operating system network stack, which reduces latency and CPU overhead. This is why it’s preferred in optimised configurations for connections between OLS, Redis, and LSAPI processes.

    Practical Implementation and Management

    To translate theory into practice, let’s analyse a real server configuration for the virtual host solutionsinc.co.uk.

    5.1 Analysis of the solutionsinc.co.uk Configuration Example

    1. External App Definition:
      • In the “External App” panel, a LiteSpeed SAPI App named solutionsinc.co.uk has been defined. This is the central configuration point for handling the dynamic content of the site.
      • Address: UDS://tmp/lshttpd/solutionsinc.co.uk.sock. This line is crucial. It informs OLS that a Unix Domain Socket (UDS) will be used to communicate with the PHP application, not a TCP/IP network socket. The .sock file at this path is the physical endpoint of this efficient communication channel.
      • Command: /usr/local/lsws/lsphp84/bin/lsphp. This is the direct path to the executable file of the LiteSpeed PHP interpreter, version 8.4. OLS knows it should run this specific programme to process scripts.
      • Other parameters, such as LSAPI_CHILDREN = 50 and memory limits, are used for precise resource and performance management of the PHP process pool.
    2. Linking with PHP Files (Script Handler):
      • The application definition alone isn’t enough. In the “Script Handler” panel, we tell OLS when to use it.
      • For the .php suffix (extension), LiteSpeed SAPI is set as the handler.
      • [VHost Level]: solutionsinc.co.uk is chosen as the Handler Name, which directly points to the application defined in the previous step.
      • Conclusion: From now on, every request for a file with the .php extension on this site will be passed through the UDS socket to one of the lsphp84 processes.
    image 114
    image 115

    This configuration is an excellent example of an optimised and secure environment: OLS handles the connections, while dedicated, isolated lsphp84 processes execute the application code, communicating through the fastest available channel—a Unix domain socket.

    5.2 Managing Unix Domain Sockets (.sock) and Troubleshooting

    The .sock file, as seen in the solutionsinc.co.uk.sock example, isn’t a regular file. It’s a special file in Unix systems that acts as an endpoint for inter-process communication (IPC). Instead of communicating through the network layer (even locally), processes can write to and read data directly from this file, which is much faster.

    When OpenLiteSpeed launches an external LSAPI application, it creates such a socket file. The PHP processes listen on this socket for incoming requests from OLS.

    Practical tip: A ‘Stubborn’ .sock file

    Sometimes, after making changes to the PHP configuration (e.g., modifying the php.ini file or installing a new extension) and restarting the OpenLiteSpeed server (lsws), the changes may not be visible on the site. This happens because the lsphp processes may not have been correctly restarted with the server, and OLS is still communicating with the old processes through the existing, “old” .sock file.

    In such a situation, when a standard restart doesn’t help, an effective solution is to:

    1. Stop the OpenLiteSpeed server.
    2. Manually delete the relevant .sock file, for example, using the terminal command: rm /tmp/lshttpd/solutionsinc.co.uk.sock
    3. Restart the OpenLiteSpeed server.

    After restarting OLS, not finding the existing socket file, it will be forced to create a new one. More importantly, it will launch a new pool of lsphp processes that will load the fresh configuration from the php.ini file. Deleting the .sock file acts as a hard reset of the communication channel between the server and the PHP application, guaranteeing that all components are initialised from scratch with the current settings.

    Summary

    The server configuration presented is a precisely designed system in which each element plays a vital role.

    • OpenLiteSpeed acts as an efficient, event-driven core, managing connections.
    • LSCache provides instant delivery of pages from the full-page cache.
    • Redis acts as an object cache, drastically accelerating the generation of dynamic content when needed.
    • LSAPI UDS creates optimised communication channels, minimising overhead and latency.

    An understanding of these dependencies allows for informed server management and optimisation to achieve maximum performance and reliability.

  • Error: Change ARI Username Password FreePBX Asterisk

    Error: Change ARI Username Password FreePBX Asterisk

    In early 2023, the number of attacks on FreePBX Asterisk systems increased. The vulnerability exploited by hackers is the ARI interface. To gain access to the ARI interface, one must know the ARI username and password, but also the login details for the FreePBX administrative interface. This is why it is so important to use strong, hard-to-crack passwords. In the new version of FreePBX, we are shown the error: Change ARI Username Password.

    The ARI user and its password are created during the FreePBX installation. The username consists of about 15 random characters, and the password of about 30 random characters. The developers of the FreePBX system discovered that for some reason on some systems the username and password are not unique.

    This does not look like an error in Asterisk or FreePBX itself, so their versions are irrelevant here. If there has been a leak of ARI data, the hacker can gain access to our FreePBX system regardless of its version.

    How to get rid of the “Change ARI Username Password” error

    image 112

    To patch the security hole, we must create a new ARI user and a new password for it. To create a new ARI user, log in to your FreePBX system and enter the command:

    fwconsole rpc "ari.create_user('RANDOM_CHARACTERS', 'RANDOM_PASSWORD')"

    In place of RANDOM_CHARACTERS, enter 15 random alphanumeric characters. Then create a new password with the command:

    fwconsole rpc "ari.change_password('RANDOM_CHARACTERS', 'RANDOM_PASSWORD')"

    In place of RANDOM_PASSWORD, enter 30 random alphanumeric characters. Next, we need to reload the settings with the command:

    fwconsole reload

    Finally, all you have to do is restart FreePBX with the command:

    fwconsole restart

    After the restart, the “Change ARI Username Password” error message should disappear.

    image 113

    Summary

    FreePBX is an extremely secure system. However, even the most secure system will be vulnerable to hacking if easy-to-crack passwords are used and the configuration is incorrect.

  • CyberPanel and running out of disk space. XCP-ng, LVM increasing disk size.

    CyberPanel and running out of disk space. XCP-ng, LVM increasing disk size.

    Sometimes it happens that the disk space allocated to our websites on our server turns out to be too small. If our operating system is installed on LVM (Logical Volume Manager), we can relatively easily expand the disk size to what we need. In this article, I will show you how to do it.

    Our working environment:

    • Virtual machine running on XCP-ng
    • Ubuntu 20.04 Server Edition operating system
    • OpenLiteSpeed web server
    • CyberPanel management panel
    • Disk space based on LVM (Logical Volume Manager)

    The 64GB allocated for websites on our server some time ago proved to be too little after a while. After exceeding 80% disk usage, the server slowed down and opening pages became uncomfortable.

    image 108

    What is LVM (Logical Volume Manager)?

    LVM is an extremely flexible tool that allows you to conveniently manage disk space on your servers. LVM can be located on different hard disks and different partitions of different capacities, and we can change the size of the disk space on the fly without even having to restart the computer or virtual machine.

    image 109

    Checking hard disk usage

    To check the usage of our hard disk, use the df command with the -h parameter, which shows the disk size in a human-friendly format.

    In the case of our system, the LVM disk size (/dev/mapper/ubuntu-vg-ubuntu-lv) is 62GB, and 56GB is occupied, which gives 95% disk space usage. This is definitely too little free space for the server to work efficiently. It’s time to allocate more space to the server.

    Increasing disk size in XCP-ng

    For our virtual machine on which the Ubuntu system with a web server is installed, we have only allocated 64GB, so the first step will be to increase the virtual hard disk for our virtual machine. To perform this operation, we will have to turn off our virtual machine for a while. To do this, we run the XCP-ng center application. Then we select the virtual machine we are interested in, and turn it off. We go to the Storage tab, click on the storage we want to enlarge and click Properties. We select Size and Location and increase the size of the virtual hard disk. Then we can restart our virtual machine.

    image 110

    Checking free space in Volume Group

    To display information about our volume groups, type vgs.

    Our volume group is ubuntu-vg with a new size of 126.50GB and it has 63.25GB of free space. To display more information about the volume group, use the vgdisplay command.

    Here we can see that the space allocated to our volume group is 63.25GB and we have another 63.25GB available, which we can add to our volume group.

    Displaying a list of logical volumes

    To display our logical volumes, type lvs.

    In our case, the logical volume ubuntu-lv belongs to the ubuntu-vg volume group.

    NOTE: Remember to replace our volume names with your own when typing commands.

    Increasing the size of our logical volume

    To assign more disk space to our volume group, we will use the lvextend command. Remember to replace ubuntu-vg and ubuntu-lv with the volumes used in your system.

    The -L parameter allows us to specify the size by which we want to increase our logical volume, in our case we are increasing it by 63.25GB.

    Note: Remember that we do not specify units TB, GB, MB etc., but P for Petabytes, T for Terabytes, G for Gigabytes, M for Megabytes etc.

    After re-entering the vgdisplay command, we see in the Alloc PE/Size field that the additional disk space has been correctly allocated.

    Enlarging the file system

    Our new disk space is not yet visible to the system. We must first enlarge the file system with the resize2fs command.

    By giving the resize2fs command, we must indicate where our logical volume is mounted, in our case it is /dev/mapper/ubuntu--vg-ubuntu--lv.

    After this operation, our new disk space is already visible to the operating system and CyberPanel. 47% disk usage is a decent result and should be enough for a while.

    image 111

    Summary

    As you can see, LVM has many advantages. If you had an operating system installed on normal disks and partitions, you probably would not be able to do without formatting the disks and installing the system from scratch. Whereas LVM allows you to add a new disk to your computer, create a partition on it and add it to an already existing group of volumes and logical volumes. Easy, fast and enjoyable.

    If you have any questions about increasing the capacity of LVM volumes, do not hesitate to ask them in the comments.

  • FreePBX SIP Trunk – Connecting to the world. Part 7

    FreePBX SIP Trunk – Connecting to the world. Part 7

    Once we have our internal telephone network configured (if not, check out our previous guides), it is time to connect our PBX to the external telephone network so that people can get through to us. To achieve this, we need a virtual phone number – either a landline or a mobile number, and a SIP trunk, which is a service that allows our FreePBX system to communicate with the national (or international) telephone network. You can usually get both services (the phone number and the SIP trunk) from a single provider.

    What a SIP Trunk gives us

    A SIP Trunk is a connection between traditional landline and mobile telephony and a VoIP telephony network. But how exactly does it work? Our SIP Trunk provider will give us a virtual phone number that our customers, who use mobile phones and landlines, can call, and then these calls will be transferred over the Internet to our FreePBX Asterisk server. A SIP Trunk also enables two-way communication, allowing calls from our internal telephone network to the outside world. The main advantages include:

    • Hundreds of simultaneous calls – An additional advantage is that even if we only have one virtual phone number, we can receive and make dozens, or even hundreds, of calls simultaneously, all depending on the performance of the computer on which the FreePBX Asterisk server is installed and the capacity of our Internet connection.
    • Price – The typically much lower cost is also a significant factor. FreePBX Asterisk is usually a lot cheaper than if we had to order and pay for dozens or hundreds of subscriptions from a traditional operator.
    • Recording all calls – FreePBX Asterisk makes it easy to configure the recording of all calls, both inbound and outbound, as well as voicemail for all phones on the internal network. Listening back to previous conversations makes running the business much easier. Note: Don’t forget to notify your customers about call recording, for example during a welcome message. You will learn how to configure a welcome message in FreePBX Asterisk in one of the next parts of our guides.
    • Notifications – Another very useful feature is email notifications for missed calls and messages left on voicemails. Notifications can be configured so that voicemail recordings are sent directly in the email message. This is extremely useful if we are away from the office.
    • The ability to connect our telephony to a CRM application – Some SIP Trunk providers offer the integration of our telephony with CRM systems. This means that all telephone calls made from our network are automatically linked to our CRM system’s customer database.
    • Easy number portability to another location – Thanks to the fact that our number is not assigned to a telephone line, we can easily move our entire telephone infrastructure to another location. All that is needed is a sufficiently fast internet connection in the new location, and we are able to move our entire telephony system within a few hours.
    • Choice of any area code – No matter where our PBX is located, we can assign area codes from all over the country to it.
    • IVR – Most SIP Trunk providers offer an IVR service, which is an automated assistant. Depending on the day of the week, business hours, or the topic of the call, the digital assistant will allow the customer to connect to the appropriate department, or will redirect the call to a voicemail or a mobile number if it is after business hours. Remember, however, that there is no need to pay a provider for this service, as you can get the same functions for free in FreePBX Asterisk.
    • Virtual FAX – FreePBX Asterisk also supports a free virtual FAX. We will explain how to configure it in one of the next parts of our guides.

    Choosing a SIP Trunk Provider

    • In the UK, there is a good choice of SIP Trunk providers. It would be a good idea if we had the opportunity to test the service for free before signing a contract. Also, make sure that the provider works correctly with FreePBX Asterisk. In addition to the phone number and SIP Trunk, providers can offer you many additional features for an extra fee, such as IVR (Interactive Voice Response), call forwarding, or call recording, but there is no need to spend money on them, as you can implement all these options for free with FreePBX Asterisk. All you need is a phone number and a SIP Trunk. When choosing a landline number, you will usually be able to choose an area code from any part of the country. If your company operates locally, it is worth choosing an area code from your region, as research shows that customers are much more likely to answer calls with a local area code.

    What to look out for when choosing a SIP Trunk provider?

    • Prices of subscriptions for the SIP Trunk service and for the virtual phone number.
    • Call costs to landline, mobile, and international numbers.
    • Packages of free calls.
    • Customer service quality, working hours, and days.

    Check the offer of one of the British providers, comparing the prices of the SIP Trunk subscription, the virtual phone number subscription, and the cost per minute for calls to landline and mobile numbers:

    • Actio
    • TeleCube
    • EasyCall
    • Spikon
    • IPpfon
    • Apifonica
    • Zadarma

    SIP Trunk Settings in FreePBX Asterisk

    Once we have our virtual phone number and a purchased SIP Trunk service, it’s time to configure our FreePBX Asterisk. To do this, click on the Connectivity tab, and then on Trunks.

    image 97

    Click on Add Trunk and select its type. Most often it will be Add SIP (chan_pjsip) Trunk, or Add SIP (chan_sip) Trunk in the case of older versions of FreePBX Asterisk. If you are not sure which one to choose, ask your SIP Trunk provider. The settings for these two versions of Trunk are slightly different. We will discuss the differences below.

    image 98

    General Tab

    image 99
    • Trunk Name – any name. For example, the name of your SIP Trunk provider.
    • Hide CallerID – turn on this option if you want to hide your phone number.
    • Outbound CallerID – ask your SIP Trunk provider about this.
    • CID Options – We set which CallerIDs are allowed to use our PBX. We most often set Allow Any CID.
    • Maximum channels – here we set the maximum number of simultaneous outbound calls. If we leave this field empty, the number of outbound calls will be unlimited.
    • Leave the other options unchanged.

    pjsip Settings – General Tab

    This tab applies only to the pjsip Trunk version. If you are configuring the sip Trunk version, see the paragraph below. You should receive all the settings you need in this tab from your SIP Trunk provider.

    sip Settings Tab

    image 100
    image 101

    The sip Trunk settings differ from pjsip. In the Outgoing and Incoming tabs, enter the settings received from your SIP Trunk provider. After entering all the settings, save them by clicking Submit, and then Apply Config.

    Checking the correct operation of the SIP Trunk

    To check if the entered SIP Trunk has connected correctly with our provider, you can do it in two ways:

    Check via SSH

    Log in to your FreePBX server using SSH and enter the following commands:

    • asterisk -rvvv
    • pjsip show endpoints

    If a correct connection has been made with the provider, you should see the message “Endpoint Available” and the connection’s IP address.

    Check via the browser

    Go to ReportsAsterisk Info. In the PJSIP, or CHANSIP window (depending on which version of SIP Trunk you are using), you should see the connection’s IP addresses, and the channel for that SIP Trunk should be highlighted in green.

    image 102
    image 103

    If our SIP Trunk is correctly connected to the provider, we can proceed to the next step and set up Inbound Routes to tell FreePBX Asterisk to use our SIP Trunk for inbound calls.

    Inbound Routes – Inbound Calls

    Go to Connectivity and Inbound Routes. Add a new Inbound Route by clicking on Add Inbound Route.

    image 104
    • Description – Enter any description.
    • DID Number – Enter the DID number received from your SIP Trunk provider.

    Leave the other fields apart from Set Destination unchanged. The Set Destination option contains a number of options and allows us to choose where inbound calls should be directed. This option gives us enormous possibilities. We can direct callers to different places depending on whether our company is currently open or not. We can redirect the caller to an IVR so they can select the appropriate department, or give them the option to send a fax to us. We will cover this option in more detail in one of the next articles. For a start, we will simply set all inbound calls to be directed to the Extension number we created in part 5 of our guides. So, select Extensions from the options and you should be able to select the previously created Extension.

    image 105

    Save the settings by clicking Submit, and then Apply Config. Inbound calls should now work, and you should be able to call your landline number received from the provider from your mobile. We will now configure outbound calls.

    Outbound Routes – Outbound Calls

    Go to Connectivity and then Outbound Routes. Add new outbound calls by clicking on Add Outbound Route.

    image 106
    • Route Name – provide any name.
    • Route CID – provide your virtual phone number received from the provider.
    • Trunk Sequence for Matched Routes – select your SIP Trunk from the list.

    If you want all outbound calls to be recorded, go to the Additional Setting tab and select Yes, or Force in the Call Recording field.

    Dial Patterns

    We will not go into the details of the Dial Patterns settings in this article. For a start, simply enter X. in the first box (Capital letter X and a dot). This means that the first digit can be from 0 to 9 and the number can have any number of digits. This will allow you to call any phone numbers without restrictions.

    image 107

    Save the settings by clicking Submit, and then Apply Config.

    Summary

    Congratulations! You have successfully configured inbound and outbound calls. We invite you to our next parts of the guides on FreePBX Asterisk.

  • From a Text File to an Online Game: A Complete Guide to Deploying a React App

    From a Text File to an Online Game: A Complete Guide to Deploying a React App

    Do you have the code for a React game ready, but it’s all in a single text file? Do you want to host this game on your WordPress site, in a specific subdirectory, and be able to update it easily? This guide will walk you through the entire process, step by step, from creating the project and configuring it, to publishing and troubleshooting common issues.

    Step 1: Creating the Project Structure from a Code File

    The first challenge is to transform a loose code file into a fully-fledged, working React project. Simply having a .txt file isn’t enough – we need a complete structure of folders and configuration files to install dependencies and build the application.

    We’ll use Vite, a modern build tool, to quickly generate a React project structure.

    1. Create the project:npm create vite@latest movie-quiz -- --template react
      This command creates a new folder named movie-quiz and fills it with a complete, minimal React project template.
    2. Install dependencies:cd movie-quiz npm install
      After entering the new folder, npm install reads the package.json file and downloads all the necessary libraries into a node_modules subfolder.

    Once these steps are complete, you’ll have a ready-to-use project structure. Now, simply copy the code from your Quiz game Movies - React.txt file and paste it into src/App.jsx, replacing the default content.

    Step 2: Configuring Tailwind CSS

    If your code, like ours, uses style classes from Tailwind CSS (e.g., bg-gray-50, font-bold), we need to add it to the project. The latest versions of Tailwind integrate with Vite very easily.

    Install the plugin:npm install @tailwindcss/vite

    Update the Vite configuration: Open the vite.config.js file and add the Tailwind plugin:

    import { defineConfig } from 'vite'
    import react from '@vitejs/plugin-react'
    import tailwindcss from '@tailwindcss/vite'
    
    export default defineConfig({
      plugins: [
        react(),
        tailwindcss(),
      ],
    })
    

    Import the styles: Open the src/index.css file, delete its content, and paste in this single line:@import "tailwindcss";

    After these steps, the application, when run with npm run dev, should display correctly with all styles applied.

    Step 3: Publishing the Game in a WordPress Subdirectory

    Once the game is working locally, we can publish it online.

    1. Configure the base path: To make the game work in a subdirectory (e.g., /quiz-game/), we need to add the base: '/quiz-game/' option to the vite.config.js file. This is a crucial step that ensures all paths to assets (CSS, JS) in the built application are correct.
    2. Build the production version:npm run build
      This command creates a dist folder containing optimised, static files of your game, ready for publishing.
    3. Upload the files to the server: Using an FTP client, connect to your server, create a quiz-game subdirectory in your main WordPress folder, and upload the contents of the dist folder into it.
    4. Configure .htaccess: To ensure that refreshing the page within the game works correctly, create a .htaccess file inside the quiz-game folder on the server. This file should contain rules to redirect all requests to the game’s index.html file, preventing WordPress from taking over the routing and showing a 404 error.

    Step 4: Updating the Game

    The process for updating the game (e.g., adding new questions) is simple and cyclical:

    1. Modify the code: Change the project files on your computer (e.g., add questions in src/App.jsx).
    2. Rebuild: Run npm run build to create a new version of the files in the dist folder.
    3. Publish: Connect to the server, delete the old contents of the quiz-game folder, and upload the new contents from the dist folder in its place.

    Glossary of Commands Used

    • npm create vite@latest [name] -- --template react: Creates a new, ready-to-use React project using Vite.
    • cd [folder-name]: (Change Directory) Changes the current directory in the terminal.
    • npm install: Reads the package.json file and installs all necessary libraries.
    • npm install [package-name]: Installs a specific, additional package.
    • npm run dev: Starts a local development server with live preview.
    • npm run build: Creates an optimised, production version of the application in the dist folder.
    • npx [command]: Executes a command from a package installed locally in the project.
    • nvm install [version]: Installs a specific version of Node.js using NVM.
    • nvm use [version]: Switches the active version of Node.js in the terminal.
    • rm -rf [folder-name]: (Remove) Deletes a folder and all of its contents.
    Quiz game 1 1
    Quiz game 2 1
    Quiz game 3 1

    Troubleshooting (FAQ)

    Here we’ve collected the errors we encountered during the process, along with their solutions.

    Error: Could not read package.json

    Problem:

    Attempting to run an npm command like npm run build in a folder that only contains a code file, not a full project structure.

    Solution:

    You must first create a full project structure using a command like npm create vite@latest project-name — –template react, and only then move your code into it and run npm commands.

    Error: could not determine executable to run

    Problem:

    The command npx tailwindcss init -p fails. npx is unable to find and run the tailwindcss package.

    Solution:

    This error can have many causes, from a corrupted npm cache to path issues on your system. The most effective solution is to bypass the problem by using the modern Tailwind integration with Vite (described in Step 2), which doesn’t require running this command manually. However, if you must run it, first try a clean install (rm -rf node_modules package-lock.json, followed by npm install).

    Error: Message about the PostCSS plugin for Tailwind

    Problem:

    After starting the development server, an error appears stating that the PostCSS plugin for Tailwind has been moved to a separate package.

    Solution:

    This error occurs when trying to use an older configuration method with the latest version of Tailwind CSS (v4+). The correct solution is to use the official @tailwindcss/vite plugin, which automates the entire process. You need to install the plugin, add it to your vite.config.js file, and remove the old configuration from postcss.config.js (if it exists).

  • FreePBX Adding a Cisco SPA525G2 VoIP phone part 6

    FreePBX Adding a Cisco SPA525G2 VoIP phone part 6

    FreePBX Adding a Cisco SPA525G2 phone

    After the initial setup of our FreePBX Asterisk, it’s time to add VoIP phones to our PBX so we can finally start making calls. The first to go will be the very successful, inexpensive, and easy-to-configure Cisco SPA525G2 VoIP phone. It is an improved version of the SPA525G model, differing only in the addition of Bluetooth communication, which allows us to pair our VoIP phone with any smartphone and conveniently switch calls to the smartphone.

    A Cisco SPA525G2 VoIP phone featuring a colour display, keypad, and various function buttons for FreePBX
    SPA525G2 FreePBX

    This model has five telephone lines, which means it allows up to five telephone calls to be made simultaneously. These calls can be conveniently switched between using the backlit buttons on the right side of the screen.

    image 87

    The phone can be connected with a 5V power supply, or directly from a PoE switch with a LAN cable. It has a colour display with a 3.2-inch diagonal and a resolution of 320×240 pixels. The phone can be easily managed via a web browser.

    image 88

    Cisco SPA525G2 setting a static IP address

    After connecting the phone to our LAN, the first step should be to set a static IP address instead of the one assigned dynamically by the DHCP server. To do this, press the ‘Settings’ button on the phone, and then use the cursor to navigate to ‘Network Configuration-Connection Type’ and change the mode from ‘DHCP’ to ‘Static IP’.

    Now we need to set the IP address, gateway and subnet mask. So we press ‘Settings’, ‘Network Configuration’ and go to the ‘Static IP Address Settings’ by entering the following in the given fields:

    1. IP Address, remembering that both our phone, FreePBX and the router must be on the same subnet. In our case, the router has the address 192.168.0.1, and FreePBX has the address 192.168.0.178. If your subnet mask has the number 255.255.255.0, then the phone’s IP address must be 192.168.0.X, where X is a number from 0 to 255. Of course, the IP address on your network must be unique, so it cannot be number 1, 178, or any other number already in use on your network.
    2. Subnet mask – If you do not have more than 256 network devices on your network, it is usually 255.255.255.0.
    3. Gateway address – The IP address of your router
    4. DNS 1 and DNS 2 – you can enter the IP address of any DNS server, for example 1.1.1.1, 8.8.8.8, or 8.8.4.4.

    Finally, we save the settings by pressing the button under the ‘Set’ label.

    Cisco SPA525G2 phone settings in the web browser

    Once we have set a static IP address for our phone, we launch a web browser on the computer and enter the IP address of our phone. You will then see a window with information about our phone, but only in user mode, from which we will not be able to make the changes needed to connect it to our FreePBX. To do this, we must switch to administrator mode by clicking the ‘Admin login’ link in the top right corner and entering the password. If no one has changed the password, the default login is ‘admin’ and the password is ‘admin’.

    image 89

    After logging in to administrator mode, we go to the ‘Ext 1’ tab, where we will have to enter a few options to connect our phone to FreePBX:

    1. Proxy – we enter the IP address of our FreePBX here.
    2. Register – we set to ‘yes’.
    3. Display Name – we enter any name here that will identify our phone.
    4. User ID – here we must enter the number of our Extension from FreePBX, which we created in the previous article.
    5. Password – We enter the password we created here, when creating the Extension in FreePBX in the ‘Secret’ field.

    We save the changes with the ‘Submit All Changes’ button. The other fields are not relevant at the moment.

    Note: Make sure you have entered the correct Extension number in the ‘User ID’ field and the ‘Secret’ password in the ‘Password’ field. Without this, the phone will not register correctly in FreePBX.

    image 90

    After a while the phone will restart and if you have entered all the data correctly, the phone should already be connected to FreePBX, and you should see phone icons on the display, just like in the picture below.

    image 91

    If the entered data is incorrect, or for other reasons the phone cannot register with FreePBX, then you will see raised handsets with exclamation marks on the display, and the phone line buttons will light up red, just like in the picture below.

    image 92

    Cisco SPA525G2 telephone line configuration

    By default, the Cisco SPA525G2 phone has all 5 phone lines connected to one Extension in FreePBX. But there is nothing to stop our phone from having 5 different internal numbers assigned.

    Note: Oh! There’s nothing to stop our phone from handling 5 different landline numbers if we have 5 FreePBX servers connected to 5 virtual landline numbers, but that’s a story for another article.

    To set different internal numbers on one phone, for each of the 5 telephone lines, we must of course have 5 different Extensions in FreePBX. You can find out how to do this in our previous guide on Extensions.

    If we have already created additional Extensions in FreePBX, we can go to the ‘Ext 2’ tab by typing the IP address of our phone in the browser (don’t forget to switch to Administrator mode) and in the ‘User ID’ and ‘Password’ window, we enter the number and ‘Secret’ of our second Extension, in the ‘Proxy’ field we re-enter the IP address of our FreePBX and confirm the changes with the ‘Submit All Changes’ button.

    We perform similar actions for the remaining telephone lines in the ‘Ext 3’, ‘Ext 4’ and ‘Ext 5’ tabs.

    Next, we go to the ‘Phone’ tab and change the numbers in the ‘Line Key’ field for each telephone line.

    image 93

    Cisco SPA525G2 Friendly names instead of Extension numbers

    By default, the Cisco SPA525G2 phone displays Extension numbers (using the SUSER variable) on the display, instead of friendly names, for example, Reception, Technical Department, or Orders Department. Sometimes several employees use one phone and we can assign them separate internal numbers with their names. To change this, we must go back to the ‘Phone’ tab in the browser and change the ‘Short Name’ field assigned to each telephone line. After confirming the changes with the ‘Submit All Changes’ button, friendly names should appear on our display.

    image 94
    image 95

    An additional advantage of this solution is that now when a given employee or department calls other internal numbers, the friendly name of the internal line will also appear on the call recipient’s end, in addition to the Extension number.

    Summary

    We have just registered our first VoIP phone in FreePBX. It is true that we still cannot make calls to landline or mobile numbers (we will deal with this in one of the next articles), but we can already make calls to internal company numbers if we have several VoIP phones.

    The Cisco SPA525G2 phone is the highest model in the SPA5xx series, very pleasant to use and easy to configure. However, not every Cisco phone is like that. For example, the great VoIP model Cisco 9971 with a large touch screen and the ability to add a camera is much more difficult to configure, because we do not change its settings from the level of the web browser, but with each change of a parameter we must create a configuration file and send it to the phone via the built-in TFTP server. But that’s a story for a completely different article.

    Therefore, if you do not have much experience in configuring VoIP phones and FreePBX, before buying, make sure that your new phone will be “FreePBX Friendly”.

    image 96
  • FreePBX Extensions Part 5

    FreePBX Extensions Part 5

    Extensions are, among other things, all the telephones connected to our FreePBX Asterisk server.

    Extension Driver Types

    You should know that there are several types of Extension drivers:

    • PJSIP – An updated version of the SIP driver. It works with most new VoIP telephones (e.g., Cisco SPA525G2).
    • Chan_SIP – The SIP driver that works with most older VoIP telephone models (e.g., Cisco CP-9971).
    • DAHDI – (Digium Asterisk Hardware Device Interface) Formerly known as Zaptel, this is the driver that supports telephones from Digium (the company is now called Sangoma) (e.g., the Digium D60 model).
    • IAX2 – (Inter-Asterisk eXchange) is a protocol developed for connecting different Asterisk servers with each other.
    • Virtual – Virtual extensions, for example, a voicemail box.

    Applications – Extensions

    To manage extensions, go to Applications > Extensions. To add a new Extension, click on Add Extension and select the driver or interface type from the list. We will now configure a new Extension using a Cisco SPA525G2 telephone as an example.

    • We can click Add Extension and select New SIP [chan_pjsip] Extension.
    • Alternatively, we can use the quick creation option by clicking Quick Create Extension.

    To start, let’s try the second option: creating an Extension quickly.

    image 79

    Quick Create Extension – Step 1

    • Type – Select SIP [chan_pjsip].
    • Extension Number – Choose any three or four-digit number. This will be the internal number for our telephone.
    • Display Name – Any name for our extension (e.g., Reception, Technical Department, John Smith, etc.). This name will appear on the displays of some telephones instead of the Extension number.
    • Outbound Caller ID – We will discuss this later. Leave this field blank for now.
    • Email Address – The email address assigned to this number.

    Click Next to proceed to Step 2.

    image 80

    Quick Create Extension – Step 2

    • Enable Find Me/Follow Me – We will cover the Follow Me function in a future article; for now, leave this option disabled.
    • Parking Lot – This feature allows you to ‘park’ calls so they can be picked up from another telephone. In the free version, you only have one option.
    • Create User Manager User – This option will create a new user for this Extension.
    • User Manager Groups – Select a group for our user. By default, only one group, ‘All Users’, is created. If you have many employees with different permissions, you can create several groups in FreePBX and set different permissions for them, for example, which groups can listen to recordings, which groups can create new Extensions, etc.
    • Enable Voicemail – Creates a voicemail box for this Extension.
    • Voicemail PIN – The PIN required to listen to recorded voicemail messages.

    Note: The default PIN is the same as the Extension number. This means that during the first call to the voicemail, the user will be able to configure it, for example, by recording their own greeting and changing the PIN. If you later reset the PIN to be the same as the Extension number, the voicemail box settings for this Extension will be deleted, and the user will be able to configure the mailbox from scratch.

    To finish creating the new Extension, press Finish and be sure to press Apply Config in the top right-hand corner to save the new settings.

    Editing Extensions

    Once we have created Extensions for all the internal telephones in the company, let’s look at the available settings. Go to Applications > Extensions and press the Edit button next to the Extension you want to edit.

    image 81

    A window with a series of useful tabs will appear. Let’s now discuss the options we haven’t mentioned before.

    image 82

    General Tab

    • Outbound CID – Our FreePBX is assigned a single external telephone number, let’s say a London area code, 020. Even though our employees are spread across the UK in Manchester, Bristol, and Glasgow, because they are connected to one FreePBX server, when they call clients, all clients will see the London telephone number assigned to our FreePBX. Statistics show that clients are much more likely to answer calls when someone is calling from a local area code. In the Outbound CID window, we can enter telephone numbers with our local city area codes.
    • Emergency CID – This is similar to Outbound CID, but much more serious as it concerns calls to emergency numbers. Imagine our employee working in the Glasgow branch needs urgent medical help and has to call an emergency number from this Extension. They dial 999, but the emergency service sees a London number instead of a Glasgow one, and the ambulance goes to the company’s address in London instead of to the person needing help in Glasgow. This is what the Emergency CID option is for, to ensure that in an emergency, the emergency services can correctly locate the caller.
    • Secret – This is the secret password that you will need to enter in the VoIP telephone’s settings so it can connect to our FreePBX Asterisk. We will discuss this option in more detail another time.
    • Language Code – Here we select the language for our voice recordings used in FreePBX Asterisk. If you don’t see your desired language, you can install it by going to Admin > Sound Languages.

    Note: You can record additional sound recordings yourself (e.g., “Please wait”, “All our consultants are busy”, etc.) and upload them to FreePBX, or you can purchase ready-made recordings. The language of the voice recordings can be set independently for each Extension. So, if we have people of different nationalities in the company, each of them can hear the announcements in their native language.

    • Select User Directory – User directory settings. Leave the default setting, PBX Internal Directory. The second option, Property Management, is used in hotels where specialised functions like guest check-in and check-out, wake-up calls, reservations, mini-bar, etc., are required. We will not cover this topic in this article as it is too extensive.
    • Link to a Default User – By default, the user is assigned to the given Extension. Select a user with the ‘Linked’ option.
    • Username – The username will be assigned automatically, or you can create your own by clicking on Use Custom Username.
    • Password For New User – The password assigned to the user.
    • Groups – The groups to which the user belongs.

    Voicemail Tab

    Let’s now discuss the most important options in the ‘Voicemail’ tab, where we can manage the voicemail settings for this specific Extension.

    image 83
    • Enabled – Enables or disables the voicemail box for this Extension.
    • Voicemail Password – The password needed to listen to saved voicemail messages.
    • Require From Same Extension – Disables the need to enter a password if you are checking voicemail for the Extension from which you are currently calling.
      • Explanation: From any telephone in our network, we can listen to voicemail messages not only for the number we are using but also for any other number, as long as we know the voicemail password.
        1. Dialling *97 lets you listen to saved messages for the telephone you are using. The ‘Require From Same Extension’ option can disable the need to enter a password.
        2. Dialling *98 followed by the Extension number lets you listen to messages from another Extension’s voicemail box, but you will always have to provide the password.
    • Email Address – The email address to which notifications about new voicemail messages will be sent.
    • Email Attachment – If you enable this option, the recorded voice message will be sent as an attachment with the email notification.
    • Play CID – Information about the message sender will be included with the message.
    • Play Envelope – Information about the time and date the message was left will be included with the message.
    • Delete Voicemail – Enable this option if you want FreePBX to delete the voicemail message from your Extension after it has been emailed to you.

    Note: Be aware that FreePBX does not check if the email with the message has reached you before deleting it from the voicemail box. If for some reason the email with the recorded message does not arrive, you will not be able to listen to the message, and you may not even know that a client recorded any message for you.

    • VmX Locater – This is quite an interesting feature. We can record a personalised greeting for our voicemail, and the caller will be able to choose one of three options. For example, they could connect to the main telephone in the company (e.g., at reception), or they could forward the call to another Extension or to a mobile number. Correctly configuring this function is time-consuming and will not be covered in this article.

    Find Me / Follow Me Tab

    image 84

    Imagine a situation where you are often away from your desk, in another part of the company, or out of the office. You can configure the Find Me/Follow Me function to sequentially ring a set of internal or mobile numbers to try and find you. You can configure this function according to dates and times using a Microsoft Outlook, CalDAV, or Apple iCal calendar. The configuration of this function is beyond the scope of this article, so I will try to write a separate article specifically for the Find Me/Follow Me feature.

    Advanced Tab

    The Advanced tab contains a variety of different functions. There are too many to discuss in one article, but there is one interesting option worth mentioning:

    • Max Contacts – By default, you can only connect one telephone to a single Extension. With this option, you can set how many different devices can have the same internal number (Extension number). You can set any number of internal telephones (including SoftPhone applications installed on smartphones) with the same number, which will ring simultaneously. But there’s a catch: to configure several telephones with the same Extension number, you must configure them using the End Point Manager application. In the free version, you can only configure telephones from Sangoma (formerly Digium). A list of supported models can be found in the Other tab. The End Point Manager Pro version, which currently costs $199, allows you to configure multiple devices from other manufacturers with the same number.

    Pin Sets Tab

    In the FreePBX Asterisk settings, you can block certain calls with a PIN code, for example, calls abroad or to expensive premium-rate numbers. If we have set up such a PIN lock, by enabling the Pinless Dialing option for an Extension, calls from that number will not require a PIN to be entered. We will discuss this issue in more detail another time.

    Bulk Editing Settings – Bulk Handler

    Bulk Handler doesn’t strictly relate to Extensions, but it’s worth mentioning this feature because it makes life much easier. If you have a dozen, several dozen, several hundred, or more Extensions and you need to change one setting in each of them, changing it in each Extension separately can take a very long time. You can do it much faster using Bulk Handler. With this function, you can export all Extensions to a CSV file, which you can conveniently open and edit in an application like Microsoft Excel. Changing one function for all Extensions will take a few seconds instead of several hours. After editing the file, you can import it back into FreePBX with a single click and apply the changes. Isn’t that simpler?

    Using Bulk Handler, you can edit not only Extensions but also many other options. To launch this application, click Admin > Bulk Handler.

    image 85

    Summary

    In this article, you have learned how to create and edit Extensions, which is an essential step to later connect them with VoIP telephones. You also now know how voicemail boxes work.

  • FreePBX Backup: Creation and Restoration, Part 4

    FreePBX Backup: Creation and Restoration, Part 4

    The importance of a backup is only truly understood by those who have had to recover files from damaged data storage. Server administrators fall into two categories: those who perform backups, and those who will start performing backups. In this article, we will learn how to create backups locally, on an FTP server, on Dropbox and Amazon S3, and how to send them to an email address and via SSH.

    Settings -> Filestore

    First, let’s navigate to Settings -> Filestore. In this window, there are several tabs, depending on where we want to store our backup files.

    image 73

    Settings -> Filestore -> Local

    We will start by creating a backup locally on the hard drive where your FreePBX system is installed. A local copy is useful when you want to test various FreePBX settings and are concerned that changing them might cause your telephone exchange to stop working correctly. However, remember that in addition to local copies, you should also create backups that are sent remotely to an FTP server, Dropbox, etc. A local backup will be useless if the hard drive on which FreePBX is installed fails.

    image 74

    Go to the Local tab and click the Add local path button. A new window will appear where you need to enter:

    • Path name: A name for your Filestore settings. It can be anything, for example, Local Copy.
    • Description: Any description, for example, Local copy on the hard drive.
    • Path: The path on the hard drive where the backups will be stored. We can use variables suggested by FreePBX. For example, the variable __ASTSPOOLDIR__ (remember the double underscores before and after) represents the /var/spool/asterisk/ folder. We can add backup at the end, so we know the files in this folder are backups. Therefore, entering __ASTSPOOLDIR__/backup is exactly the same as /var/spool/asterisk/backup.

    Finally, confirm the changes with the Submit button.

    image 75

    Settings -> Filestore -> FTP

    If you have access to an FTP server, you should definitely use the option to send backups to it. This significantly increases the security of your FreePBX telephone exchange. If you only make local backups, in the event of a hard drive failure, all local backups will also be lost. If you don’t know how to set up an FTP server at home, you can purchase affordable server space in the cloud, for instance at Zetohosting, where you will also get FTP server access as part of the hosting package.

    First, in the Filestore window under the FTP tab, we will enter the settings that will allow us to log in to the server. Click the Add FTP Instance button and fill in the required fields in the new window:

    image 76
    • Enabled: This button enables or disables the data store.
    • Server Name: Any name for your data store.
    • Description: Any description.
    • Hostname: The IP address of your FTP server, or the domain name.
    • Port: The port on which your FTP server operates.
    • Use TLS: If your FTP server requires SSL/TLS encryption, enable this option.
    • Username: The username for the FTP server.
    • Password: The password.
    • Filesystem type: If you know the operating system of your FTP server, select the appropriate option. If you are unsure, select Auto.
    • Path: The access path where backups will be saved. Note: provide the full path (starting with /), otherwise your Filestore will not work.
    • Transfer Mode: Choose Active or Passive mode for your FTP server.
    • Timeout: The inactivity time in seconds after which the connection to the FTP server will be terminated.

    You should receive all the necessary data to configure the FTP connection from your FTP server provider.

    Admin -> Backup & Restore

    Once we have created a location to save the files, we can go to the Admin -> Backup & Restore window. In the Backup tab, click Add Backup to configure a new backup. For my needs with FreePBX, I usually set up monthly and weekly backups, keeping the last three weekly copies and one from each of the last three months. Of course, there is nothing stopping you from creating daily or quarterly backups. It all depends on how much hard drive space you can allocate for backups. Let’s start by setting up monthly backups.

    Basic Information

    • Backup name: Any name, for example, Monthly Copies. (It’s worth avoiding special characters in the name. I’ll explain why shortly.)
    • Backup Description: Any description, for example, Keep copies from the last 3 months.
    • Backup Items: Here you choose which FreePBX modules should be included in the backup. A good starting point is to back up all modules, so don’t change anything here.
    • Custom Files: If you have manually copied any files to your FreePBX (for example, via FTP) and they are stored outside the FreePBX/Asterisk folders, and you want them to be included in the backup, you must tell FreePBX where they are located. If you haven’t copied any additional files, you don’t need to worry about this.

    Notifications

    • Notification Email: Your email address to which notifications about completed backups or errors during backup creation will be sent.
    • Inline Logs: Includes logs from the backup process in the email message.
    • Email Type: Sends an email notification only if the backup was successful (Success), ended in an error (Failure), or in both cases (Both).

    Storage

    • Storage location: Here we select the location—which we created earlier in the Filestore window—where our backups will be stored. In our case, it will be Local Copy.
    • Append Backup Name as a directory to the Storage path: If you enable this option, an additional directory with the name of our backup will be created in the directory where our backups are saved (in our case /var/spool/asterisk/backup/). In this instance, it would be Monthly Copies. This helps to keep the backups organised and makes it easier to find the one you need in case of a failure. This is why I mentioned earlier to avoid diacritical characters in the name, to prevent character encoding issues.

    Schedule and Maintenance

    Here we set whether we want backups to be performed automatically at scheduled intervals.

    • Enabled: Enables the backup schedule.
    • Scheduling: Sets the frequency of the backups. We can set it to run hourly, daily, weekly, monthly, or yearly.

    Maintenance

    In this section, we set how many copies we want to keep on the disk and when unnecessary copies should be deleted.

    • Delete After Runs: Here we set the number of recent copies we want to keep. In our case, we want to keep the last 3 copies. All copies over three will be deleted. If we set it to 0, copies will not be deleted at all.
    • Delete After Days: We can also set a time after which copies will be deleted, regardless of how many copies we have. I suggest setting this to Unlimited.

    Note: If we set the first option to 0 and the second to Unlimited, the copies will never be deleted. As backups can be large, you might find that you quickly fill up your disk space.

    Hooks

    Here you can set what the computer should do before or after performing or restoring a backup. For example, after a backup, you can compress the files or transfer them to a remote server. You can also copy the backups to a connected USB stick—for this, you can mount it in this window before the backup is made. If you haven’t written scripts in Linux before, you don’t need to worry about this.

    Warm Spare

    If our FreePBX telephone exchange serves a large company and you cannot afford any downtime, you can install a second FreePBX server that will be synchronised with the main exchange. In the event of a failure, you can quickly switch your telephony to the backup FreePBX server. If you do not have two FreePBX servers, you can skip these options.

    Save

    Finally, we save our settings with the Save button.

    Manual Backup Execution

    After saving the settings, you can check if the backup is performed correctly by running it manually. To do this, press the arrow button as shown in the image below.

    image 77

    If all settings are correct, you should see the message “Finished created backup file” in the program logs.

    To be extra sure that the backup was created, you can log in to the FreePBX console via SSH and check the backup save path, which in our case will be /var/spool/asterisk/backup/.

    Navigate to the backup directory with the command cd /var/spool/asterisk/backup/ and list the contents of the directory with ls. As you can see in the attached illustration, an additional subfolder Monthly-Copies has been created. Open this folder with the command cd Monthly-Copies and list its contents with ls. As you can see, the backup file has been created correctly inside this directory.

    [root@creativeart ~]# cd /var/spool/asterisk/backup/
    [root@creativeart backup]# ls
    Monthly-Copies
    [root@creativeart backup]# cd Monthly-Copies/
    [root@creativeart Monthly-Copies]# ls
    20230218-085312-1676710392-16.0.33-1234817093.tar.gz
    [root@creativeart Monthly-Copies]#
    

    Admin -> Backup & Restore -> Restore

    After creating our first backup, we should be able to see it in the Restore tab. Next to each backup, there is an Actions window where we can restore the backup, download it to our computer’s hard drive, or delete it. After downloading the copy to your computer, you can re-upload it to the server in the Upload your restore files window by clicking the Click to upload a backup file button.

    To use the Restore from the cloud option, we must first configure Filestore to have access to cloud file storage services.

    image 78

    Summary

    You now know how to automatically create and restore backups both on a local disk and on a remote FTP server. Now, in the event of any failure, you can easily restore your FreePBX telephone exchange to working order.