OpenClaw Self-Hosting on AlmaLinux 10: Setup Guide

ML and AI

By Jennifer Webb

Updated on Aug 09, 2026

OpenClaw Self-Hosting on AlmaLinux 10: Setup Guide

What this tutorial sets up

This guide shows how to deploy a private OpenClaw self-hosting instance on a fresh AlmaLinux 10 dedicated server, secure it, place it behind Nginx, and confirm that it comes back cleanly after a reboot. It is aimed at HostnExtra customers who want local control over an AI workload without turning the server into a general-purpose test bed. If you are still choosing hardware, start with a dedicated server from HostnExtra dedicated infrastructure so you get full root access, NVMe storage, and predictable network behavior.

You will create a non-root sudo user, install the runtime pieces, sit OpenClaw behind a reverse proxy, add TLS with Let’s Encrypt, and test the service from both the server and a client machine. The same structure works for other private AI services that expose a local web interface and an HTTP port.

Prerequisites, DNS, and server access

  • One fresh AlmaLinux 10 dedicated server
  • At least 2 CPU cores, 4 GB RAM, and 30 GB free storage for a small private deployment
  • A domain or subdomain such as claw.example.com
  • An A record pointing claw.example.com to your server IPv4 address
  • Open ports 22, 80, and 443
  • Local computer with SSH client

Use these placeholders in the commands below: SERVER_IP=203.0.113.10, DOMAIN_NAME=claw.example.com, ADMIN_USER=deploy, and APP_DIR=/opt/openclaw.

Important: keep your original root SSH session open until the non-root login test succeeds.

ssh [email protected]

This is your first connection from the local machine to the server. If your provider uses a custom SSH port, add it with -p. After you log in, run the OS check first:

cat /etc/os-release

Confirm that the server is running AlmaLinux 10 before you use the RHEL-family commands. The instructions below are split for AlmaLinux/Rocky Linux and Ubuntu/Debian so you do not mix package managers or firewall tools.

AlmaLinux 10 and Rocky Linux 10

Create the sudo user and SSH key access

Run these commands as VPS as root. They create the admin account, add it to the wheel group, set up the SSH directory, and install your public key.

ADMIN_USER=deploy
useradd -m -s /bin/bash "$ADMIN_USER"
passwd "$ADMIN_USER"
usermod -aG wheel "$ADMIN_USER"
install -d -m 700 -o "$ADMIN_USER" -g "$ADMIN_USER" /home/$ADMIN_USER/.ssh
nano /home/$ADMIN_USER/.ssh/authorized_keys
chown "$ADMIN_USER:$ADMIN_USER" /home/$ADMIN_USER/.ssh/authorized_keys
chmod 600 /home/$ADMIN_USER/.ssh/authorized_keys

The passwd command sets the new account password. Paste your local public key into authorized_keys, save the file, and exit the editor. Ownership and permissions matter here; SSH will reject the key file if they are wrong.

From your local computer, open a second terminal and test the new login before you change root access:

ssh [email protected]
sudo -v

If you can log in and sudo -v asks for a password, wheel membership is working. Keep the root session open until this passes.

Update packages, time sync, and host identity

Run these as VPS as root to start from a current base and avoid time-related certificate problems later.

dnf -y update
dnf -y install chrony firewalld policycoreutils-python-utils nginx certbot python3-certbot-nginx git curl
systemctl enable --now chronyd
systemctl enable --now firewalld

chronyd keeps the clock accurate for TLS and logs. firewalld will manage the network policy for the web service.

hostnamectl set-hostname claw.example.com
hostnamectl status

Set the real hostname you want the server to present in logs and prompts. Confirm the new hostname appears in the status output.

Install and place OpenClaw

Because OpenClaw packaging can vary by release channel, this guide uses a local application directory and a service wrapper. Replace the repository URL or binary source with the package you actually received from the project maintainer.

mkdir -p /opt/openclaw
chown -R deploy:deploy /opt/openclaw

Run this as root so the application directory exists before you place files in it. Ownership is assigned to the sudo user so later edits do not require root.

Now switch to the named sudo user for the remaining application work.

su - deploy
cd /opt/openclaw

As VPS as the named sudo user, create an environment file for the app. Use a dedicated secret and keep it private.

nano /opt/openclaw/openclaw.env

Put the following content in the file:

OPENCLAW_HOST=127.0.0.1
OPENCLAW_PORT=8088
OPENCLAW_BASE_URL=https://claw.example.com
OPENCLAW_SECRET_KEY=replace-with-a-long-random-string

Save and exit, then lock down the file:

chmod 600 /opt/openclaw/openclaw.env

That keeps other users from reading the secret key.

Next, add the application binary or source tree to /opt/openclaw. If your upstream project uses Git, clone it here. If it ships as a tarball or binary release, unpack it here. After installation, confirm the expected entry point exists, for example:

ls -la /opt/openclaw
./openclaw --version

Replace ./openclaw --version with the exact version check supplied by your package. The goal is to confirm you have a runnable build before you wire it into systemd.

Create the systemd service

Back as VPS as root, create a dedicated service file so OpenClaw starts on boot.

exit
nano /etc/systemd/system/openclaw.service

Use this service definition, adjusting the ExecStart line to match your actual OpenClaw binary:

