---
title: "How to Install WordPress on Debian 13: Commands and Steps"
description: "How to install WordPress on Debian 13 with nginx, PHP 8.4 and MariaDB, with every command and the steps that differ from Ubuntu: sudo, PHP, firewall."
url: "https://carthacker.com/hosting/install-wordpress-debian-13/"
author: "Adrian Wadowski"
published: "2026-10-31"
section: "Hosting & Security"
image: "https://carthacker.com/wp-content/uploads/install-wordpress-on-debian-13.jpg"
publisher: "CartHacker (carthacker.com)"
language: "en"
---

# How to Install WordPress on Debian 13: Commands and Steps

By [Adrian Wadowski](https://carthacker.com/author/adrian/), building online stores since 1998. Published October 31, 2026. 20 min read.

When I ran the commands of an Ubuntu install on a new Debian 13 server, the install failed twice because of the PHP version: Debian 13 comes with PHP 8.4, and Ubuntu 26.04 with PHP 8.5. First, `apt install php8.5-fpm` ended with "Unable to locate package". Then the socket path I'd copied from the Ubuntu server block gave every page a 502 Bad Gateway error, although `nginx -t` said the configuration was fine. A third failure had nothing to do with PHP: after I'd switched to root, nginx -t gave me "command not found".

If you want to **install WordPress on Debian 13** (codename trixie) with nginx, PHP-FPM and MariaDB, most of the work is the same as on Ubuntu, and [my Ubuntu guide](https://carthacker.com/setup/install-wordpress-ubuntu-26-04/) has those steps in full. What's different is a short list: root access without sudo, the PHP packages and the sury.org repository, the socket path in nginx, the firewall, automatic security updates and Certbot.

I tested every command in a new Debian 13.7 container and finished with WordPress and WooCommerce running. Here's the short version: write 8.4 wherever an Ubuntu guide writes 8.5, become root with `su -` (with the dash) when there's no sudo, set up the firewall yourself, and check whether automatic security updates are on, because **on Debian that depends on how the server was installed**.

## How installing WordPress on Debian 13 differs from Ubuntu 26.04

I compared the two systems on the same day in two ways: I ran `apt-cache policy` on a new container of each, and I read the package lists of the official cloud images both projects publish. A cloud image is the ready-made system a new cloud server is copied from, and Debian's is small: it has fewer than half the packages of Ubuntu's.

| On a new server | Debian 13.7 | Ubuntu 26.04.1 |
| --- | --- | --- |
| PHP from the system's own packages | 8.4.27, in main | 8.5.4, php8.5-fpm in universe |
| PHP-FPM service and socket | php8.4-fpm, /run/php/php8.4-fpm.sock | php8.5-fpm, /run/php/php8.5-fpm.sock |
| nginx | 1.26.3 | 1.28.3 |
| MariaDB | 11.8.6 | 11.8.6 |
| Certbot from apt | 4.0.0 | 4.0.0 |
| sudo | in the cloud image; from the installer only when root has no password | always |
| add-apt-repository | not in Debian 13 | installed |
| snap | not installed | installed |
| Firewall | no ufw, no active rules | ufw installed, off until enabled |
| Automatic security updates | on in the cloud image, off after the installer | on |
| /usr/sbin in a normal user's PATH | no | yes |
| Packages in the cloud image | 322 | 678 |
| nginx layout, web user, web root | sites-available, www-data, /var/www/html | the same |

I took the versions from apt on the day I tested. The sudo, snap, firewall and update rows come from the official cloud images, the Debian installer and Ubuntu's server documentation.

Two rows are the same on both systems, so you have less to change: MariaDB is the same release on both, and the nginx layout row is the same too (the sites folders, the www-data user and the web root). So the database and WordPress steps of the Ubuntu guide work as written, except the `sudo -u www-data` in front of each WP-CLI command when your server has no sudo (the section on root access shows what to type instead). Ubuntu commands fail where the PHP version differs, and some fail even earlier, because sudo is missing.

## Root access when Debian has no sudo

Ubuntu guides start every command with sudo, because Ubuntu always has it. On Debian, whether sudo is there depends on how the server was installed. The official Debian cloud image includes sudo. The Debian installer adds sudo only when you leave the root password empty, and then the installer gives the first user sudo rights (the installation guide says so in its part on the root password).

If you set a root password during the install, the first Ubuntu command fails at once:

```bash
root@server:~# sudo apt update
-bash: sudo: command not found
```

Without sudo you'll log in as your own user and switch to root with su, and then commands such as nginx -t, typed the way you'd type them on Ubuntu, fail. **Plain su keeps your own PATH**, and a normal user's PATH on Debian doesn't include /usr/sbin, the folder that holds nginx, PHP-FPM and most admin tools. Ubuntu adds /usr/sbin and the other admin folders to every user's PATH in /etc/environment. On my Debian test server that file was empty.

Here's what happened when I logged in as a user named shop:

```bash
shop@server:~$ su
Password:
root@server:/home/shop# nginx -t
bash: nginx: command not found
root@server:/home/shop# exit
exit
shop@server:~$ su -
Password:
root@server:~# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
```

The dash starts a login shell with root's own PATH. Plain su has kept your own PATH since Debian 10, when su moved to the util-linux package, and the Debian wiki's page on that release warns that after a plain su "many system administration commands will fail". Would you rather type sudo, the way you do on Ubuntu? Then install sudo once as root and add your user to the sudo group (the new group works from your next login):

```bash
root@server:~# apt install sudo
root@server:~# usermod -aG sudo shop
```

WP-CLI needs a different command too. Ubuntu guides run it as the web server user with `sudo -u www-data wp ...`, and su can't do that, because www-data doesn't have a login shell. When you're root, `runuser` does what `sudo -u` does, and since it comes with util-linux, every Debian server has it:

```bash
root@server:/var/www/example.com# su www-data -c "wp core version"
This account is currently not available.
root@server:/var/www/example.com# runuser -u www-data -- wp core version
7.1.3
```

## Install PHP 8.4 from Debian's own packages

Debian 13 has one PHP version in its archive (Debian's own package repository): 8.4. The package names contain the version (php8.4-fpm and so on), and generic names such as php-fpm install those same packages. An apt install line with php8.5 package names, copied from a current Ubuntu guide, stops before it installs anything, and the php8.3 names from older guides stop the same way. The ondrej/php PPA (a personal package archive on Ubuntu's Launchpad) that many guides add won't help either, because Debian doesn't have add-apt-repository:

```bash
root@server:~# apt install -y php8.5-fpm
...
Error: Unable to locate package php8.5-fpm
Error: Couldn't find any package by glob 'php8.5-fpm'
root@server:~# add-apt-repository ppa:ondrej/php
-bash: add-apt-repository: command not found
```

On Debian I type the generic names, because they always install the PHP version the release supports. This is the whole stack I installed, PHP extensions included:

```bash
root@server:~# apt update
root@server:~# apt install nginx mariadb-server php-fpm php-mysql php-curl php-gd php-intl \
    php-mbstring php-xml php-zip php-imagick php-bcmath php-redis php-soap redis-server curl unzip
```

On a new Debian 13 server that line installs 253 packages, and it took between one and two minutes in my two runs. On a real server nginx, MariaDB, Redis and PHP-FPM start during that install, and they're already enabled for the next boot. Redis is in Debian's main archive too, so the reason the Ubuntu guide gives for switching to Valkey (redis-server is in universe there) doesn't apply here. Debian 13 has valkey-server as well, if you'd rather run it.

PHP's settings are then in /etc/php/8.4/fpm/ (php.ini, and the pool file pool.d/www.conf), and nginx reaches PHP through /run/php/php8.4-fpm.sock. **Wherever an Ubuntu guide says 8.5, you write 8.4**: in commands and in paths, including the path of the php.ini you edit for upload limits (/etc/php/8.4/fpm/php.ini) ([the 413 and upload_max_filesize guide](https://carthacker.com/hosting/413-request-entity-too-large/) has those settings).

### PHP 8.4 is the newest version WooCommerce lists as tested

Does a store lose anything with the older PHP? WooCommerce's own server requirements say it doesn't. They recommend PHP 8.3 or greater and name 8.4 as the newest version they've tested, so **Debian's PHP is the newest one WooCommerce lists as tested**, and Ubuntu's 8.5 is one version newer than any version on that list. WordPress asks for 8.3 or greater too.

The support period isn't a problem either. php.net keeps fixing security bugs in PHP 8.4 until the end of 2028, and that's a few months after Debian's regular support for this release has already ended.

For me, the bigger difference is who delivers the security fixes. On Debian, php8.4-fpm is in the main archive and **the Debian security team patches it**: the build I installed came from trixie-security. On Ubuntu, php8.5-fpm (the package that actually runs WordPress behind nginx) is in universe. Canonical's standard five years of security updates cover main, and universe is outside main. That's why [the Ubuntu guide](https://carthacker.com/setup/install-wordpress-ubuntu-26-04/) recommends Ubuntu Pro for a store on 26.04. On Debian you don't need that step.

Don't install Debian's `wordpress` package. Debian's build is WordPress 6.8.10, while wordpress.org is at 7.1.3, and on a new container apt wanted 149 packages for it, Apache and its PHP module among them. You don't need any of that: download WordPress with WP-CLI, the way the Ubuntu guide does.

## How to install PHP 8.5 from sury.org on Debian 13

Do you need another PHP at all? Only if a plugin needs PHP 8.5, or an old one still needs 8.3. Then the repository for Debian is packages.sury.org, run by Ondrej Sury, a Debian developer who has packaged PHP for Debian for many years. It's the Debian counterpart of the ondrej/php PPA that Ubuntu users add: the same developer and the same PHP versions, built for Debian (a PPA is built for Ubuntu releases only).

Debian's extrepo tool already has the repository and its signing key in its list, so three commands add it:

```bash
root@server:~# apt install extrepo
root@server:~# extrepo enable sury
root@server:~# apt update
```

The README on packages.sury.org shows the same setup done by hand, with a keyring package and a php.list file. Use extrepo or the README setup, never both, because when I had both, apt wouldn't read its sources at all ("Conflicting values set for option Signed-By"). For Debian 13 the repository had every PHP from 8.1 to 8.5.

The next apt upgrade shows the downside. With Debian's PHP already installed, adding sury.org made **29 packages upgradable**: 28 PHP packages with the same PHP version, rebuilt by sury.org with a higher package number, and libgd3, the image library behind PHP's GD extension. Run that upgrade and your PHP comes from one developer's repository instead of Debian's, signed with a key that expires in February 2028. His own page says he does this work mostly in his free time.

Automatic updates skip sury.org packages: unattended-upgrades installs only packages from the origins (apt's name for who published a package) on its allowed list, Debian and Debian-Security. In another test container with fewer PHP extensions, 24 sury.org updates were waiting, and a dry run of unattended-upgrades (it lists what it would install and installs nothing) answered "No packages found that can be upgraded unattended". **Your automatic updates skip every sury.org package** until you add sury.org to that allowed list, which takes one line in a new file:

```bash
root@server:~# cat /etc/apt/apt.conf.d/51unattended-upgrades-sury
Unattended-Upgrade::Origins-Pattern:: "origin=deb.sury.org,codename=${distro_codename}";
```

With that line in place, the dry run listed php8.4-fpm and the other sury.org packages.

Another problem appeared when I installed the newer PHP next to Debian's. `php -v` switched to 8.5 by itself, because Debian's alternatives system points the php command at the highest version installed, while the store kept running 8.4 through its socket. WP-CLI and cron jobs used PHP 8.5, while the store's pages still used PHP 8.4. `update-alternatives --set php /usr/bin/php8.4` sets the php command back to the site's version.

For a WooCommerce store I'd stay on Debian's 8.4 until a plugin I need requires a different PHP version. It's the version WooCommerce tests, and its fixes arrive in the same apt upgrade as the rest of the system.

## nginx 1.26 uses the same folders as Ubuntu

Debian's nginx is one stable release older than Ubuntu's (1.26 against 1.28), and Debian keeps it for as long as the release is supported, adding the security fixes to it. For a WordPress site that didn't make any difference in my test. Even the http2 on directive, which nginx added in version 1.25.1, loads fine.

Ubuntu took these folders from Debian: sites-available, sites-enabled, conf.d and snippets/fastcgi-php.conf. So the server block goes where the Ubuntu guide puts it, and only the PHP lines change:

```nginx
location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.4-fpm.sock;
}
```

Then you link the site, test it and reload nginx, the same as on Ubuntu. [How to set up nginx for WooCommerce](https://carthacker.com/hosting/nginx-wordpress-config/) explains every line of a complete nginx config file.

```bash
root@server:~# ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
root@server:~# rm /etc/nginx/sites-enabled/default
root@server:~# nginx -t && systemctl reload nginx
```

### Why nginx -t passes but the site shows a 502 error

That fastcgi_pass line is where my 502 came from, because I'd pasted the Ubuntu socket path into the Debian server block. Why did the test pass? **nginx -t only checks that the configuration is valid**. It doesn't look for the socket, so nginx reloaded without an error and the first page view failed:

```bash
root@server:~# grep fastcgi_pass /etc/nginx/sites-available/example.com
        fastcgi_pass unix:/run/php/php8.5-fpm.sock;
root@server:~# nginx -t && systemctl reload nginx
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
root@server:~# curl -s -o /dev/null -w '%{http_code}\n' http://localhost/
502
root@server:~# tail -n 1 /var/log/nginx/error.log
2026/10/28 00:18:57 [crit] 19153#19153: *9 connect() to unix:/run/php/php8.5-fpm.sock failed (2: No such file or directory) while connecting to upstream, client: ::1, server: example.com, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/run/php/php8.5-fpm.sock:", host: "localhost"
root@server:~# ls /run/php/
php-fpm.sock
php8.4-fpm.pid
php8.4-fpm.sock
```

The ls output shows the fix. Next to php8.4-fpm.sock there's php-fpm.sock, a link without a version number. The PHP-FPM service creates it when it starts and points it at its own socket. With **fastcgi_pass unix:/run/php/php-fpm.sock**, my Debian test server returned 200. Ubuntu builds its PHP packages from the same Debian packaging, so the same link should be there too, but I only tested it on Debian: run `ls /run/php/` on your Ubuntu server before you rely on it.

That's the name I'd use while the server has one PHP version. With a second PHP from sury.org the link moved: it pointed at Debian's version, then at the newer one after I set update-alternatives back to automatic mode, then at Debian's again after a reboot. A server with two versions needs the path with the version in it. If the socket path is correct and you still get a 502 error, [my 502 Bad Gateway article](https://carthacker.com/hosting/502-bad-gateway-nginx/) explains the other causes, each with its error.log line.

The default site has one more problem, on Debian and Ubuntu alike: its commented-out PHP example still points at php7.4-fpm.sock, a version neither system has included for years.

### nginx from nginx.org uses different folders

If you want the newest nginx on Debian, nginx.org runs its own Debian repository, and its package is built differently. I installed nginx.org's current stable release, 1.30.6, in a new Debian container and put the same server block into conf.d. That package doesn't have a sites-available or a snippets folder, so the line `include snippets/fastcgi-php.conf` from Debian's layout failed. After I'd fixed that, the next error was about permissions: nginx.org's package runs nginx as the user nginx, and that user isn't allowed to open a PHP socket that belongs to www-data:

```bash
nginx: [emerg] open() "/etc/nginx/snippets/fastcgi-php.conf" failed (2: No such file or directory) in /etc/nginx/conf.d/example.com.conf:18
...
[crit] 10000#10000: *1 connect() to unix:/run/php/php8.4-fpm.sock failed (13: Permission denied) while connecting to upstream
```

In that output I left out the lines between the two errors and shortened the second error line. Then I got nginx.org's package working with PHP: I replaced the snippet with `include fastcgi_params;` and a `fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;` line, added the nginx user to the www-data group with `usermod -aG www-data nginx` and restarted nginx.

For a store I'd keep Debian's own nginx. Commands from Ubuntu guides work with it, and its fixes come with apt upgrade like everything else.

## MariaDB 11.8: the same version on Debian and Ubuntu

I didn't have to change anything for the database. Both systems include MariaDB 11.8.6, and WordPress asks for 10.11 or greater. On Debian, root logs in through the Unix socket without a password (the root account is defined as `IDENTIFIED VIA mysql_native_password USING 'invalid' OR unix_socket`), new databases default to utf8mb4, and the usual CREATE DATABASE and CREATE USER commands ran unchanged.

One old name is gone on both systems: mysql_secure_installation. MariaDB includes that script only as `mariadb-secure-installation` now, while the mysql and mysqldump commands are still there. If a command from an older guide isn't found, try it with the mariadb- prefix.

## Set up a firewall on Debian 13

Ubuntu includes ufw and leaves it off. Debian doesn't include ufw or any rules: its cloud image has only the iptables package, and even where the nftables package is installed, its service is disabled and /etc/nftables.conf holds chains with no rules in them. So every port that a program listens on is open.

**Allow SSH before you enable any firewall**, or the firewall also blocks your own SSH connection.

Which tool should you pick? The quickest is ufw, because Debian's ufw has the same application profiles as Ubuntu's (OpenSSH and Nginx Full both exist), so the Ubuntu commands work as soon as the package is installed. Over SSH, ufw enable asks you to confirm with y first:

```bash
root@server:~# apt install ufw
root@server:~# ufw allow OpenSSH
root@server:~# ufw allow 'Nginx Full'
root@server:~# ufw enable
Firewall is active and enabled on system startup
```

Or don't install ufw, and write the ruleset nftables loads at boot. On a server made from the cloud image, install nftables first with `apt install nftables`. This /etc/nftables.conf allows SSH, HTTP and HTTPS, answers ping and drops everything else:

```bash
#!/usr/sbin/nft -f
flush ruleset

table inet filter {
    chain input {
        type filter hook input priority filter; policy drop;

        iif "lo" accept
        ct state established,related accept
        ct state invalid drop

        meta l4proto { icmp, ipv6-icmp } accept

        tcp dport 22 accept
        tcp dport { 80, 443 } accept
    }
    chain forward {
        type filter hook forward priority filter; policy drop;
    }
    chain output {
        type filter hook output priority filter; policy accept;
    }
}
```

```bash
root@server:~# nft -c -f /etc/nftables.conf
root@server:~# systemctl enable --now nftables
root@server:~# systemctl is-enabled nftables
enabled
```

`nft -c` only checks the file, and no output means no errors. I'd still use ufw on a single web server, because whoever manages the server after you will know the ufw commands.

## Automatic security updates depend on how the server was installed

Ubuntu Server installs unattended-upgrades and turns on automatic security updates right after installation, as its documentation says. **Debian's installer has done the opposite since 2018**: at the request of the Debian security team, its update setting defaults to "No automatic updates", and a default install doesn't even show the question.

Debian's cloud team made the other choice for its images, which include unattended-upgrades, and on Debian 13 that package switches itself on when it's installed. So a server made from the cloud image and one made with the installer behave in opposite ways.

Which one did your provider give you? A line ending in "1" means automatic updates are on, and no line at all means the package isn't installed:

```bash
root@server:~# apt-config dump APT::Periodic::Unattended-Upgrade
APT::Periodic::Unattended-Upgrade "1";
```

If the command prints nothing, the package isn't there, so run `apt install unattended-upgrades` and then run the check again. On my test server that one command turned automatic updates on: the daily timer was scheduled, and the allowed list held only Debian's own origins, including the security archive. On a server made with the installer the check can print "0", because the installer saves the answer "No automatic updates" for this package before the package is ever installed. If you see "0", or want to change the setting later, run `dpkg-reconfigure unattended-upgrades` and answer Yes.

## Install Certbot with apt (Debian has no snap)

Certbot's own instructions install it with snap, and Debian doesn't have snapd unless you add it. I'd use Debian's package instead: **Certbot 4.0.0 from the main archive**, the same version Ubuntu has in apt, while the snap has 5.8.0, released at the start of September.

```bash
root@server:~# apt install certbot python3-certbot-nginx
root@server:~# certbot --version
certbot 4.0.0
```

The package renews certificates with a systemd timer set for midnight and noon, and each run waits a random time of up to 12 hours. `systemctl list-timers certbot.timer` shows when it'll run next. [How to set up Certbot on nginx](https://carthacker.com/hosting/certbot-nginx/) shows how to get the first certificate, including when the store is behind Cloudflare.

When the store works over HTTPS, test its speed from another computer. My test server sent the WooCommerce home page in about 110 milliseconds without a page cache, but that request came from the server itself, and a shopper's request has to travel over the internet first.

> **Store Speed Test:** Check how fast your new Debian server responds to shoppers. Paste a product page address and see its three Core Web Vitals scores and the total delay. A free account names the 5 apps that cost the most time, with the fix for your platform. [Test my store](https://carthacker.com/store-speed-test/)

## How I tested Debian 13, and what a container test can't check

I tested in a container from the official debian:13 Docker image (not the cloud image from the table), Debian 13.7, on October 28, 2026, and ran every command as root, except the su test, where I logged in as a user named shop. A plain container doesn't run systemd, so I ran the install twice: once with the old service command, and once in a second container that boots systemd, where the systemctl, ufw and nftables commands really ran.

The Docker image also stops packages from starting their services during an install (a small policy-rc.d file does that), so I removed that file to make the second container behave like a server. The Ubuntu 26.04.1 container was only for apt-cache policy and for reading what's inside its packages; I installed nothing on it.

A container can't run the Debian installer either, so what I say about sudo and update defaults on an installed server comes from Debian's installation guide and the installer's source code. These are the versions I had at the end:

- Debian 13.7, PHP 8.4.27, nginx 1.26.3 and MariaDB 11.8.6 from Debian's archive.
- WordPress 7.1.3, WooCommerce 11.2.1 and WP-CLI 2.12.0.
- For the comparisons: Ubuntu 26.04.1, PHP 8.5.12 from sury.org and nginx 1.30.6 from nginx.org.

On a real server, check the services after the first reboot, before the store takes orders:

```bash
root@server:~# systemctl is-active nginx php8.4-fpm mariadb nftables
active
active
active
active
```

I restarted my systemd container to get that output. If you chose ufw, write ufw in place of nftables in that command. Four lines that say active mean the web server, PHP, the database and the firewall all started again after a reboot with nobody logged in to start them, and that's the last thing I check before a store opens on a new server.

## Sources

- Debian: [Debian 13 trixie release information](https://www.debian.org/releases/trixie/) (13.0 on August 9, 2025, 13.7 on September 12, 2026, support dates), [release notes, what's new](https://www.debian.org/releases/trixie/release-notes/whats-new.en.html) (PHP 8.4, nginx 1.26, MariaDB 11.8), [installation guide, section 6.3.2.1](https://www.debian.org/releases/trixie/amd64/ch06s03.en.html) (root password and sudo), [wiki, new in buster](https://wiki.debian.org/NewInBuster) (su and PATH), [wiki, nftables](https://wiki.debian.org/nftables) and [wiki, unattended upgrades](https://wiki.debian.org/UnattendedUpgrades).
- Debian packages: [php8.4-fpm](https://packages.debian.org/trixie/php8.4-fpm), [nginx](https://packages.debian.org/trixie/nginx), [mariadb-server](https://packages.debian.org/trixie/mariadb-server) and [certbot](https://packages.debian.org/trixie/certbot) in trixie; the installer's update question in [pkgsel](https://salsa.debian.org/installer-team/pkgsel) (Debian bug [875858](https://bugs.debian.org/875858)); the [Debian 13 cloud images](https://cloud.debian.org/images/cloud/trixie/latest/), their [build configuration](https://salsa.debian.org/cloud-team/debian-cloud-images) and the cloud team's [decision on unattended-upgrades](https://lists.debian.org/debian-cloud/2018/07/msg00007.html).
- Ubuntu: [release cycle](https://ubuntu.com/about/release-cycle) (main and universe under standard support and Ubuntu Pro), [php8.5-fpm in 26.04 on Launchpad](https://launchpad.net/ubuntu/resolute/amd64/php8.5-fpm), [automatic updates](https://ubuntu.com/server/docs/how-to/software/automatic-updates/), [firewalls](https://ubuntu.com/server/docs/how-to/security/firewalls/) and the [26.04 cloud image](https://cloud-images.ubuntu.com/releases/resolute/release/).
- PHP: [supported versions](https://www.php.net/supported-versions.php). Ondrej Sury: [deb.sury.org](https://deb.sury.org/) and [the repository README](https://packages.sury.org/php/README.txt).
- nginx: [ngx_http_v2_module](https://nginx.org/en/docs/http/ngx_http_v2_module.html) (the http2 directive since 1.25.1) and [nginx.org packages for Linux](https://nginx.org/en/linux_packages.html).
- WordPress: [requirements](https://wordpress.org/about/requirements/). WooCommerce: [server requirements](https://woocommerce.com/document/server-requirements/). Certbot: [instructions for nginx](https://certbot.eff.org/instructions?ws=nginx&os=snap).

---

## Cite this guide

Wadowski, A. (2026, October 31). *How to Install WordPress on Debian 13: Commands and Steps*. CartHacker. https://carthacker.com/hosting/install-wordpress-debian-13/

## Free tools from CartHacker

- [Store Speed Test](https://carthacker.com/store-speed-test/): Find the apps that slow your product page down.
- [Core Web Vitals Monitoring](https://carthacker.com/plugins/core-web-vitals-monitoring/): Monitor your store's Core Web Vitals every day, for free.
- [Trust Seals & Badges](https://carthacker.com/trust-badges/): Show shoppers it's safe to buy, right under Add to cart.
- [QR Code Generator](https://carthacker.com/qr-code-generator/): Make a QR code you can still change after printing.
- [PDF Tools](https://carthacker.com/pdf-tools/): Free online PDF tools that run in your browser: merge, split, convert, sign and protect PDFs. 39 tools, no upload, no watermark, no sign-up.
- [CartHacker Premium](https://carthacker.com/premium/): one subscription, monthly or yearly, that upgrades every tool at once:
  - 50 trust badges in 30 languages, switched automatically
  - 180 days of Core Web Vitals, per page
  - All 39 PDF tools, unlimited and never uploaded
  - 200 QR codes, tracked and editable after printing
  - No ads on any guide or tool
  - Every new guide 2 weeks before the public
  - Product Feed Manager and new tools included
- Every quota and price, tool by tool: https://carthacker.com/llms.txt
