ehiniumChat is a lightweight, private group chat system designed for Linux servers. It uses only system packages, stores data in SQLite, and provides a clean Telegram-like UI with realtime messaging.
This project is intentionally simple, auditable, and self-hosted.
- Private login (no public signup)
- User-defined groups and memberships
- Realtime messaging via WebSocket
- Message pagination (loads latest 10, loads older on scroll)
- Unread message dots and counters
- Group info panel (members + last seen)
- File upload with image preview
- Mobile responsive UI
- SQLite database (single file)
- No external services, no pip, no npm
- Linux server (Ubuntu recommended, any version)
- Root or sudo access
- Ability to install packages using
apt - Optional: domain + CDN (for HTTPS on client side)
Used system packages only:
python3python3-aiohttp
If your server is Iran-access (زمان قطعی اینترنت):
Public resolvers like 8.8.8.8 or 1.1.1.1 usually do not work.
Make sure your server:
- Uses datacenter-provided DNS, or
- Uses Iranian DNS resolvers
Default Ubuntu mirrors may fail.
Recommended tools to switch mirrors automatically:
https://github.com/mexenon/syshelper
https://github.com/GeeDook/mirava
After fixing mirrors:
sudo apt updateIf GitHub is blocked, download the packaged file from this mirror:
https://uploadkon.ir/uploads/3cfb13_26ehiniumChat-tar.gzsudo apt update
sudo apt install -y python3 python3-aiohttpsudo mkdir -p /opt/ehiniumChat/uploadsOption A: using GitHub:
git clone https://github.com/ehinium/ehiniumChat.git
sudo mkdir -p /opt/ehiniumChat
sudo cp -a ehiniumChat/* /opt/ehiniumChat/Option B: using the Iranian mirror:
wget https://uploadkon.ir/uploads/3cfb13_26ehiniumChat-tar.gz
sudo tar -xzf ehiniumChat-tar.gz -C /Ensure files exist:
ls /opt/ehiniumChatMake executable:
sudo chmod +x /opt/ehiniumChat/app.py
sudo chmod +x /opt/ehiniumChat/admin_cli.py || trueThis key signs login cookies.
Generate:
python3 - <<'PY'
import secrets
print(secrets.token_hex(32))
PYCreate file:
sudo nano /opt/ehiniumChat/secret.keyPaste the generated hex string and save.
sudo python3 /opt/ehiniumChat/app.pyApp starts on:
http://0.0.0.0:8080
Open in browser:
http://SERVER_IP:8080
Stop with Ctrl+C after confirming it works.
sudo nano /etc/systemd/system/ehiniumchat.servicePaste:
[Unit]
Description=ehiniumChat (aiohttp + sqlite)
After=network.target
[Service]
Type=simple
WorkingDirectory=/opt/ehiniumChat
ExecStart=/usr/bin/python3 /opt/ehiniumChat/app.py
Restart=always
RestartSec=2
User=root
Environment=PYTHONUNBUFFERED=1
[Install]
WantedBy=multi-user.targetsudo systemctl daemon-reload
sudo systemctl enable ehiniumchat
sudo systemctl restart ehiniumchat
sudo systemctl status ehiniumchat --no-pagerLogs:
sudo journalctl -u ehiniumchat -n 200 --no-pagerCommon setup:
Browser to CDN is HTTPS, CDN to server is HTTP.
Requirements:
- CDN must support WebSocket proxying
- Paths:
- UI: /chat
- WebSocket: /ws
- Uploads: /uploads/
If CDN terminates HTTPS, browser uses wss automatically.
If admin_cli.py is present:
List users:
sudo /opt/ehiniumChat/admin_cli.py list-usersAdd user (default password = username123):
sudo /opt/ehiniumChat/admin_cli.py add-user aliSet password:
sudo /opt/ehiniumChat/admin_cli.py set-pass ali NewPasswordAdd group:
sudo /opt/ehiniumChat/admin_cli.py add-group "My Group"Add member to group:
sudo /opt/ehiniumChat/admin_cli.py add-member "My Group" aliRename group:
sudo /opt/ehiniumChat/admin_cli.py rename-group "Old Name" "New Name"On old server:
sudo systemctl stop ehiniumchat
sudo tar -czf /root/ehiniumChat_backup.tgz -C /opt ehiniumChatCopy archive to new server and extract:
sudo tar -xzf ehiniumChat_backup.tgz -C /Reinstall packages and start service.
To give the software without your users/messages:
sudo tar -czf ehiniumChat_clean.tgz \
/opt/ehiniumChat/app.py \
/opt/ehiniumChat/admin_cli.pyDo not share:
- ehiniumchat.db
- uploads/
- secret.key
Recipient must create their own secret.key.
- ISP cannot read messages if client to CDN is HTTPS
- CDN can read messages if origin is HTTP
- Datacenter network can read messages if origin is HTTP
- Messages are stored in plaintext in SQLite
- Passwords are stored in plaintext (by design)
This system is suitable for private groups and internal teams.
It is not end-to-end encrypted.