Install and first run
Four platforms, one core. Pick your package, unlock the vault, connect. The sync server is optional and comes last.
Install
Every package is on the releases page. Nothing phones home during installation.
Linux — AppImage, runs without installing
chmod +x Skerry-*.AppImage ./Skerry-*.AppImageNeeds FUSE. Without it, run with --appimage-extract-and-run.
Linux — Debian, Ubuntu
sudo apt install ./skerry_*_amd64.debLinux — Fedora, RHEL
sudo dnf install ./skerry-*.x86_64.rpmWindows — .msi installer
The build is not code-signed: SmartScreen shows "Windows protected your PC" → More info → Run anyway. The portable .zip needs no installer.
macOS — .dmg, Apple Silicon or Intel
Unsigned and not notarized: right-click the app → Open on the first launch. Get Info shows a 1.x.y version because macOS packaging demands a major ≥ 1 — the About screen shows the real one.
Android — signed .apk, sideload
Android 8.0 and newer, arm64-v8a. Allow installation from your browser or file manager when the system asks.
Verify the download
Every release ships SHA256SUMS.txt next to the packages.
Check the file you downloaded against it
sha256sum -c --ignore-missing SHA256SUMS.txtOn Windows: certutil -hashfile Skerry-x.y.z.msi SHA256, then compare by eye.
First run
Set the master password
It encrypts the local vault, stays on the device and cannot be recovered — forget it and the data cannot be decrypted. On Android you can add biometric unlock afterwards, in More → Security.
Add a host — New connection
Address, port, user, then the key or password. Credentials go into the vault, not into a config file.
Or import what you already have
New connection → Import from ssh_config reads ~/.ssh/config and lists the hosts to pick from. Keys are not imported — you set authentication when you connect.
Tag production hosts
A host tagged prod runs every command through the risk check; a destructive one stops for confirmation.
Your own sync server
Optional. Skerry is fully functional without it — this is only for having one vault on several devices. There is no vendor cloud.
Run the container
docker run -d --name skerry-sync -p 8080:8080 \ -e SKERRY_JWT_SECRET="$(openssl rand -base64 48)" \ -e SKERRY_ADMIN_TOKEN="$(openssl rand -hex 16)" \ -v skerry-data:/data \ secherkasov/skerry-sync:latestSQLite in a named volume, zero configuration. Keep SKERRY_JWT_SECRET — changing it signs everyone out.
Point the app at it
Settings → Sync → SERVER URL, then register or sign in. The server verifies your password with SRP-6a and never receives it.
Link the second device
On the signed-in device: Settings → Sync → Link a device, then scan the QR from the other one.
The server has a web console
A public page at /, your account area at /account, the operator view at /console — served by the same container, fully offline.
PostgreSQL instead of SQLite
Uncomment the db service and the postgres variables in docker-compose.yml. The full deployment guide — TLS, backups, API — is in server/README.md.
Build from source
Requires JDK 21; the Gradle toolchain resolver fetches one if your machine has none. Packages are produced for the OS and architecture of the machine that builds them.
Clone the repository
git clone https://github.com/SeCherkasov/SkerrySSH.git cd SkerrySSHRun the desktop app
./gradlew :composeApp:runPackage it
./gradlew :composeApp:packageDistributionForCurrentOS # .deb / .rpm / .msi / .dmg ./gradlew :composeApp:packageAppImage # portable Linux .AppImageAndroid
ANDROID_HOME=$HOME/Android/Sdk ./gradlew :androidApp:installDebugServer only, no Android SDK
./gradlew :server:run -PserverOnly