Installing ClickHouse on Ubuntu/Debian: A Step-by-Step Guide from Someone Who Got Burned by Wrong Permissions
Three Mistakes I Made During My First Installation
The first time I installed ClickHouse on production, I thought, "What's so hard about it — just apt install." Result: ports were closed, logs weren't being written, and after 15 minutes the server crashed because I forgot to configure max_server_memory_usage. Second attempt: I confused the official repository with a shady PPA. Third: I didn't set ulimit -n, and ClickHouse simply couldn't open enough file descriptors.
So below is not just a copy of the documentation, but a guide where I highlight all the pitfalls. All commands have been tested on a clean Ubuntu 22.04 LTS and Debian 12.
Step 1. Add the Official Repository (Don't Google Ready-Made Scripts)
The official documentation has a script curl https://clickhouse.com/ | sh. I wouldn't recommend using it on a server if you don't fully understand what it does. Better to do a manual installation via apt with key verification. This is a case where security is more important than speed.
# Add ClickHouse GPG key (package signature)
sudo apt-get install -y apt-transport-https ca-certificates curl gnupg
curl -fsSL 'https://packages.clickhouse.com/rpm/latest/repodata/repomd.xml.key' | sudo gpg --dearmor -o /usr/share/keyrings/clickhouse-keyring.gpg
# Add repository to apt sources
echo "deb [signed-by=/usr/share/keyrings/clickhouse-keyring.gpg] https://packages.clickhouse.com/deb stable main" | sudo tee /etc/apt/sources.list.d/clickhouse.list
# Update package list
sudo apt-get update
Why so complicated? Because without signature verification, you risk installing a package from an unofficial repository. In production, we had a case where a developer ran curl | sh and got an old version with a vulnerability. Don't repeat that.
Step 2. Install the Server and Client
# Install packages
sudo apt-get install -y clickhouse-server clickhouse-client
# If you want benchmarking utilities
sudo apt-get install -y clickhouse-common-static
During installation, you'll be asked for a password for the default user. Important note: If you leave it empty, no password will be set at all. In production, this is a disaster. Even for a dev environment, set a simple password like clickhouse_dev — it'll be easier to remember later.
After installation, you'll see:
ClickHouse server has been installed.
Configuration file: /etc/clickhouse-server/config.xml
Logs directory: /var/log/clickhouse-server/
Data directory: /var/lib/clickhouse/
Step 3. Check the Version — A Life Hack the Documentation Doesn't Mention
clickhouse-server --version
Expected output (at the time of writing):
ClickHouse server version 24.8.2.3 (official build).
Personal experience: After updating the ClickHouse version, the data storage format on disk sometimes changes. If you had an old version and ran apt upgrade, the system might fail to start with the error Unknown data type. Always run clickhouse-server --version before updating and read the changelog.
Step 4. Start via systemd — and Check You Didn't Forget Anything
# Enable auto-start on boot
sudo systemctl enable clickhouse-server
# Start the server now
sudo systemctl start clickhouse-server
# Check status
sudo systemctl status clickhouse-server
If everything is fine, you'll see:
● clickhouse-server.service - ClickHouse Server (analytic DBMS)
Loaded: loaded (/etc/systemd/system/clickhouse-server.service; enabled)
Active: active (running) since ...
Common mistake: The server doesn't start due to insufficient file descriptors. Check:
# View current limit for the service
cat /proc/$(pidof clickhouse-server)/limits | grep "open files"
# If less than 262144, add to /etc/systemd/system/clickhouse-server.service.d/override.conf
[Service]
LimitNOFILE=262144
LimitNPROC=32768
After making changes, don't forget:
sudo systemctl daemon-reload
sudo systemctl restart clickhouse-server
Step 5. First Login via clickhouse-client — and My Favorite Test
clickhouse-client --password
# Enter the password you set in step 2
If you didn't set a password, just:
clickhouse-client
The first query is always a version check:
SELECT version();
Output:
┌─version()─┐
│ 24.8.2.3 │
└───────────┘
Now you can be proud — ClickHouse is working.
Bonus performance test: Run this query — it will show how fast your machine can generate and process data:
SELECT sum(number) FROM numbers(100000000);
On a decent server (4+ cores), it will execute in 0.3-0.5 seconds. On a weak virtual machine — up to 2 seconds. If it's more than 5 seconds, you have CPU or throttling issues.
Step 6. Where Important Files Are Located — Memorize These Paths
| File/Directory | Purpose | What I Changed Most Often |
|---|---|---|
/etc/clickhouse-server/config.xml |
Main config | listen_host (to listen on more than just localhost), max_server_memory_usage, http_port |
/etc/clickhouse-server/users.xml |
User settings | password for default, readonly, quota |
/var/log/clickhouse-server/clickhouse-server.log |
Main log | When it doesn't start, check here first |
/var/log/clickhouse-server/clickhouse-server.err.log |
Error log | I catch memory and disk errors here |
/var/lib/clickhouse/ |
Table data | Check if the disk is full |
/var/lib/clickhouse/status |
PID and status | For monitoring scripts |
Real-world moment: Once, ClickHouse stopped accepting requests. Everything was running, but the console hung. It turned out the log file had grown to 80 GB and filled the root partition. Add rotation to the config:
<logger>
<size>1000M</size>
<count>10</count>
</logger>
Step 7. Minimal Configuration for Development
For a local machine or dev server, I use this config.xml (I only change what's critical):
<!-- /etc/clickhouse-server/config.d/dev-override.xml -->
<clickhouse>
<!-- Listen on all interfaces, not just localhost -->
<listen_host>0.0.0.0</listen_host>
<!-- Limit memory to avoid killing the laptop -->
<max_server_memory_usage>0.75</max_server_memory_usage> <!-- 75% of total RAM -->
<max_memory_usage_for_all_queries>0</max_memory_usage_for_all_queries>
<!-- Timeouts for dev environment -->
<keep_alive_timeout>3</keep_alive_timeout>
<!-- Avoid creating too many partitions on disk -->
<merge_tree>
<max_parts_in_total>1000</max_parts_in_total>
</merge_tree>
</clickhouse>
Apply:
sudo systemctl restart clickhouse-server
Why a separate file instead of editing config.xml? When the package is updated, config.xml may be overwritten. Put all custom changes in /etc/clickhouse-server/config.d/. I learned this from a downgrade after a failed update — I lost a week of settings.
Step 8. Open Ports for External Connections
ClickHouse listens on three ports:
- 8123 — HTTP (for REST API, Grafana, intuitive)
- 9000 — Native TCP protocol (for clickhouse-client and drivers)
- 9009 — Inter-server communication (for clusters, don't touch unnecessarily)
On a dev machine, I open at least 8123 to connect from TablePlus or DBeaver:
# Check if the process is listening
sudo netstat -tulpn | grep clickhouse
# If not, allow in UFW
sudo ufw allow 8123/tcp
sudo ufw allow 9000/tcp
Common mistake: On Ubuntu 22.04, the firewall may block by default even if ClickHouse listens on 0.0.0.0. Always check with telnet localhost 8123 and telnet $(hostname -I) 8123.
Typical Installation Problems and How I Solved Them
Problem 1: Code: 210. DB::NetException: Connection refused
Cause: The server didn't start or is only listening on 127.0.0.1.
Solution:
# Check status
systemctl status clickhouse-server
# View log
tail -n 50 /var/log/clickhouse-server/clickhouse-server.log
# Edit config
sudo nano /etc/clickhouse-server/config.xml
# Find <listen_host>0.0.0.0</listen_host> and uncomment
Problem 2: cannot create directory '/var/lib/clickhouse/' Permission denied
Cause: Permissions on the data directory were messed up after manual intervention.
Solution:
sudo chown -R clickhouse:clickhouse /var/lib/clickhouse
sudo chmod 755 /var/lib/clickhouse
Problem 3: Server starts but crashes after 30 seconds with Out of memory
Cause: ClickHouse by default wants to use almost all RAM.
Solution: In a dev environment, strictly limit memory:
# In /etc/clickhouse-server/config.xml add
<max_server_memory_usage>2147483648</max_server_memory_usage> # 2 GB
Or via system limit:
sudo systemctl edit clickhouse-server
# Add:
[Service]
MemoryMax=2G
Problem 4: Installation fails due to conflict with clickhouse-common-static
Cause: Remnants of a previous version or a broken apt cache.
Solution:
sudo apt-get remove --purge clickhouse-*
sudo rm -rf /etc/clickhouse-server /var/lib/clickhouse
sudo apt-get clean
# Repeat installation from the beginning
Health Check — My Personal Checklist
After installation, I always run three tests:
Local connection
clickhouse-client -q "SELECT 1" # Should return 1Remote HTTP connection (from another machine)
curl "http://YOUR_SERVER_IP:8123/?query=SELECT+version()"Data write
CREATE DATABASE test; CREATE TABLE test.t (id UInt64) ENGINE = MergeTree ORDER BY id; INSERT INTO test.t SELECT number FROM numbers(1000); SELECT count() FROM test.t;
If everything passes, the installation is successful.
What's Next?
Now you have a working ClickHouse on Ubuntu/Debian. The next step is to learn how to wrap it in Docker and set up a three-node cluster with replication.
➡️ Next article: [Installing ClickHouse via Docker: Production Cluster in 10 Minutes] (link coming)
⬅️ Previous article: [What is ClickHouse: Why Columnar DBMS Tear Analytics to Shreds] (link coming)
Good luck with the installation. If you get stuck, first check /var/log/clickhouse-server/clickhouse-server.err.log. That error has saved me more times than coffee on a Monday morning.
← Previous: ClickHouse: Why Columnar DBMS Tear Analytics to Shreds
→ Next: ClickHouse in Docker: How I Stopped Worrying and Launched Analytics in 2 Minutes
— Editorial Team
No comments yet.