2.9 KiB
2.9 KiB
ess-helm-nixos
NixOS configuration for hosting Element Server Suite Community on a single VPS using K3s, Helm, and NixOS-managed nginx as the TLS-terminating reverse proxy.
Architecture
Internet
|
v :80 / :443
NixOS nginx (TLS via Let's Encrypt / ACME)
|
v :30080 (plain HTTP)
K3s ingress-nginx
|
v ClusterIP
ESS Helm chart
├── Synapse ess-helm.de
├── MAS auth.ess-helm.de
├── Element Web chat.ess-helm.de
├── Element Admin admin.ess-helm.de
└── Matrix RTC SFU mrtc.ess-helm.de (:30001 TCP / :30002 UDP direct)
Matrix user IDs: @user:ess-helm.de
DNS setup
Create the following A records pointing to the VPS public IP:
| Record | Type | Value |
|---|---|---|
ess-helm.de |
A | <VPS public IP> |
auth.ess-helm.de |
A | <VPS public IP> |
chat.ess-helm.de |
A | <VPS public IP> |
admin.ess-helm.de |
A | <VPS public IP> |
mrtc.ess-helm.de |
A | <VPS public IP> |
Firewall
| Port | Protocol | Purpose |
|---|---|---|
| 80 | TCP | HTTP (ACME challenge + redirect to HTTPS) |
| 443 | TCP | HTTPS (all ESS services via nginx) |
| 30001 | TCP | Matrix RTC WebRTC TCP transport |
| 30002 | UDP | Matrix RTC WebRTC muxed UDP transport |
Verification
- Element Web: chat.ess-helm.de
- Federation tester: federationtester.matrix.org/?server_name=ess-helm.de
- Matrix client well-known: ess-helm.de/.well-known/matrix/client
Usage
# flake.nix
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs/nixos-25.11";
ess-helm.url = "github:sid/ess-helm";
ess-helm.inputs.nixpkgs.follows = "nixpkgs";
synix.url = "git+https://git.sid.ovh/sid/synix.git?ref=release-25.11";
synix.inputs.nixpkgs.follows = "nixpkgs";
};
outputs = { self, nixpkgs, ess-helm, synix, ... }: {
nixosConfigurations.my-server = nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
ess-helm.nixosModules.ess-helm
synix.nixosModules.nginx
./configuration.nix
];
};
};
}
# configuration.nix
{
services.ess-helm = {
enable = true;
serverName = "example.com";
openFirewall = true;
configureNginx = true;
};
security.acme.defaults.email = "admin@example.com";
services.nginx = {
enable = true;
openFirewall = true;
forceSSL = true;
};
}
Subdomains default to auth., chat., admin., mrtc.. Override individually if needed:
services.ess-helm.elementWeb.subdomain = "element"; # -> element.example.com
Upgrade the ESS or ingress-nginx chart version:
services.ess-helm.ess = {
version = "26.X.Y";
hash = "...";
};