Installation
Docker
Image: ghcr.io/wangwanjie/gately, available for amd64, arm64 and arm/v7.
docker run -d --name gately --network host --cap-add NET_ADMIN \
-v ./gately-data:/etc/gately \
-v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/wangwanjie/gately:latestDocker Compose
services:
gately:
image: ghcr.io/wangwanjie/gately:latest
container_name: gately
restart: unless-stopped
# Port forwarding, STUN traversal and web services all listen on host ports directly
network_mode: host
# Intrusion Prevention writes bans to the host firewall (remove if not needed)
cap_add:
- NET_ADMIN
volumes:
# Config directory (plain JSON, safe to keep in git; ssl.json contains certificate private keys)
- ./data:/etc/gately
# Docker management (remove if not needed)
- /var/run/docker.sock:/var/run/docker.sock
environment:
- TZ=Asia/Shanghai--cap-add NET_ADMIN and cap_add let Intrusion Prevention write bans to the host's nftables firewall. You can drop them; bans then still apply to Gately's own services.
The image ships with sh, bash and curl, so typical notification scripts run out of the box.
Binary
- Get the archive for your platform from the download page: Linux (amd64 / arm64 / arm / mips / mipsle / riscv64), macOS, Windows or FreeBSD.
- Extract it and run:
./gately -c /etc/gatelysystemd
The repository ships a complete service file, deploy/systemd/gately.service, which already grants the capability needed to listen on low ports:
sudo install -m 0755 gately /usr/local/bin/gately
sudo install -m 0644 gately.service /etc/systemd/system/gately.service
sudo systemctl daemon-reload && sudo systemctl enable --now gatelyOpenWrt
Every release ships OpenWrt packages that contain the binary, the procd init script and a rule that keeps your config across firmware upgrades:
- OpenWrt 24.10 and earlier (including iStoreOS and other 24.10-based firmware) use the
.ipk, installed withopkg install; - OpenWrt 25.12 and later use the
.apk, installed withapk add --allow-untrusted(the packages are unsigned, so--allow-untrustedis required).
Run grep DISTRIB_ARCH /etc/openwrt_release to find the device architecture, then pick the package from the OpenWrt group on the download page:
| DISTRIB_ARCH | Package |
|---|---|
x86_64 | gately_<version>_openwrt_amd64 |
aarch64_* | gately_<version>_openwrt_arm64 |
arm_cortex-a*_* (ARMv7 with VFP / NEON) | gately_<version>_openwrt_arm |
mipsel_* | gately_<version>_openwrt_mipsle |
mips_* | gately_<version>_openwrt_mips |
riscv64_* | gately_<version>_openwrt_riscv64 |
cd /tmp
# OpenWrt 24.10 / iStoreOS (x86_64 shown)
opkg install ./gately_<version>_openwrt_amd64.ipk
# OpenWrt 25.12
apk add --allow-untrusted ./gately_<version>_openwrt_amd64.apk- The service is enabled at boot and started right after install; the admin UI is at
http://<router address>:16680. Config lives in/etc/gatelyand is kept across firmware upgrades (sysupgrade); - Upgrade: download the newer package and run
opkg installorapk add --allow-untrustedagain; your config is kept. If you disabled the service at boot, it stays disabled after the upgrade; - Uninstall:
opkg remove gatelyorapk del gately. The config directory is kept; runrm -rf /etc/gatelyto remove it as well; - The device architecture is checked before install. opkg aborts when the architecture does not match; the apk in OpenWrt 25.12 still installs the package but leaves the service stopped, so run
apk del gatelyand install the right package; - The binary is about 35 MB and needs the same amount of free space (check with
df -h /overlay), which suits x86 soft routers, ARM64 boxes and other devices with ample storage; routers with 16 MB / 32 MB of flash are too small; - The arm package needs ARMv7 with hardware floating point. ARMv5 / ARMv6 devices and FPU-less cores such as
arm_cortex-a9are not supported yet.
You can also deploy manually: download the Linux archive and use the procd init script deploy/openwrt/gately.init:
cp gately /usr/bin/gately && chmod +x /usr/bin/gately
cp gately.init /etc/init.d/gately && chmod +x /etc/init.d/gately
/etc/init.d/gately enable && /etc/init.d/gately startfnOS native app
Every release ships offline packages for fnOS: gately_<version>_fnos_x86.fpk (Intel / AMD) and gately_<version>_fnos_arm.fpk (ARM). They are not listed in the official App Center, so install them manually:
- Get the
.fpkfor your device's architecture from the download page; - In fnOS, open "App Center → Manual install" (the button at the bottom-left), pick the file and finish the wizard;
- Click the Gately icon on the fnOS desktop to open the admin UI.
Works with the fnOS unified gateway
The desktop icon opens the admin UI through the fnOS unified gateway at /app/gately/ on the address you use for fnOS, sharing the same entry point. Both the LAN address and your remote fnOS domain work, with no need to open or forward port 16680.
Access through the gateway is controlled by fnOS, and only fnOS administrators can open it. The secure entrance path and "LAN-only access" apply only to direct access on port 16680. On the LAN, http://<NAS address>:16680 still works.
Sign in with your fnOS administrator session
Turn on "Sign in with fnOS" under "Settings → Access control" and administrators who are signed in to fnOS enter Gately straight from the desktop icon, without a password or two-step code:
- Only fnOS administrators are signed in, as the Gately administrator; regular fnOS users still enter a username and password;
- It applies only to access through the unified gateway; direct access on port 16680 still requires a normal sign-in;
- After you sign out, Gately does not sign you back in silently; the login page shows a "Sign in as fnOS user <name>" button instead;
- The setting is off by default and only shown in the fnOS package.
Notes
- The app runs as
root, so it can listen on 80/443, manage Docker throughdocker.sockand open a real Web terminal. Install it only on a NAS you control. - Config lives in the app's
vardirectory and is kept on uninstall unless you choose "delete all" in the uninstall wizard. - The package also adds a
/usr/local/bin/gatelycommand forgately ctl,gately mcpandgately reset-password. - Port 16680 is shared with the Docker image. Stop the
gatelycontainer before starting the native app.
Initial sign-in
The admin UI listens on port 16680 by default. The default account is admin and the default password is gately.cn. For automated deployments, set the GATELY_INITIAL_PASSWORD environment variable to choose your own password instead of the default.
The default password is public; while it is still in use, the admin UI keeps showing a warning at the top asking you to change it. The first sign-in shows an onboarding guide that walks you through changing the password, enabling two-factor authentication or a Passkey, running the network self-check, importing from Lucky and setting up notifications.
Reset password and two-factor authentication
If you forget the administrator password or lose your two-factor authenticator (TOTP), reset it by running a command on the server where Gately runs. The command needs read and write access to the config directory, which is the same as having access to the server, so it cannot be used over the network:
gately reset-password: resets the administrator password to the defaultgately.cn; add-p <new password>to set a new password directly;gately reset-totp: turns off two-factor authentication for the administrator; you can enable it again after signing in.
Before doing anything, the command shows the administrator username and the action it is about to take, and asks you to type yes to confirm so a slip of the keyboard does no harm; in scripts and other non-interactive environments, add -y to skip the confirmation. A running Gately applies the change within seconds without a restart; if Gately is not running, the change applies on the next start. A reset invalidates all signed-in sessions and clears login lockouts; the username, Passkeys, read-only accounts and other configuration stay unchanged.
| Install method | Command |
|---|---|
| Docker | docker exec -it gately gately reset-password |
| systemd | sudo gately reset-password |
| OpenWrt / iStoreOS | gately reset-password |
| fnOS | sudo gately reset-password |
| Other | ./gately reset-password -c <config dir> |
Without -c, the command looks in GATELY_CONFIG_DIR, data in the current directory, /etc/gately and the fnOS package config directory /var/apps/gately/var/config, in that order, and prints the directory it uses. Resets are recorded in the system log and the audit log.
Upgrading
Online upgrade
Linux binary installs (systemd, PVE LXC containers, manual OpenWrt installs and so on) can upgrade online from the About page of the admin UI: click "Check for Updates", then "Upgrade now" when a new version is found. This also works for LXC containers created in PVE from the OCI image, so there is no need to delete and recreate them. Gately will:
- Download
gately_<version>_linux_<arch>.tar.gzfor this platform from GitHub; - Verify its SHA-256 against the
checksums.txtof the same release; - Test-run the new binary with
-versionto make sure it runs on this machine; - Replace the executable and restart with the same arguments, keeping the previous version as
gately.oldin the same directory.
Everything happens in a dialog: it first shows the release notes, then the current step, download progress and speed once the upgrade starts. Until the binary is replaced (fetching, downloading and verifying) you can click "Cancel upgrade" at any time, which leaves the current binary untouched.
If GitHub is hard to reach, set an update proxy on the About page or under Settings → Network & Runtime. It supports http://, https:// and socks5://, and both the update check and the download go through it. When empty, Gately connects directly and still honors the HTTPS_PROXY environment variable.
Without internet access, get the tar.gz from the download page and click "Upload upgrade package" on the About page. Uploads accept any version, so you can also roll back to an older release.
Online upgrades only run when an admin starts them; Gately never downloads or installs a version on its own. If the new version fails to start, roll back manually with the kept copy (systemd example):
mv /usr/local/bin/gately.old /usr/local/bin/gately
systemctl restart gatelyIf you granted low-port access to the binary with setcap, run setcap again after the upgrade.
Other deployments
- Docker:
docker pullthe new image and recreate the container (keep the config directory mounted); - fnOS: manually install the newer
.fpkfrom the App Center; your config is kept; - OpenWrt packages: download the newer
.ipk/.apkand runopkg install/apk add --allow-untrusted; your config is kept (see OpenWrt); - Windows, macOS, FreeBSD: replace the executable and restart the service.
Before upgrading, export a configuration backup or keep the config directory in git. Downloaded archives and images can be checked against their signatures as described in Verifying Releases.