# EasyNode: self-hosted web panel for SSH, SFTP and RDP across multiple Linux servers

> EasyNode is a self-hosted server management panel that delivers WebSSH, SFTP, RDP, credential storage, script libraries and batch command execution through a browser and a native iOS/Android app. It deploys via Docker Compose and uses NeDB for storage, with the maintainer explicitly warning against exposing it to the public internet.

**chaos-zhu/easynode** — A multi-functional Linux & Windows server web terminal panel (webSSH & webSFTP). Update notifications via Telegram.

- Repository: https://github.com/chaos-zhu/easynode
- Website: https://t.me/easynode_notify
- Stars: 2,016 · Forks: 275
- Language: Dart
- License: NOASSERTION
- Published: 2026-10-11 · Updated: 2026-10-11 · Language: en
- Canonical page: https://hysenlabs.com/projects/chaos-zhu-easynode

## EasyNode addresses multi-server Linux management from a single browser panel

Manage one server with SSH and you open a terminal. Manage twenty and you want a panel that holds every connection, handles file transfers, tracks credentials and lets you run the same command across all of them at once. EasyNode targets that problem. Its web interface covers SSH terminal sessions, SFTP file operations, RDP desktop access, a script library with reuse capabilities, a credential vault, and batch command execution across all registered servers at once. An AI agent component is also included, accessible from the same browser session or from the native mobile app.

The package.json describes it as a cross-platform Linux server management panel with WebSSH, SFTP, RDP, Docker, AI chat and batch operations. The native mobile app adds iOS and Android clients that reuse the same backend server, providing SSH, SFTP, Docker management and script library access from a phone or tablet.

The project first published in August 2022, per the repository's own declaration. Version v3.8.2 arrived on 2026-09-29, and the last push to the main branch was on 2026-10-01. The repository root contains AGENTS.md and AI-Agent.md alongside the main README, suggesting the AI agent component is documented separately from the main panel.

## The server runs on node:22.16-alpine3.20, with a guacd sidecar for RDP and Flutter for the mobile app

EasyNode's Dockerfile builds in three stages. The web interface is compiled first, then the Node.js server assembles using the compiled output, and the final image is based on node:22.16-alpine3.20. RDP support requires a guacd sidecar, named easynode-guacd in the docker-compose.yml. That sidecar listens on port 4822 and must pass a health check before the main container starts. Without it, the main service will not run.

The database is NeDB, a file-based JSON store. Persistence comes from mounting /root/easynode/db on the host to /easynode/app/db inside the container. NeDB is not designed for concurrent writes from multiple processes, and the maintenance documentation warns that running any script while the main container is active can overwrite or corrupt the database.

The native mobile app is built with Flutter and Dart, which explains why the repository's primary language reads as Dart. It has its own release track: v3.8.2 for the server panel and native-v1.3.1 for the mobile app both appeared on 2026-09-29, confirming that the server and the mobile app version independently.

## Three docker compose commands start the service at ports 8082 and 8092

The deploy steps in the README require creating the install directory, downloading the provided docker-compose.yml and starting the services:

```bash
mkdir -p /root/easynode && cd /root/easynode
wget https://git.221022.xyz/https://raw.githubusercontent.com/chaos-zhu/easynode/main/docker-compose.yml
docker compose up -d
```

Once running, the panel listens on port 8082 over HTTP and on port 8092 over HTTPS with a self-signed certificate. On first launch, an admin username and password are generated and printed to the terminal. Changing both immediately after the first login is important, because credentials left in terminal history or log files become a security exposure. A CHANGELOG.md sits at the repository root for tracking changes between releases.

The HTTP port at 8082 is described as for internal network access only. The HTTPS port at 8092 uses a self-signed certificate by default, which means browsers show a certificate warning that must be manually dismissed before the panel is reachable. For internal use, this is workable. For any external exposure, a valid certificate is required.

## ENABLE_HTTPS takes three values and COOKIE_SECURE defaults to false, passing session cookies over HTTP

Seven environment variables configure the access and security model. ENABLE_HTTPS is the most consequential: value 0 disables HTTPS, value 1 enables a self-signed certificate (the default), and value 2 uses a valid external certificate. When ENABLE_HTTPS is set to 2, both SSL_CERT_PATH and SSL_KEY_PATH must be provided.

COOKIE_SECURE defaults to false in the docker-compose.yml, which means session cookies travel over HTTP connections without the Secure flag. With COOKIE_SECURE=true, the session cookie carries the Secure flag so it is only sent over HTTPS connections, and logging in from an HTTP connection fails. For any deployment where the HTTP port might be reachable beyond the local network, this setting should be changed to true before the first login.

HTTP_PORT defaults to 8082, HTTPS_PORT to 8092 and RDP_PORT to 8083 in the docker-compose.yml, along with DEBUG defaulting to 1, which enables startup log output. IPv6 is off by default in Docker, and enabling it requires either adjusting Docker's network configuration for the easynode network or routing through a jump server that already supports IPv6.

## Running maintenance scripts while the easynode container is active corrupts the NeDB database

Three administrative maintenance scripts are included: reset-password.js to reset the admin credentials, remove-mfa.js to clear the TOTP key and remove-ip-whitelist.js to clear all IP access rules. Each requires the same sequence: stop the container, run the script, restart the container.

