Debian

Install Zammad Helpdesk on Debian 13 (Trixie)

Zammad publishes its own repository for Debian 13, so a clean Trixie server needs no workarounds. Zammad, PostgreSQL 17, Redis and nginx all arrive in one apt transaction, and only Elasticsearch needs a repository of its own. Older Zammad guides for Debian, this site’s earlier version included, set it up on MariaDB and Apache, and that path is closed now because Zammad 7 runs on PostgreSQL only.

Original content from computingforgeeks.com - post 161429

This guide shows you how to install Zammad on Debian 13 with Elasticsearch 9, put nginx in front with HTTPS, create the first admin, back it up and watch its health. It ends with the memory tuning that decides whether Zammad fits on a small VM. Every command below was run on Debian 13.7 in October 2026 with Zammad 7.2.2 and Elasticsearch 9.5.5, and every number was measured on that server.

Size the server

Zammad itself is modest, but Elasticsearch is not, and it’s the part that decides your RAM. After setup, with a 2 GB Java heap, Elasticsearch alone held 2.6 GB resident, against roughly 250 MB each for the three Zammad processes and 298 MB for PostgreSQL. The whole box used 3.9 GB of its 8 GB.

Zammad on Debian 13 architecture with measured memory per service: nginx, zammad-web, websocket, worker, PostgreSQL 17, Redis and Elasticsearch 9

Only nginx listens on the network. PostgreSQL, Redis, Elasticsearch and the three Zammad processes all bind to localhost, so the firewall section only has to open SSH, HTTP and HTTPS, and nothing else is reachable even if a rule goes wrong later. For a team of up to a few dozen agents, start from this:

  • Debian 13 (Trixie), 64-bit, with sudo access
  • 4 vCPU and 8 GB RAM (6 GB works with a 1 GB Elasticsearch heap)
  • 20 GB disk, plus room for attachments and backups
  • A DNS A record such as helpdesk.example.com pointing at the server
  • Ports 22, 80 and 443 reachable from your network

Our test VM had 4 vCPU, 8 GB and a 40 GB disk, and the Zammad and Elasticsearch packages took about 2.8 GB of that disk. Grow the disk with your attachment volume, since Zammad stores files in PostgreSQL by default and the database is what the backup script dumps.

Set your domain once

The domain appears in the nginx config, the certificate request and a Zammad setting, and a typo in any one of them gives you a half-working helpdesk. Export it and the admin email as variables so every later command uses the same values. Replace both with your own before you paste anything else.

export ZAMMAD_DOMAIN="helpdesk.example.com"
export ADMIN_EMAIL="[email protected]"

Zammad needs a UTF-8 locale, because PostgreSQL creates its database with the server’s encoding, and a POSIX locale leaves you with a non-UTF-8 database that Zammad’s documentation does not support. Debian’s cloud images default to C.UTF-8, which is fine. Check yours before going further.

locale | grep LANG=

Our server reported the UTF-8 default:

LANG=C.UTF-8

Any value ending in UTF-8 works, so you can move on.

Install Elasticsearch 9

Zammad works without Elasticsearch, but its search, reporting and ticket lookups then fall back to slow database queries. Install it first, so it is already running when you connect Zammad to it after the package install. Debian doesn’t package Elasticsearch, so add Elastic’s signed repository; the standalone Elasticsearch on Debian guide covers clusters and tuning beyond what Zammad needs.

sudo apt update
sudo apt install -y curl apt-transport-https gnupg
curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | gpg --dearmor | sudo tee /usr/share/keyrings/elasticsearch-keyring.gpg > /dev/null && sudo chmod 644 /usr/share/keyrings/elasticsearch-keyring.gpg
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/9.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-9.x.list

Install the package next. It needs 1.5 GB of disk because it bundles its own JDK, so you do not install Java separately. The install also prints a generated password for the elastic user, and there is no need to copy it, since a later step resets it into a variable.

sudo apt update
sudo apt install -y elasticsearch

Zammad indexes attachments as well as ticket text, so raise Elasticsearch’s request size limit to 400 MB, and bind it to localhost so it is never exposed. The second command rewrites the http.host: 0.0.0.0 line the package writes by default:

echo "http.max_content_length: 400mb" | sudo tee -a /etc/elasticsearch/elasticsearch.yml
sudo sed -i 's/^http.host: 0.0.0.0/http.host: 127.0.0.1/' /etc/elasticsearch/elasticsearch.yml

