Understanding Manjaro as a Server Operating System
Manjaro is an Arch Linux derivative that bridges the gap between the bleeding-edge, do-it-yourself nature of Arch and the user-friendly experience expected from modern distributions. While Manjaro is primarily known as a desktop operating system, its server deployment capabilities are often overlooked. Manjaro Server is not a separate edition — it is the same Manjaro base configured without a graphical environment and optimized for headless, always-on operations. It inherits Arch's rolling release model, pacman package manager, and access to the AUR, but adds its own curated repositories, stability checks, and pre-configured kernels.
A Manjaro server gives you near-instant access to the latest software packages, a minimal footprint, and complete control over every component running on your system — making it an exceptional choice for developers, DevOps engineers, and self-hosted infrastructure enthusiasts who want a lightweight, modern Linux server without the bloat of traditional LTS distributions.
Why Manjaro for Server Deployments Matters
🚀 Deploy your AI agent in 10 minutes
Managed Hermes hosting. Zero DevOps. 100M tokens/mo included.
Try it free →Choosing the right operating system for a production server is a strategic decision. Manjaro brings several distinct advantages to the table that set it apart from Debian-based or RHEL-based alternatives:
- Rolling Release with a Safety Net: Unlike Arch, Manjaro holds packages in its own repositories for additional testing. You get fresh software without the immediate risk of upstream breakage.
- Package Availability: Access to the official repositories, the AUR, and the ability to build from source with ease means virtually any server software is available.
- Minimal Base System: A Manjaro server installation starts lean. No desktop environment, no unnecessary services — just what you define.
- Kernel Management: Manjaro offers multiple kernel versions with simple switching. This is invaluable for workloads that require specific kernel features or hardware compatibility.
- Performance: Arch-based systems are built with modern compiler flags and optimizations, often yielding measurable performance gains for compute-heavy workloads.
- Learning Curve Alignment: Teams familiar with Arch principles will find Manjaro's server environment intuitive and well-documented.
Pre-Installation Planning and Hardware Considerations
Before inserting the installation media, define the server's role. Is it a web server, database host, container orchestration node, or a multi-purpose application server? This decision drives partition layout, package selection, and kernel configuration. For production deployments, consider the following minimum specifications:
- CPU: 2 cores minimum; 4+ cores recommended for production workloads
- RAM: 2 GB minimum for headless operation; 8 GB+ for database or container-heavy roles
- Storage: 20 GB minimum for a base system; 50 GB+ with separate partitions for data and logs
- Network: Gigabit Ethernet with static IP capability; dual NICs if serving as a router or firewall
Download the latest Manjaro minimal ISO from the official website. The minimal ISO provides a command-line installer — perfect for server deployments where no graphical environment is needed.
Step-by-Step Installation Guide
Step 1: Booting the Installation Media
Write the ISO to a USB drive and boot from it. On UEFI systems, ensure UEFI boot mode is selected. You will be greeted by a command-line prompt. Manjaro's minimal ISO uses the manjaro-arm-installer or the CLI installer depending on architecture. For x86_64 systems, use the setup command to launch the terminal-based installer.
Step 2: Partitioning the Disk
Proper partitioning is critical for server longevity. A recommended partition scheme for a production server on a 100 GB drive looks like this:
# Partition layout (using fdisk or parted)
/dev/sda1 - 512 MB EFI System Partition (for UEFI boot)
/dev/sda2 - 1 GB /boot (kernel images and initramfs)
/dev/sda3 - 20 GB / (root filesystem)
/dev/sda4 - 8 GB swap (sized for RAM + hibernation if needed)
/dev/sda5 - remaining /var (logs, databases, variable data)
Use fdisk or parted to create these partitions. For the EFI partition, ensure it is formatted as FAT32 with type code EFI System. Example using fdisk interactively:
# Launch fdisk on the target disk
fdisk /dev/sda
# Create GPT partition table (g command)
# Create partitions with appropriate sizes
# Set EFI partition type to 1 (EFI System)
# Write changes with w
After partitioning, format each partition:
# Format EFI partition
mkfs.fat -F32 /dev/sda1
# Format boot partition (ext4 recommended)
mkfs.ext4 /dev/sda2
# Format root partition
mkfs.ext4 /dev/sda3
# Initialize swap
mkswap /dev/sda4
swapon /dev/sda4
# Format /var partition (ext4 or XFS for large file support)
mkfs.ext4 /dev/sda5
Step 3: Mounting and Base Installation
Mount the partitions in the correct order:
# Mount root partition
mount /dev/sda3 /mnt
# Create mount points
mkdir -p /mnt/{boot,var,efi}
# Mount boot
mount /dev/sda2 /mnt/boot
# Mount var
mount /dev/sda5 /mnt/var
# Mount EFI
mount /dev/sda1 /mnt/efi
Now install the base system using pacstrap:
# Install base system packages
pacstrap /mnt base base-devel linux-lts linux-lts-headers \
linux-firmware manjaro-release manjaro-system \
nano sudo networkmanager openssh grub efibootmgr \
curl wget git htop iotop nfs-utils samba \
ufw fail2ban apparmor manjaro-tools-base
The linux-lts kernel is recommended for servers. It receives long-term support patches and is less likely to introduce breaking changes compared to the latest kernel. You can install additional kernels later using Manjaro's kernel management tools.
Step 4: System Configuration
Generate the filesystem table:
genfstab -U /mnt >> /mnt/etc/fstab
Chroot into the new system:
manjaro-chroot /mnt /bin/bash
Set the timezone, locale, and hostname:
# Set timezone (adjust for your region)
ln -sf /usr/share/zoneinfo/America/New_York /etc/localtime
# Generate locale
echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
locale-gen
# Set system language
echo "LANG=en_US.UTF-8" > /etc/locale.conf
# Set hostname
echo "manjaro-server" > /etc/hostname
# Configure hosts file
cat > /etc/hosts << 'EOF'
127.0.0.1 localhost
::1 localhost
127.0.1.1 manjaro-server.localdomain manjaro-server
EOF
Set the root password and create an administrative user:
# Set root password
passwd root
# Create admin user with sudo privileges
useradd -m -G wheel -s /bin/bash adminuser
passwd adminuser
# Enable sudo for wheel group
echo "%wheel ALL=(ALL:ALL) ALL" >> /etc/sudoers
Step 5: Bootloader Installation
Install GRUB for UEFI systems:
# Install GRUB
grub-install --target=x86_64-efi --efi-directory=/efi \
--bootloader-id=Manjaro-Server --recheck
# Generate GRUB configuration
grub-mkconfig -o /boot/grub/grub.cfg
Exit the chroot, unmount partitions, and reboot:
exit
umount -R /mnt
reboot
Post-Installation System Hardening
Security is not optional in production. Immediately after first boot, lock down the system before installing any services.
Enable and Configure the Firewall
Manjaro ships with UFW (Uncomplicated Firewall), which provides a sane interface to iptables:
# Start and enable UFW
systemctl enable --now ufw
# Set default deny policies
ufw default deny incoming
ufw default allow outgoing
# Allow SSH (limit connection rate)
ufw limit ssh
# Allow HTTP and HTTPS if this is a web server
ufw allow 80/tcp
ufw allow 443/tcp
# Enable the firewall
ufw enable
# Verify status
ufw status verbose
Configure Fail2ban for Intrusion Prevention
Fail2ban monitors log files and temporarily bans IPs that exhibit malicious behavior:
# Create a local configuration override
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
# Edit the local configuration
cat > /etc/fail2ban/jail.local << 'EOF'
[DEFAULT]
bantime = 3600
findtime = 600
maxretry = 5
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
[sshd-ddos]
enabled = true
port = ssh
filter = sshd-ddos
logpath = /var/log/auth.log
maxretry = 6
EOF
# Start and enable fail2ban
systemctl enable --now fail2ban
# Check status
fail2ban-client status
SSH Daemon Hardening
The default SSH configuration is permissive. Tighten it:
# Edit SSH configuration
cat > /etc/ssh/sshd_config << 'EOF'
Port 22
Protocol 2
HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
# Authentication
LoginGraceTime 30
PermitRootLogin prohibit-password
StrictModes yes
MaxAuthTries 3
MaxSessions 5
PubkeyAuthentication yes
PasswordAuthentication yes
PermitEmptyPasswords no
ChallengeResponseAuthentication no
UsePAM yes
# Hardening
X11Forwarding no
PrintMotd no
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers adminuser
EOF
# Regenerate host keys with stronger algorithms
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
# Restart SSH
systemctl restart sshd
Enable Automatic Security Updates
Manjaro's rolling release model means updates arrive continuously. Automating security patches reduces exposure:
# Install pamac (Manjaro's package manager helper)
pacman -S pamac-cli
# Create a systemd timer for weekly updates
cat > /etc/systemd/system/pacman-update.service << 'EOF'
[Unit]
Description=Automated package updates
After=network-online.target
Wants=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/bin/pamac upgrade --no-confirm --aur
StandardOutput=journal
EOF
cat > /etc/systemd/system/pacman-update.timer << 'EOF'
[Unit]
Description=Weekly package update trigger
[Timer]
OnCalendar=weekly
Persistent=true
[Install]
WantedBy=timers.target
EOF
systemctl enable pacman-update.timer
systemctl start pacman-update.timer
Setting Up Core Server Services
Network Configuration with Static IP
Servers need static IP addresses. Configure NetworkManager or switch to systemd-networkd for a lighter alternative:
# Disable NetworkManager if not needed
systemctl disable NetworkManager
systemctl stop NetworkManager
# Enable systemd-networkd
systemctl enable --now systemd-networkd
systemctl enable --now systemd-resolved
# Create wired network configuration
cat > /etc/systemd/network/10-wired.network << 'EOF'
[Match]
Name=enp0s3
[Network]
Address=192.168.1.100/24
Gateway=192.168.1.1
DNS=1.1.1.1
DNS=8.8.8.8
EOF
# Apply configuration
networkctl reload
networkctl status enp0s3
Web Server Stack: Nginx + PHP + MariaDB
For a typical LEMP stack deployment:
# Install packages
pacman -S nginx-mainline php php-fpm mariadb php-pgsql \
php-sqlite php-gd php-imagick php-intl php-apcu \
php-memcached php-redis composer certbot certbot-nginx
# Start and enable MariaDB
systemctl enable --now mariadb
# Secure MariaDB installation
mysql_secure_installation
# Answer prompts: set root password, remove anonymous users,
# disallow remote root login, remove test database, reload privileges
# Create application database and user
mysql -u root -p << 'SQL'
CREATE DATABASE app_production CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'appuser'@'localhost' IDENTIFIED BY 'SecurePassword123!';
GRANT ALL PRIVILEGES ON app_production.* TO 'appuser'@'localhost';
FLUSH PRIVILEGES;
EXIT;
SQL
# Configure PHP-FPM
sed -i 's/;cgi.fix_pathinfo=1/cgi.fix_pathinfo=0/' /etc/php/php.ini
sed -i 's/expose_php = On/expose_php = Off/' /etc/php/php.ini
sed -i 's/memory_limit = 128M/memory_limit = 256M/' /etc/php/php.ini
sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 64M/' /etc/php/php.ini
# Start PHP-FPM
systemctl enable --now php-fpm
Configure Nginx with production-grade settings:
# Create Nginx site configuration
cat > /etc/nginx/sites-available/app.conf << 'EOF'
server {
listen 80;
listen [::]:80;
server_name app.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name app.example.com;
ssl_certificate /etc/letsencrypt/live/app.example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/app.example.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
root /var/www/app/public;
index index.php index.html;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_read_timeout 300;
}
location ~ /\.(ht|git|env) {
deny all;
}
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
}
EOF
# Enable the site
mkdir -p /etc/nginx/sites-enabled
ln -sf /etc/nginx/sites-available/app.conf /etc/nginx/sites-enabled/app.conf
# Set correct permissions
chown -R http:http /var/www/app
find /var/www/app -type d -exec chmod 755 {} \;
find /var/www/app -type f -exec chmod 644 {} \;
# Start Nginx
systemctl enable --now nginx
Container Runtime with Docker
Docker is essential for modern server workloads:
# Install Docker
pacman -S docker docker-compose
# Start and enable Docker
systemctl enable --now docker
# Add admin user to docker group
usermod -aG docker adminuser
# Configure Docker daemon for production
cat > /etc/docker/daemon.json << 'EOF'
{
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2",
"live-restore": true,
"icc": false,
"userland-proxy": false
}
EOF
systemctl restart docker
Monitoring Stack: Prometheus + Node Exporter + Grafana
Observability is not optional in production. Deploy a basic monitoring stack:
# Install node exporter for system metrics
pacman -S prometheus-node-exporter
systemctl enable --now prometheus-node-exporter
# Install Prometheus
pacman -S prometheus
cat > /etc/prometheus/prometheus.yml << 'EOF'
global:
scrape_interval: 15s
evaluation_interval: 15s
scrape_configs:
- job_name: 'node'
static_configs:
- targets: ['localhost:9100']
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
EOF
systemctl enable --now prometheus
# Install Grafana
pacman -S grafana
systemctl enable --now grafana-server
# Grafana will be available at http://localhost:3000
# Default credentials: admin/admin — change immediately
Automated Backups with Rsnapshot
Production servers require automated, tested backup strategies. Rsnapshot provides efficient incremental backups using rsync:
# Install rsnapshot
pacman -S rsnapshot rsync
# Configure rsnapshot
cat > /etc/rsnapshot.conf << 'EOF'
config_version 1.2
snapshot_root /backups/
no_create_root 1
cmd_cp /usr/bin/cp
cmd_rm /usr/bin/rm
cmd_rsync /usr/bin/rsync
cmd_logger /usr/bin/logger
interval hourly 6
interval daily 7
interval weekly 4
interval monthly 3
backup /etc/ localhost/
backup /home/ localhost/
backup /var/www/ localhost/
backup /var/lib/mysql/ localhost/
exclude /var/cache/pacman/pkg/
EOF
# Create backup directory
mkdir -p /backups
# Create cron job for rsnapshot
cat > /etc/cron.d/rsnapshot << 'EOF'
0 */4 * * * root /usr/bin/rsnapshot hourly
30 1 * * * root /usr/bin/rsnapshot daily
0 2 * * 1 root /usr/bin/rsnapshot weekly
30 2 1 * * root /usr/bin/rsnapshot monthly
EOF
SSL/TLS Certificate Automation with Certbot
Let's Encrypt certificates should be automated from day one:
# Install certbot
pacman -S certbot certbot-nginx
# Obtain certificate (ensure DNS resolves and Nginx is running)
certbot --nginx -d app.example.com --non-interactive \
--agree-tos --email admin@example.com --redirect
# Enable automatic renewal
systemctl enable --now certbot-renew.timer
# Verify renewal timer
systemctl list-timers certbot-renew.timer
Kernel Tuning for Server Workloads
Manjaro's kernel management tools allow precise tuning. Apply sysctl parameters optimized for server workloads:
# Create sysctl configuration
cat > /etc/sysctl.d/99-server-tuning.conf << 'EOF'
# Increase network throughput
net.core.rmem_max = 134217728
net.core.wmem_max = 134217728
net.ipv4.tcp_rmem = 4096 87380 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
# Increase file descriptors
fs.file-max = 2097152
fs.nr_open = 1048576
# Reduce swap tendency (good for servers with ample RAM)
vm.swappiness = 10
vm.vfs_cache_pressure = 50
# Enable TCP fast open
net.ipv4.tcp_fastopen = 3
# Protect against common attacks
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.all.secure_redirects = 0
net.ipv4.conf.default.secure_redirects = 0
# Kernel hardening
kernel.kptr_restrict = 2
kernel.yama.ptrace_scope = 2
kernel.pid_max = 4194304
EOF
# Apply immediately
sysctl --system
Log Management with Journald
Systemd's journal is powerful but needs configuration for production:
# Configure journald
cat > /etc/systemd/journald.conf << 'EOF'
[Journal]
Storage=persistent
Compress=yes
Seal=yes
RateLimitIntervalSec=30
RateLimitBurst=1000
SystemMaxUse=2G
SystemKeepFree=500M
SystemMaxFileSize=100M
MaxRetentionSec=30day
SyncIntervalSec=5m
ForwardToSyslog=no
EOF
systemctl restart systemd-journald
Production Deployment Checklist
Before declaring the server production-ready, run through this checklist:
- Firewall active and rules verified:
ufw status verbose - SSH hardened and key-based auth tested: Verify login with SSH keys before disabling password authentication
- Automatic updates configured: Ensure the pamac timer is active
- Backups tested: Run
rsnapshot hourlymanually and verify restoration - Monitoring dashboards accessible: Confirm Grafana loads and shows node metrics
- SSL certificates valid: Check with
certbot certificates - Database secured: No anonymous users, no test databases
- Application runs as non-root user: Verify with
ps aux - Log rotation active: Journald limits configured
- Disk space monitored: Set up alerts for disk usage over 80%
Best Practices for Manjaro Server Management
1. Use the LTS Kernel for Stability
The linux-lts kernel receives backported fixes and avoids the rapid churn of the latest kernel. Switch kernels with:
pacman -S linux-lts linux-lts-headers
# Remove other kernels if not needed
pacman -R linux linux-headers
# Update bootloader after kernel changes
grub-mkconfig -o /boot/grub/grub.cfg
2. Leverage Manjaro's Staging Repositories
For production, consider enabling the unstable or testing repositories only for specific packages that need bleeding-edge features, while keeping the core system on stable:
# /etc/pacman.conf — keep stable as default
# Only uncomment [testing] for specific packages with caution
3. Implement Configuration Management
Use dotfiles, Ansible, or a simple Git repository to track all configuration changes. This enables rapid redeployment and auditing:
# Initialize a configuration tracking repo
cd /etc
git init
git add nginx/ ssh/ systemd/ ufw/ fail2ban/
git commit -m "Initial production configuration snapshot"
# Push to a private remote repository
4. Regular Package Database Maintenance
Arch-based systems require periodic maintenance to prevent package database corruption and orphan accumulation:
# Clean package cache (keep last 3 versions)
paccache -r -k 3
# Remove orphaned packages
pacman -Rns $(pacman -Qtdq)
# Refresh mirror list monthly
pacman-mirrors --fasttrack && pacman -Syyu
5. Test Updates in a Staging Environment
Before applying major updates to production, replicate the server configuration in a container or VM and run the updates there first. Manjaro's rolling nature means regressions can occur — a staging environment catches them before they reach users.
6. Enable AppArmor for Mandatory Access Control
AppArmor profiles restrict application capabilities at the kernel level:
# Install and enable AppArmor
pacman -S apparmor
systemctl enable --now apparmor
# Verify status
aa-status
7. Document Every Change
Maintain a changelog file at /root/CHANGELOG.md recording every modification with timestamps. In incident response scenarios, this log is invaluable for determining what changed and when.
Disaster Recovery and Migration Planning
A production server must have a documented recovery procedure. Create a script that rebuilds the server from scratch:
# Create a recovery script template
cat > /root/recovery/recover-server.sh << 'EOF'
#!/bin/bash
# Manjaro Server Recovery Script — Generated $(date +%Y-%m-%d)
set -euo pipefail
echo "Starting recovery process..."
# Install base packages
pacstrap /mnt base base-devel linux-lts linux-lts-headers \
linux-firmware manjaro-release manjaro-system \
nano sudo networkmanager openssh grub efibootmgr \
curl wget git htop iotop nfs-utils samba \
ufw fail2ban apparmor manjaro-tools-base \
nginx-mainline php php-fpm mariadb \
docker docker-compose prometheus grafana \
certbot certbot-nginx rsnapshot
# Restore configuration from backup
rsync -avz /backup/latest/etc/ /mnt/etc/
rsync -avz /backup/latest/var/www/ /mnt/var/www/
rsync -avz /backup/latest/var/lib/mysql/ /mnt/var/lib/mysql/
echo "Recovery script complete. Boot into the new system and verify."
EOF
chmod +x /root/recovery/recover-server.sh
Test this recovery procedure quarterly by restoring to a spare machine or VM. An untested backup is not a backup — it is a wish.
Conclusion
Manjaro Server bridges the gap between Arch Linux's raw power and the operational stability demanded by production environments. By combining Manjaro's curated repositories, the LTS kernel, and a rigorous security posture, you gain a server operating system that is simultaneously modern, minimal, and manageable. The rolling release model keeps your stack current without the disruptive major-version upgrades that plague traditional distributions, while the AUR unlocks access to virtually any server software imaginable.
The journey from bare metal to a production-ready Manjaro server requires deliberate effort — partitioning for growth, hardening every exposed service, automating backups, and establishing observability before you need it. This tutorial has walked you through each of these stages, providing concrete, tested configurations that you can adapt to your specific workload. Whether you are deploying a web application, a container orchestration platform, or a database cluster, the principles remain the same: start minimal, secure early, automate relentlessly, and document everything. With these foundations in place, your Manjaro server is ready to serve as a reliable, high-performance foundation for years to come.