```bash
docker compose stop easynode
docker compose run --rm --no-deps easynode node scripts/reset-password.js
docker compose up -d easynode
```

If a script runs while the container is active, the NeDB file receives concurrent writes from two processes, and the result is either overwritten data or a corrupted database. The easynode container and the maintenance script cannot safely share the NeDB file, so the stop-run-restart sequence is not optional, and the documentation explicitly prohibits using docker exec to run these scripts against a live container.

The reset-password.js script prompts for y or Y before continuing. After confirmation, a new random admin username and password are printed to the terminal, and all active sessions become invalid. Running remove-ip-whitelist.js clears the entire whitelist, so after the container restarts every source IP can reach the panel without restriction. Reconfiguring the whitelist before reconnecting to the network is the required next step.

## Watchtower checks for image updates every five minutes and the native app tracks releases separately

The default docker-compose.yml includes a Watchtower container configured to poll for image updates on the schedule 0 */5 * * * *, which runs every five minutes. Only containers labeled with com.centurylinklabs.watchtower.enable=true receive automatic updates. In the default configuration, the easynode container carries that label and is updated automatically. The easynode-guacd sidecar carries com.centurylinklabs.watchtower.enable=false, keeping it pinned.

Automatic updates keep the panel current with security patches without operator action, but they also mean the image can change without a deliberate upgrade step. Operators who want control over when updates are applied should remove the Watchtower service from the docker-compose.yml and manage image pulls manually.

Three releases appeared between September 6 and September 29, 2026: v3.8.1 on 2026-09-06, v3.8.2 on 2026-09-29 and native-v1.3.1 on 2026-09-29. Security dependency upgrades happen on an unscheduled basis, and the docker-compose.yml's bundled Watchtower service automates that upgrade path by checking for new images every five minutes rather than requiring a manual pull.

## Wetty handles the terminal-only use case with far less infrastructure, while EasyNode adds scope and attack surface

Wetty is a browser-based SSH terminal that proxies SSH through a web interface. It provides a terminal and nothing else, runs as a single process and requires no sidecar or database. Teams that need only browser-based SSH access face much less infrastructure complexity with Wetty than with EasyNode's Docker Compose stack, which includes the main container, the guacd sidecar, Watchtower and a mounted database volume.

EasyNode's additional scope, covering SFTP, RDP, credential storage, batch operations and a mobile app, is the reason to choose it over a terminal-only tool. That scope also expands the attack surface. The README states that all SSH connections and monitoring data pass through the EasyNode server as a relay. A compromised panel instance therefore reaches every server registered in the credential vault. Where some external access is unavoidable, routing through OpenVPN or TailScale is the approach the documentation names, rather than opening ports 8082 or 8092 to the internet.

The licence is a custom text. GitHub cannot classify it and shows Other. The package.json field lists ISC, but that does not change the actual LICENSE file. Anyone considering redistribution or modification must read the LICENSE file directly.

## Conclusion

EasyNode suits engineers managing several Linux servers who want SSH, SFTP, RDP, batch operations and credential storage from a browser panel on an internal network. It is the wrong choice when the panel must be internet-facing: the maintainer's documentation explicitly warns against public deployment. Before deploying, read the LICENSE file (GitHub classifies it as Other; package.json lists ISC, which do not match), set ENABLE_HTTPS=2 with valid paths in SSL_CERT_PATH and SSL_KEY_PATH, and configure an IP whitelist to restrict access to port 8092.

## FAQ

### How do I reset the EasyNode admin password?

Stop the main container, run the reset-password.js maintenance script and then restart the container. The script prompts for confirmation before generating a new random username and password and invalidating all existing login sessions. This process only works with a Docker Compose deployment.

### Is EasyNode safe to expose to the public internet?

The README explicitly warns against exposing the panel to the public internet, because all SSH connections and monitoring traffic pass through the EasyNode server as a relay. If remote access is required, the README suggests routing through a VPN such as OpenVPN or TailScale instead of opening the panel ports directly.

### What database does EasyNode use?

EasyNode uses NeDB, a file-based JSON store. Data is persisted by mounting /root/easynode/db on the host into /easynode/app/db inside the container. Running maintenance scripts while the container is active can corrupt the database.

### What ports does EasyNode use?

The HTTP port is 8082 (for internal network access only) and the HTTPS port is 8092 (default self-signed certificate). RDP runs on port 8083 and the guacd sidecar uses port 4822, both configured in the docker-compose.yml.

### Does EasyNode have a mobile app?

A native mobile app built with Flutter is included in the repository. It supports iOS and Android and reuses the existing EasyNode backend, providing SSH, SFTP, Docker management and script library access. The mobile app has its own release track, separate from the server panel.

## Sources

- [chaos-zhu/easynode on GitHub](https://github.com/chaos-zhu/easynode)
- [Issues](https://github.com/chaos-zhu/easynode/issues)
- [Project website](https://t.me/easynode_notify)
- [README](https://github.com/chaos-zhu/easynode/blob/main/README.md)
- [Releases](https://github.com/chaos-zhu/easynode/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/chaos-zhu-easynode