Elasticsearch sizes its heap from total RAM unless you tell it otherwise, and on a shared box that starves Zammad and PostgreSQL. Cap it at 2 GB for now, because that is comfortable on 8 GB. The tuning section at the end shows what 1 GB does to memory and to index rebuild time.

printf -- '-Xms2g\n-Xmx2g\n' | sudo tee /etc/elasticsearch/jvm.options.d/heap.options

Enable and start the service, then check where it listens. The first start took 24 seconds on our VM, so give it a moment before the ss check.

sudo systemctl enable elasticsearch.service --now
sudo ss -tlnp | grep 9200

Port 9200 should only appear on the loopback address. If you see *:9200 or 0.0.0.0:9200, the sed above didn’t match and Elasticsearch is reachable from outside:

LISTEN 0      4096   [::ffff:127.0.0.1]:9200            *:*    users:(("java",pid=10896,fd=886))

With Elasticsearch listening on localhost only, the search side is ready for Zammad.

Add the Zammad repository and install

Zammad’s packages are built by packager.io, which serves a separate repository per Debian release. Fetch the key and the repository file for your release; the second command reads the version from /etc/os-release, so it picks 13 on Trixie:

sudo curl -fsSL "https://go.packager.io/srv/deb/zammad/zammad/gpg-key.gpg" -o /usr/share/keyrings/zammad.gpg && sudo chmod 644 /usr/share/keyrings/zammad.gpg
. /etc/os-release
sudo curl -fsSL "https://go.packager.io/srv/zammad/zammad/stable/installer/debian/${VERSION_ID}.list" -o /etc/apt/sources.list.d/zammad.list
cat /etc/apt/sources.list.d/zammad.list

The file should point at the debian/ tree with suite 13. The same URL pattern serves Debian 12, so on Bookworm the command writes suite 12, but the rest of this guide is Trixie-only: Bookworm’s nginx 1.22 does not know the http2 on; directive used later, and it ships PostgreSQL 15 instead of 17.

# This file was automatically generated.
deb [signed-by=/usr/share/keyrings/zammad.gpg] https://go.packager.io/srv/deb/zammad/zammad/stable/debian/ 13 main
# GPG key: https://go.packager.io/srv/deb/zammad/zammad/gpg-key.asc

Now install Zammad. The package depends on PostgreSQL, Redis and nginx, so this one command brings the whole application stack, creates the database and starts every service. If you would rather run PostgreSQL on its own server, set that up first with the PostgreSQL on Debian guide and follow Zammad’s external database notes.

sudo apt update
sudo apt install -y zammad

It pulled 113 packages (a 339 MB download that unpacked to 1.3 GB) and took 3 minutes 39 seconds, most of it spent on database migrations after the packages unpacked. The installer finishes with a banner telling you to edit the nginx server_name, which is the next step. First, confirm that all four Zammad units and the services they need are up:

systemctl is-active zammad zammad-web zammad-worker zammad-websocket postgresql redis-server nginx

Seven lines of active mean the install is complete. Apart from Zammad itself, the stack comes from Debian’s own archive, so its security updates arrive with the rest of your apt upgrade:

nginx 1.26.3-3+deb13u9
postgresql 17+278
redis-server 5:8.0.2-3+deb13u3
zammad 7.2.2-1792091196.c958f83.debian13

Only Zammad comes from the packager.io repository; PostgreSQL 17, Redis and nginx are Debian’s own builds.

Connect Zammad to Elasticsearch

Elasticsearch 9 enables TLS and authentication by default, so Zammad needs the URL, a user and the cluster’s CA certificate. Reset the elastic password into a shell variable, so it is never printed to the terminal or stored in your history:

ES_PASS=$(sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic -b -s)

Hand the connection details to Zammad. Feed the password in on standard input rather than as a command-line argument, because arguments show up in ps for every local user while the Rails runner boots, which takes several seconds:

sudo zammad run rails r "Setting.set('es_url', 'https://localhost:9200')"
sudo zammad run rails r "Setting.set('es_user', 'elastic')"
printf '%s' "$ES_PASS" | sudo zammad run rails r "Setting.set('es_password', STDIN.read)"

