SealSkin

Troubleshooting and FAQ

Certificates, Firefox and mobile requirements, the Docker socket, GPUs, storage, and other things that go wrong.

Connecting

The dashboard says "Server unreachable" right after I imported my configuration.

With a self-signed certificate the browser refuses the served UI until you have accepted the certificate once. Click Open server, accept it in the tab that opens, then Retry. Browsers forget an accepted self-signed certificate after a while; when that happens to a server the extension has reached over HTTPS, it shows Secure connection failed instead of quietly loading the interface over plain HTTP. Accept the certificate again, or choose Continue without TLS. If the address or ports are wrong, Change connection takes you back to the connection page. Check that the session port is reachable from where you are (curl -k https://<server>:8443/).

Login fails with "Failed to fetch".

Either nothing answers on the ports in your configuration, or the TLS certificate is expired. The server logs an error at start-up when the proxy certificate has expired and warns two weeks ahead; the dashboard shows the same warning. Renew the certificate (the docker-sealskin installer can renew a Duck DNS one) and restart the container.

Firefox never connects, Chrome works.

Firefox does not allow extensions to talk to a server with an untrusted certificate and has no HTTP fallback. Use a trusted certificate, for example the Let's Encrypt one the installer obtains through Duck DNS, and make sure the extension's server address is that hostname, not an IP.

The mobile app shows a blank page or "Server unreachable".

The Android and iOS WebViews reject self-signed certificates and block mixed content, so the served UI only loads over HTTPS from a certificate the device trusts. There is no fallback. Once the certificate is trusted, the app behaves like the extension.

The server says "HOST_URL" in admin.json.

HOST_URL was not set when the container was first started. Open the file and replace the string with your server's hostname or IP before importing it, or set HOST_URL and delete the keys/admins/admin file and admin.json to have them generated again (that also generates a new key).

I lost admin.json.

The server only keeps the public key. Remove /config/.config/sealskin/keys/admins/admin and restart: a new key pair and admin.json for admin are created, and the account keeps its desktops and its root key. Any other administrator can also create a new administrator from the dashboard.

The client says "Update required".

The extension or app speaks a different bridge protocol version than the UI your server serves. Update whichever is older; the served UI is updated by updating the server image.

Sessions

A launch fails with a Docker error.

The server needs the Docker socket and the right to use it. If the error is a permission denied on /var/run/docker.sock, make the socket group-writable on the host (sudo chmod g+rw /var/run/docker.sock) and restart the container. docker logs sealskin shows the exact error from Docker.

A launch times out waiting for the container.

The container started but did not answer HTTP within a minute. Usually the image is still being pulled for the first time (pull it from Installed Apps ahead of time), the host is out of memory, or the server cannot reach the container's IP. The server and its sessions must share a Docker network; the server uses the network it finds itself attached to.

"Nvidia runtime error on host."

Install the nvidia-container-toolkit, v1.20.1 or higher, and register it with Docker. NVIDIA support needs the proprietary driver 580 or newer with nvidia-drm.modeset=1; the toolkit's refresh service creates /dev/nvidia-modeset at boot, so a headless host needs nothing more.

No GPU is offered in the launcher.

Three things have to line up: the server detected the GPU at start-up (the dashboard lists detected GPUs), the user's settings allow GPU access, and the application declares support for that GPU type (nvidia_support or dri3_support in the store entry). Restart the container after installing drivers so detection runs again.

Files I put in the session are gone after it stops.

Cleanroom sessions are deleted with the session. Use a home directory (or Auto) and put files in Desktop/files, which is your shared files directory and survives every session. Sending a file to a running session from the launcher also places it there.

The session opens but the clock is wrong.

The client sends your browser's time zone with every launch and the container's TZ follows it; failing that, the server's own TZ applies. Set TZ on the sealskin container for a sensible default.

Server

Can I run SealSkin behind my existing reverse proxy?

Yes. The proxy terminates TLS for the web app's name and passes WebSockets; SealSkin's own Caddy stays behind it and keeps routing and authenticating every session request. With session isolation it also serves the session names, <session id>.<domain>, which takes a wildcard certificate. The proxy can also sign users in. Behind a reverse proxy has configurations for SWAG, Traefik, Nginx Proxy Manager, and Caddy, with Authelia and Authentik.

Why must the container be named sealskin?

The server inspects its own container to translate the paths it sees (/config, /storage) into the host paths Docker needs for session volumes, to learn the externally mapped ports it writes into configuration files, and to attach sessions to its network. It looks itself up by that name, falling back to its hostname.

I edited a YAML file by hand and nothing happened.

The watcher reloads a file when it changes on disk, with a short debounce. Check the log for a parse error: a broken file is skipped with a message and the previous state kept. Files whose name starts with . are ignored, and SEALSKIN_WATCH_CONFIG_FILES=false disables the watcher altogether, in which case a restart picks up the edit.

How do I move to a new server key or a new certificate?

Replace ssl/proxy_cert.pem and ssl/proxy_key.pem and restart for a new certificate; clients need nothing. Replacing ssl/server_key.pem changes the server public key every client has stored, so every user has to import a new configuration file (the Export Config of an already-updated client or a new file from the Users panel).

Where are the logs?

docker logs -f sealskin. SEALSKIN_LOG_LEVEL=DEBUG makes the server considerably more talkative. Caddy logs errors only.

Getting help

Search the issues and ask on the LinuxServer.io Discord. Problems with a specific application image belong with that image's repository; problems with the container packaging belong with docker-sealskin.