This directory installs the Axichat self-host stack on your Debian server.
The main entry point is install.sh in the repo root.
You should not need prior ejabberd or Stalwart knowledge; the script pauses and tells you exactly what to do.
ejabberd/README.md and stalwart/README.md are advanced/manual documents for troubleshooting.
- be independent
- have full control over your own email server
- provide a secure, private way to talk with family and friends
- avoid hosted storage limits
- avoid hosted rate limits
- control your own data
- use your own domain for all your email and XMPP messages
We highly recommend watching this tutorial before you start:
We have found Netcup great for email hosting because it is one of the few VPS providers that allows port 25 and has been reliable for us. If you want a voucher, open a GitHub issue or email voucher@axi.chat with the product you want.
- Debian host with
sudoor root access - a domain that already points to the server
- control over your provider firewall / security group
- no other service already using the required ports
Ports you always need available:
80/tcp5222/tcp,5223/tcp,5269/tcp,5443/tcp3478/udp
Extra ports if you are not using --no-email:
25/tcp,465/tcp,587/tcp,993/tcp,8443/tcp
The installer does not do generic SSH hardening or baseline server-security setup. If UFW is already active on the server, it adds only the app-specific UFW rules for this stack. If UFW is inactive or not installed, open the required ports yourself in your provider firewall or host firewall. The installer still sets up the local ejabberd ACME port-80 forwarder itself, because that is part of the app stack rather than general firewall policy.
If you leave email enabled, the following must be done separately from the script:
- Stalwart Webadmin over an SSH tunnel
- copying DNS records from Webadmin into your DNS provider
- setting PTR / reverse DNS with your host or provider
PTR / reverse DNS is usually set in your VPS or hosting provider panel, not in your normal DNS zone editor.
- Get this repo onto the server and enter the
selfhostdirectory.
On the server, run:
curl -L https://gitlab.com/axichat/selfhost/-/archive/main/selfhost-main.tar.gz | tar -xzf -cd selfhost-mainIf you already have the repo on your laptop and want to upload it manually instead:
scp -r ./selfhost root@YOUR_SERVER_IP:~ssh root@YOUR_SERVER_IPcd ~/selfhost- Choose one of these entry points.
If you want all capabilities (chat and email):
sudo bash ./install.sh install --domain example.com --public-token your-shared-tokenChoose your own public token. Everyone that uses your server will need to enter it into their Axichat clients, so it should be something you can remember and distribute. It is not a secret.
If you do not want email:
sudo bash ./install.sh install --domain example.com --no-email- Follow the guided checkpoints.
When the installer needs something off-server, it prints the exact steps and then waits for you in the same terminal. In the normal flow, you do not need to open the component READMEs.
If the script gets interrupted, rerun the same install command and it will continue from the saved phase.
Typical email checkpoints:
- create the Stalwart domain in Webadmin
- create the
email-glueStalwart API key - copy DNS records from Webadmin into your DNS provider
- configure PTR / reverse DNS in your hosting provider panel
For the normal guided setup, use your apex domain itself as the mail host. You do not need mail.example.com records unless you intentionally want a separate mail hostname.
sudo bash ./install.sh verifysudo bash ./install.sh doctorverify checks the local services and health endpoints. doctor adds higher-level checks and uses dig for DNS checks when it is available.
For normal installs (without --no-email), doctor checks not just that MX/PTR records exist, but that MX points at your configured mail domain and PTR points back to the same domain.
For normal installs (without --no-email), verify is the immediate local check and doctor is the better follow-up after DNS and PTR have propagated.
If you later pull a newer version of this repo and want to re-run the installed services with the same saved config, use:
sudo bash ./install.sh upgradeupgrade re-runs the saved app/service configuration. It does not restart the install from scratch.
If you use fpush, keep /opt/fpush/settings.json and the APNS .p12 file it references in place before running upgrade. That is what lets the rerun stay non-interactive.
To view the current public token later:
sudo bash ./install.sh public-token showTo change it without reinstalling:
sudo bash ./install.sh public-token set new-shared-tokenpublic-token show prints the saved token the clients should enter.
public-token set updates the saved wrapper config, syncs email-glue, and restarts email-glue when it is already installed.
If the install is still paused mid-flow, set updates the saved config so the next rerun uses the new token.
To reset a demo box and try again from a clean local state, run:
sudo bash ./uninstall.sh --yesThat removes the locally installed stack and then prints the manual DNS / PTR cleanup steps you still need to do off-server.
It removes the installed app stack, not the whole server history. By default it asks whether to purge ejabberd ACME certificate state.
Choose no if you want demo reruns to reuse the existing ACME state and avoid new TLS issuance.
Choose yes, or pass --purge-certs, if you want full certificate cleanup.
For the full flag list, run:
bash ./uninstall.sh helpIf you rerun the same install command after an interruption, the wrapper continues from the saved phase instead of starting over.
ejabberd/README.md: advanced/manual ejabberd path, fpush notes, and ejabberd-specific promptsstalwart/README.md: advanced/manual Stalwart path, Webadmin/API-key flow, direct script flags, and email-specific verification
Most users should only need those READMEs for troubleshooting, manual recovery, or direct component debugging.
- mailbox quota is unlimited
- ejabberd upload limits are large
- message history is kept by default
- normal installs require a user-chosen public client token