Import Elasticsearch’s self-signed CA into Zammad’s trust list the same way, then build the search index. On a fresh install the rebuild took 13.5 seconds; on a migrated helpdesk with years of tickets, plan for much longer:

sudo cat /etc/elasticsearch/certs/http_ca.crt | sudo zammad run rails r 'SSLCertificate.create!(certificate: STDIN.read)'
sudo zammad run rake zammad:searchindex:rebuild

Don’t trust SearchIndexBackend.enabled? as a check: it only tests that es_url is set, and on our server it still printed true with Elasticsearch stopped. Ask Elasticsearch for Zammad’s indices instead, using the same password variable:

sudo curl -s --cacert /etc/elasticsearch/certs/http_ca.crt -u "elastic:$ES_PASS" "https://localhost:9200/_cat/indices?v" | grep -E 'health|zammad' | head -6

This one check does put the password on sudo‘s command line for the instant curl runs, which is acceptable for a one-off test on a server only you log in to. A working connection lists a set of zammad_production_* indices. They show yellow because a single node can’t place replica shards, which is normal here:

health status index                                                 uuid                   pri rep docs.count docs.deleted store.size pri.store.size dataset.size
yellow open   zammad_production_role                                WbTaLrHvS5OL6KAP14Kpgg   1   1          3            0     32.4kb         32.4kb       32.4kb
yellow open   zammad_production_report_profile                      8ZQKaixXR2isp6grmHd8jA   1   1          1            0      7.5kb          7.5kb        7.5kb
yellow open   zammad_production_knowledge_base_category_translation DFmimNlUQSatA5DDUM5IGQ   1   1          0            0       227b           227b         227b
yellow open   zammad_production_public_link                         fxihRNbQScWCyGFKT0FT_g   1   1          0            0       227b           227b         227b
yellow open   zammad_production_template                            fceDEBwCQlCNJCmiYhH-Cw   1   1          0            0       227b           227b         227b

No zammad_ lines means the rebuild never reached Elasticsearch, and the usual causes are a wrong password in es_password or a skipped CA import, so check those two before anything else.

Open the firewall

Debian ships without a firewall front end, so UFW is not there to configure. Install it, allow SSH before you enable it, then open HTTP for the certificate check and HTTPS for the helpdesk:

sudo apt install -y ufw
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable
sudo ufw status

Enabling UFW before the SSH rule exists can cut your own session, which is why the order matters. If you already run nftables or firewalld on Debian, open the same three ports there instead and skip UFW.

Point nginx at your domain

The Zammad package drops a site file with server_name localhost and leaves Debian’s default site enabled next to it. The default site would answer requests for your domain first, so remove it, set your domain in Zammad’s file and reload nginx.

sudo rm /etc/nginx/sites-enabled/default
sudo sed -i "s/server_name localhost;/server_name ${ZAMMAD_DOMAIN};/" /etc/nginx/sites-available/zammad.conf
sudo nginx -t && sudo systemctl reload nginx

Zammad now answers on plain HTTP at your domain, and on the server’s bare IP too, because its site is the only one left. Keep it that way only until the certificate is issued, because Zammad’s login cookies expect HTTPS. More importantly, the setup wizard is open from this moment: the first person to reach it creates the administrator account. On a public server, either work through the next sections without long breaks, or limit ports 80 and 443 in UFW to your own address until the admin account exists.

Get a TLS certificate

Zammad’s nginx TLS template expects a Diffie-Hellman parameter file. Generating 4096-bit parameters is slow and random: it took 15 minutes 16 seconds on this Debian VM, against 3 minutes 3 seconds for the same command on an Ubuntu VM of the same size. Mozilla publishes the standard RFC 7919 ffdhe4096 group, which is what a good DH file should be anyway, so fetch it instead of waiting:

curl -fsSL https://ssl-config.mozilla.org/ffdhe4096.txt | sudo tee /etc/ssl/dhparam.pem > /dev/null
sudo openssl dhparam -in /etc/ssl/dhparam.pem -noout -text | head -2

OpenSSL recognises it as the named group:

    DH Parameters: (4096 bit)
    GROUP: ffdhe4096

Install Certbot from the Debian archive; Trixie ships version 4.0 with the nginx plugin:

sudo apt install -y certbot python3-certbot-nginx