[Unit]
Description=OpenClaw private AI service
After=network-online.target
Wants=network-online.target

[Service]
User=deploy
Group=deploy
WorkingDirectory=/opt/openclaw
EnvironmentFile=/opt/openclaw/openclaw.env
ExecStart=/opt/openclaw/openclaw --host 127.0.0.1 --port 8088
Restart=on-failure
RestartSec=5
NoNewPrivileges=true
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Save the file, then validate and start it only after the syntax is in place:

systemd-analyze verify /etc/systemd/system/openclaw.service
systemctl daemon-reload
systemctl enable --now openclaw.service
systemctl status openclaw.service --no-pager

The verification step catches bad unit syntax before reload. The status output should show the service as active. If it fails, check the journal first:

journalctl -u openclaw.service -n 50 --no-pager

Look for a missing binary, a bad environment file path, or the wrong command-line flag. Fix the file and repeat the reload and start steps.

Open the firewall and add Nginx reverse proxy

Open only the ports required for web traffic and SSH.

firewall-cmd --permanent --add-service=ssh
firewall-cmd --permanent --add-service=http
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
firewall-cmd --list-all

The list output should show SSH, HTTP, and HTTPS as allowed.

Now create the Nginx site file as root:

nano /etc/nginx/conf.d/openclaw.conf

Use this server block:

server {
    listen 80;
    server_name claw.example.com;

    location / {
        proxy_pass http://127.0.0.1:8088;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Save it, then test the Nginx syntax before reloading:

nginx -t
systemctl reload nginx
systemctl enable --now nginx

If nginx -t reports an error, fix the file before you reload. That keeps a bad configuration from taking the site offline.

Issue the TLS certificate

With DNS pointing at the server and port 80 reachable, request a certificate:

certbot --nginx -d claw.example.com

Follow the prompts, choose the redirect option when offered, and confirm that Certbot writes the HTTPS configuration into Nginx. Then test renewal logic:

certbot renew --dry-run

That dry run should complete without errors and proves the certificate automation is working.

Verify the service end to end

Check the local listener on the server first:

ss -ltnp | grep -E '(:8088|:80|:443)'
curl -I http://127.0.0.1:8088
curl -I https://claw.example.com

You should see the app listening on 127.0.0.1:8088, then a valid HTTP response from the local service and the public HTTPS URL. If the proxy returns a 502, inspect both services:

systemctl status openclaw.service --no-pager
systemctl status nginx --no-pager
journalctl -u nginx -n 50 --no-pager
journalctl -u openclaw.service -n 50 --no-pager

For reboot persistence, run:

reboot

After the server comes back, reconnect from your local computer and confirm the service still starts:

ssh [email protected]
systemctl is-enabled openclaw.service
systemctl is-active openclaw.service

Finally, open the site in a browser and confirm the TLS certificate shows as trusted. That is the client-side smoke test.

Rollback and cleanup

If you need to back out the deployment, stop the service first, then remove the proxy and firewall changes in that order:

systemctl disable --now openclaw.service
rm -f /etc/systemd/system/openclaw.service
systemctl daemon-reload
rm -f /etc/nginx/conf.d/openclaw.conf
nginx -t && systemctl reload nginx
certbot delete --cert-name claw.example.com

Only remove the certificate after you have confirmed the site is no longer needed. That keeps the rollback safe and reversible.

Ubuntu and Debian

If you are using Ubuntu or Debian instead of AlmaLinux or Rocky Linux, keep the same deployment model but switch to apt, the sudo group, and UFW. After logging in as root, run cat /etc/os-release first, then use:

apt update
apt -y upgrade
apt -y install chrony ufw nginx certbot python3-certbot-nginx git curl
systemctl enable --now chrony
systemctl enable --now ufw

Create the admin user with usermod -aG sudo deploy, place keys in /home/deploy/.ssh/authorized_keys, and test sudo -v from a second terminal before changing root login rules. For the firewall, use ufw allow OpenSSH, ufw allow 80/tcp, ufw allow 443/tcp, then ufw enable and ufw status verbose. The Nginx, Certbot, systemd, and verification steps are the same, but package names and firewall commands differ.

Troubleshooting checks that matter

  • SSH login fails: run ls -ld /home/deploy /home/deploy/.ssh /home/deploy/.ssh/authorized_keys and correct ownership or permissions with chown and chmod 700/chmod 600.
  • Service will not start: run journalctl -u openclaw.service -n 100 --no-pager and correct the binary path, port, or environment file value.
  • Nginx returns 502: run curl -I http://127.0.0.1:8088; if that fails, OpenClaw is not listening or is listening on a different port.
  • TLS issuance fails: confirm DNS points to the server and ports 80 and 443 are open before rerunning Certbot.

Need dedicated infrastructure for a private AI service? Start with a HostnExtra dedicated server and build the rest of the stack around full root access and predictable performance.

View HostnExtra dedicated servers

Related HostnExtra guides

FAQ

Do I need a dedicated server for OpenClaw self-hosting?
For a private production deployment, yes. A dedicated server gives you full root access, storage control, and predictable network resources.

Can I skip Nginx and run the app directly on HTTPS?
You can, but a reverse proxy keeps TLS, headers, and future maintenance simpler.

What should I test after a reboot?
Check the service status, local port listener, HTTPS response, and browser certificate trust.