What You'll End Up With
By the end of this guide you'll have Valkey 7.2 running as a systemd service on Ubuntu 24.04, with AOF persistence enabled, a password-protected TCP socket, and a verified connection from a client application. Valkey is a community-driven fork of Redis created after Redis Ltd. changed Redis 7.4 to a non-OSS license. It's API-compatible with Redis, so your existing redis-cli, client libraries, and RESP commands work without modification.
Prerequisites
- Ubuntu 24.04 LTS VPS (1 vCPU, 1 GB RAM minimum — a Hetzner CX11 at ~$4–6/month works fine)
- A non-root sudo user
- SSH access to the server
- Basic familiarity with
systemdandufw
1. Update the System and Install Build Dependencies
Valkey isn't in Ubuntu 24.04's default apt repos yet, so you'll build from source. First, pull in a clean package index and install the tools you need.
Step 1. Update apt and install dependencies.
sudo apt update && sudo apt upgrade -y
sudo apt install -y build-essential tcl pkg-config libssl-dev wget
This installs GCC, make, the TCL interpreter (used by Valkey's test suite), and OpenSSL headers for TLS support.
2. Download and Compile Valkey 7.2
Step 2. Download the Valkey 7.2.5 source tarball.
wget https://github.com/valkey-io/valkey/archive/refs/tags/7.2.5.tar.gz -O /tmp/valkey-7.2.5.tar.gz
Step 3. Extract the archive.
tar -xzf /tmp/valkey-7.2.5.tar.gz -C /tmp
Step 4. Compile with TLS support enabled.
cd /tmp/valkey-7.2.5
make BUILD_TLS=yes -j$(nproc)
Expected output (last two lines):
Hint: It's a good idea to run 'make test' ...
Make succeeded
Compilation takes 2–4 minutes on a single-core VPS.
Step 5. Install the binaries to /usr/local/bin.
sudo make install PREFIX=/usr/local
This places valkey-server, valkey-cli, valkey-benchmark, and companion binaries under /usr/local/bin/.
3. Create a Dedicated System User and Directories
Never run Valkey as root. Create a locked-down system account and the directories it owns.
Step 6. Create the valkey system user.
sudo useradd --system --no-create-home --shell /bin/false valkey
Step 7. Create the data and config directories.
sudo mkdir -p /etc/valkey /var/lib/valkey /var/log/valkey
sudo chown valkey:valkey /var/lib/valkey /var/log/valkey
sudo chmod 750 /var/lib/valkey /var/log/valkey
/var/lib/valkey is where AOF and RDB snapshot files will live. /var/log/valkey holds the server log.
4. Write the Valkey Configuration File
Step 8. Create /etc/valkey/valkey.conf.
sudo tee /etc/valkey/valkey.conf > /dev/null << 'EOF'
# Network
bind 127.0.0.1
port 6379
protected-mode yes
# Authentication — change this password
requirepass CHANGE_THIS_STRONG_PASSWORD
# Persistence: AOF (append-only file)
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
# RDB snapshot as a safety net
save 900 1
save 300 10
save 60 10000
# Directories
dir /var/lib/valkey
logfile /var/log/valkey/valkey.log
# Memory limit — tune to ~70% of your RAM
maxmemory 700mb
maxmemory-policy allkeys-lru
# Disable dangerous commands
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
EOF
Replace CHANGE_THIS_STRONG_PASSWORD with a real password (32+ random characters). The rename-command directives disable destructive commands so a compromised app can't wipe your data.
Step 9. Lock down the config file permissions.
sudo chown root:valkey /etc/valkey/valkey.conf
sudo chmod 640 /etc/valkey/valkey.conf
5. Create the systemd Service Unit
Step 10. Write the unit file.
sudo tee /etc/systemd/system/valkey.service > /dev/null << 'EOF'
[Unit]
Description=Valkey In-Memory Data Store
After=network.target
[Service]
Type=notify
User=valkey
Group=valkey
ExecStart=/usr/local/bin/valkey-server /etc/valkey/valkey.conf --supervised systemd
ExecStop=/usr/local/bin/valkey-cli -a CHANGE_THIS_STRONG_PASSWORD shutdown nosave
Restart=on-failure
RestartSec=5s
LimitNOFILE=65535
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ReadWritePaths=/var/lib/valkey /var/log/valkey
[Install]
WantedBy=multi-user.target
EOF
Replace CHANGE_THIS_STRONG_PASSWORD in ExecStop with the same password you set in valkey.conf. The ProtectSystem=strict and NoNewPrivileges directives sandbox the process at the kernel level.
Step 11. Reload systemd, enable, and start Valkey.
sudo systemctl daemon-reload
sudo systemctl enable --now valkey
Expected output:
Created symlink /etc/systemd/system/multi-user.target.wants/valkey.service ...
6. Harden the Firewall
Valkey is bound to 127.0.0.1 so it's not reachable from the internet by default. Keep it that way — expose it only to localhost or a private network interface.
Step 12. Allow SSH and deny everything else inbound.
sudo ufw allow OpenSSH
sudo ufw --force enable
If you have multiple VPS nodes on a Hetzner private network and need to reach Valkey from another host, add a rule scoped to that interface:
sudo ufw allow in on eth1 to any port 6379
Replace eth1 with your private network interface name (check with ip link show).
7. Verify It Works
Step 13. Check the service status.
sudo systemctl status valkey
Expected output (truncated):
● valkey.service - Valkey In-Memory Data Store
Loaded: loaded (/etc/systemd/system/valkey.service; enabled)
Active: active (running) since ...
Step 14. Authenticate with valkey-cli and run a ping.
valkey-cli -a CHANGE_THIS_STRONG_PASSWORD ping
Expected output:
PONG
Step 15. Write and read a test key.
valkey-cli -a CHANGE_THIS_STRONG_PASSWORD set test:hello "world"
valkey-cli -a CHANGE_THIS_STRONG_PASSWORD get test:hello
Expected output:
OK
"world"
Step 16. Confirm AOF persistence is active.
valkey-cli -a CHANGE_THIS_STRONG_PASSWORD info persistence | grep aof_enabled
Expected output:
aof_enabled:1
Step 17. Check the AOF file exists on disk.
sudo ls -lh /var/lib/valkey/appendonly.aof
You should see a non-zero file. If the file isn't there yet, write a few more keys — Valkey flushes to disk every second with appendfsync everysec.
Step 18. Confirm your existing Redis client library connects. Here's a Node.js example using ioredis:
// test-valkey.js
const Redis = require('ioredis');
const client = new Redis({
host: '127.0.0.1',
port: 6379,
password: 'CHANGE_THIS_STRONG_PASSWORD',
});
client.ping().then((res) => {
console.log(res); // PONG
client.disconnect();
});
node test-valkey.js
Expected output:
PONG
The same pattern applies to Python (redis-py), Ruby (redis-rb), Go (go-redis), and PHP (predis) — no library changes needed.
Troubleshooting
Service fails to start — "Permission denied" on log file
Run sudo chown -R valkey:valkey /var/log/valkey and sudo systemctl restart valkey.
NOAUTH Authentication required error
You're connecting without -a. Always pass -a YOUR_PASSWORD to valkey-cli, or set the REDISCLI_AUTH environment variable: export REDISCLI_AUTH=CHANGE_THIS_STRONG_PASSWORD.
Address already in use on port 6379
Another process (possibly a leftover Redis install) is holding the port. Find it with sudo ss -tlnp | grep 6379 and stop it before starting Valkey.
AOF file not being written
Verify appendonly yes is in /etc/valkey/valkey.conf and that the valkey user owns /var/lib/valkey. Check sudo journalctl -u valkey -n 50 for write errors.
High memory usage eating into system RAM
Lower maxmemory in /etc/valkey/valkey.conf and restart the service. On a 1 GB VPS, 512mb is a safer ceiling if you're running other processes.
make fails with missing cc
Run sudo apt install -y gcc — the build-essential meta-package sometimes misses this on minimal cloud images.
Valkey restarts loop in systemd
Run sudo journalctl -u valkey --since "5 minutes ago" to read the exact error. Common causes: wrong path in ExecStart, config file syntax error, or the valkey user lacking read permission on /etc/valkey/valkey.conf.
Next Steps
- Enable TLS between your app and Valkey: generate a self-signed cert with
openssl req -x509 -newkey rsa:4096 -keyout /etc/valkey/valkey.key -out /etc/valkey/valkey.crt -days 365 -nodesand addtls-port 6380,tls-cert-file, andtls-key-filedirectives tovalkey.conf. - Set up Valkey Sentinel for automatic failover if you add a second VPS — Valkey Sentinel is protocol-compatible with Redis Sentinel, so existing tooling works.
- Monitor with Prometheus: the
redis_exporterby Oliver006 works against Valkey without modification. Point it at127.0.0.1:6379with your password and scrape the/metricsendpoint. - Automate backups: add a daily cron that copies
/var/lib/valkey/appendonly.aofto an S3-compatible bucket (Hetzner Object Storage is $0.023/GB) usingrclone.
Running Valkey instead of a managed Redis service saves $15–$30/month on a typical indie project — that's your Hetzner VPS bill covered twice over. The Redis compatibility means zero migration cost from any existing stack.