Request the certificate with certonly, so Certbot proves the domain through nginx but leaves Zammad’s config alone. The next section replaces that config with Zammad’s TLS template, which carries the websocket proxy headers Certbot’s version would miss:

sudo certbot certonly --nginx -d "${ZAMMAD_DOMAIN}" -m "${ADMIN_EMAIL}" --agree-tos --non-interactive

Our lab server had no public DNS, so this request is the one command we couldn’t run; we put a certificate at the same /etc/letsencrypt/live/ paths and tested everything after it. If Certbot fails, check that the A record resolves to this server and that port 80 is open at your provider’s firewall as well as in UFW.

Switch nginx to HTTPS

Copy Zammad’s TLS template over the HTTP site and point it at your domain and the Let’s Encrypt files. The template already carries the proxy headers the websocket needs, which is why it beats writing a TLS block yourself.

sudo cp /opt/zammad/contrib/nginx/zammad_ssl.conf /etc/nginx/sites-available/zammad.conf
sudo sed -i -e "s/server_name example.com;/server_name ${ZAMMAD_DOMAIN};/" \
  -e "s#/etc/ssl/certs/example.com.pem#/etc/letsencrypt/live/${ZAMMAD_DOMAIN}/fullchain.pem#" \
  -e "s#/etc/ssl/private/example.com.key#/etc/letsencrypt/live/${ZAMMAD_DOMAIN}/privkey.pem#" \
  -e "s#/etc/ssl/certs/root-ca-plus-intermediates.pem#/etc/letsencrypt/live/${ZAMMAD_DOMAIN}/chain.pem#" \
  /etc/nginx/sites-available/zammad.conf
sudo nginx -t

The template passes the test, but nginx 1.26 on Trixie complains about it in three places.

2026/10/18 07:00:14 [warn] 19350#19350: the "listen ... http2" directive is deprecated, use the "http2" directive instead in /etc/nginx/sites-enabled/zammad.conf:36
2026/10/18 07:00:14 [warn] 19350#19350: the "listen ... http2" directive is deprecated, use the "http2" directive instead in /etc/nginx/sites-enabled/zammad.conf:37
2026/10/18 07:00:14 [warn] 19350#19350: "ssl_stapling" ignored, no OCSP responder URL in the certificate "/etc/letsencrypt/live/helpdesk.example.com/fullchain.pem"

Fix all three, plus a fourth issue the warnings do not mention. The commands below make four changes to the template:

  • move the port 80 return 301 into a location / block
  • turn ssl_stapling and ssl_stapling_verify off
  • drop http2 from both listen 443 lines
  • add a separate http2 on; directive

The redirect is the one that matters. The template puts return 301 at server level, which runs before any location, so the /.well-known/ location meant for certificate challenges never gets a request. Certbot’s nginx plugin works around that on renewal, but webroot-based ACME clients do not. Stapling goes because Let’s Encrypt removed OCSP URLs from its certificates in May 2025, so there is nothing left to staple:

sudo sed -i 's|^  return 301 https://$server_name$request_uri;|  location / {\n    return 301 https://$server_name$request_uri;\n  }|' /etc/nginx/sites-available/zammad.conf
sudo sed -i -e 's/ssl_stapling on;/ssl_stapling off;/' -e 's/ssl_stapling_verify on;/ssl_stapling_verify off;/' /etc/nginx/sites-available/zammad.conf
sudo sed -i -e 's/listen 443 ssl http2;/listen 443 ssl;/' -e 's/listen \[::\]:443 ssl http2;/listen [::]:443 ssl;\n  http2 on;/' /etc/nginx/sites-available/zammad.conf
sudo nginx -t && sudo systemctl reload nginx

The test is now clean, with no warnings. Give the reloaded workers a moment, then check both ports. Run the checks from your workstation, or from the server if your provider routes its own public address back to it.

sleep 2
curl -sI "http://${ZAMMAD_DOMAIN}/" | grep -iE "^HTTP|^location"
curl -sI "https://${ZAMMAD_DOMAIN}/" | grep -iE "^HTTP|strict-transport"

Port 80 redirects and port 443 answers over HTTP/2 with HSTS. Our first check, run the instant the reload returned, still got a 200 on port 80 from an old worker; with a two-second pause the redirect was there, so wait a moment before you decide something is wrong:

HTTP/1.1 301 Moved Permanently
Location: https://helpdesk.example.com/
HTTP/2 200
strict-transport-security: max-age=63072000

Both lines must show up before you move on; a missing strict-transport-security header means the TLS server block isn’t the one answering.

Set the URL Zammad uses

Zammad builds the links in its notification emails from two settings, fqdn and http_type. A fresh install starts with zammad.example.com over http, and the setup wizard fills them from its System URL field, which it guesses from the address you open it on. Set them now, so a wizard opened by IP address or over plain HTTP can’t leave your customers with broken ticket links:

sudo zammad run rails r "Setting.set('fqdn', ARGV[0]); Setting.set('http_type', 'https')" "${ZAMMAD_DOMAIN}"
sudo zammad run rails r "puts Setting.get('fqdn'), Setting.get('http_type')"

Both values come back as you set them:

helpdesk.example.com
https

Notification emails now link to https://helpdesk.example.com rather than the seeded placeholder.

Create the admin account

Open https://helpdesk.example.com in a browser and choose Set up a new system. The first screen creates the administrator, and Zammad’s password policy applies right away. Our first attempt used a long lowercase-and-digits password and was refused:

Zammad administrator account form on Debian 13 showing the password policy error

The red banner names the exact rule the password broke.

Invalid password, it must contain at least 2 lowercase and 2 uppercase characters!

The form keeps your other fields, so only the two password boxes need a new value. Length alone does not satisfy the rule, and the message names the character class you’re missing; Zammad’s documentation lists the full default policy as 10 or more characters, 2 uppercase and 2 lowercase letters, and at least one digit.

With a compliant password, Zammad creates the account and moves on to the rest of the wizard: company name and logo, the notification sender (sendmail by default, or SMTP), and an optional first mailbox. Skip the mailbox if you want to test first, because Zammad acts on every email it fetches. The agent dashboard is where you land after signing in:

Zammad agent dashboard after the first login on Debian 13

The Ubuntu version of this guide walks through creating a first ticket and searching it, which is the quickest proof that the Elasticsearch connection works end to end; the Zammad on Ubuntu guide has those screens. If the login loops back to the sign-in page, the CSRF token verification fix covers the proxy headers that cause it.

Moving from the MariaDB version of this guide

If your Zammad came from an older guide that used MariaDB, do not upgrade the package yet. Zammad 7 supports PostgreSQL only, and its documentation states that an upgrade to Zammad 7 is not possible on a MySQL installation, so apt upgrade on that box hits a wall rather than a newer helpdesk.

The supported route is to move the data first and upgrade second, in this order:

  1. Back up the current instance with the backup script below
  2. Install PostgreSQL next to MariaDB
  3. Migrate the data with pgloader, following Zammad’s migration guide
  4. Point Zammad at PostgreSQL and confirm it starts
  5. Only then upgrade to Zammad 7

The migration commands need Zammad 5.3 or newer. We did not run a MariaDB migration in this lab, so follow the upstream page for those exact steps. A fresh install on a new Debian 13 server, as above, followed by a data move is often less work than in-place surgery on an old Debian 11 box.

Back up Zammad

Zammad ships a backup script that dumps the database and, optionally, the file store. Copy the sample config into place, then read the settings, because the defaults keep backups on the same disk as the data they protect.

sudo cp /opt/zammad/contrib/backup/config.dist /opt/zammad/contrib/backup/config
grep -E '^[A-Z_]+=' /opt/zammad/contrib/backup/config

Backups land in /var/tmp/zammad_backup and are kept for 10 days. That directory is on the same disk as Zammad, so copy it off the server too:

BACKUP_DIR='/var/tmp/zammad_backup'
HOLD_DAYS='10'
FULL_FS_DUMP='no'
DEBUG='no'

Run it once by hand and list what it wrote.

sudo /opt/zammad/contrib/backup/zammad_backup.sh
sudo ls -lh /var/tmp/zammad_backup/

On a fresh install it finished in under a second with a 6.4 MB database dump. The latest_* links always point at the newest pair, so a restore script never has to work out timestamps.

-rw------- 1 root root 6.4M Oct 18 07:01 20261018070119_zammad_db.psql.gz
-rw------- 1 root root  126 Oct 18 07:01 20261018070119_zammad_files.tar.gz
lrwxrwxrwx 1 root root   55 Oct 18 07:01 latest_zammad_db.psql.gz -> /var/tmp/zammad_backup/20261018070119_zammad_db.psql.gz
lrwxrwxrwx 1 root root   57 Oct 18 07:01 latest_zammad_files.tar.gz -> /var/tmp/zammad_backup/20261018070119_zammad_files.tar.gz

Schedule it nightly from root’s crontab with sudo crontab -e and a line such as 0 2 * * * /opt/zammad/contrib/backup/zammad_backup.sh, then ship the directory to object storage or another host.

Watch Zammad’s health

Zammad exposes a health endpoint for your monitoring system under the gear icon at Settings > System > Monitoring. The page shows a token and a ready-made URL. Treat the token like a password, because anyone who has it can read your instance’s health details, which is why it is blanked out here.

Zammad System Monitoring page on Debian 13 with the health check token and no issues status

Poll that URL with your token from Uptime Kuma on Debian, Zabbix or a plain cron job. A healthy instance returns a short JSON document.

{"healthy":true,"message":"success","issues":[],"actions":[]}

Don’t rely on it for search, though. We stopped Elasticsearch on the test server and polled the endpoint again, with TOKEN holding the monitoring token:

sudo systemctl stop elasticsearch; systemctl is-active elasticsearch
curl -s "https://helpdesk.example.com/api/v1/monitoring/health_check?token=${TOKEN}"

Elasticsearch was down, and Zammad still called itself healthy:

inactive
{"healthy":true,"message":"success","issues":[],"actions":[]}

A dead search cluster therefore goes unnoticed until agents complain that search returns nothing. Add a separate check on systemctl is-active elasticsearch, or on the _cat/indices query from the Elasticsearch section, next to the Zammad one, and start Elasticsearch again with sudo systemctl start elasticsearch if you tried this yourself.

Tune memory on a small server

Two settings decide whether Zammad fits a smaller VM, and we measured both on this server. Elasticsearch’s heap is the big one. Dropping it from 2 GB to 1 GB took its resident memory from 2.6 GB to 1.5 GB, and the box’s used memory from 3.9 GB to 2.8 GB:

printf -- '-Xms1g\n-Xmx1g\n' | sudo tee /etc/elasticsearch/jvm.options.d/heap.options
sudo systemctl restart elasticsearch

The indices survive the restart, so there is nothing to rebuild. We ran a rebuild anyway as a timing test, and it took 20.7 seconds instead of 13.5; don’t repeat that on a busy helpdesk, because a rebuild drops and recreates the indices and search is degraded until it finishes. A 1 GB heap is fine for a small team with a modest ticket history; once the index grows past a few gigabytes or searches slow down, give the heap back, keeping it at no more than half the RAM you can spare for Elasticsearch.

The other lever is Puma, Zammad’s web server. By default it runs a single process, which used 246 MB here. Setting WEB_CONCURRENCY (Zammad’s documentation lists it as ZAMMAD_WEB_CONCURRENCY; we tested the shorter name) forks extra workers for more concurrent agents, and each one costs about the same again:

sudo zammad config:set WEB_CONCURRENCY=2
sudo systemctl restart zammad

With two workers, Puma’s total grew to about 690 MB, a 237 MB master plus two 228 MB workers. Only add workers when agents report a sluggish UI under load, and remove the setting with sudo zammad config:unset WEB_CONCURRENCY if you do not need it. On an 8 GB server the defaults above leave plenty of headroom, and on a 6 GB server the 1 GB Elasticsearch heap is the change that makes the difference.

Keep reading

Configure Samba File Share on Debian 13 / 12 Debian Configure Samba File Share on Debian 13 / 12 Backup and Restore Linux Systems with Timeshift Debian Backup and Restore Linux Systems with Timeshift Install KVM on Debian 13 / Debian 12: Complete Guide KVM Install KVM on Debian 13 / Debian 12: Complete Guide Upgrade a Single Package on Ubuntu / Debian with apt Debian Upgrade a Single Package on Ubuntu / Debian with apt APT Cheat Sheet: apt and apt-get Commands for Ubuntu/Debian Cheat Sheets APT Cheat Sheet: apt and apt-get Commands for Ubuntu/Debian How To Install Snap on Ubuntu or Debian Containers How To Install Snap on Ubuntu or Debian

Leave a Comment

Press ESC to close