S5
Streaming & Messaging AWS

Sockudo 5.2.0 WebSocket Server on AWS User Guide

| Product: Sockudo 5.2.0 on Ubuntu 24.04 on AWS

Overview

This guide covers launching and using the Sockudo 5.2.0 on Ubuntu 24.04 AMI from cloudimg on Amazon EC2. It is one version of the cloudimg streaming and messaging listing on AWS Marketplace; you pick it as the software version when you subscribe.

Sockudo is an open source (MIT) real-time messaging server written in Rust. It speaks the Pusher Channels protocol, so the Pusher client libraries (pusher-js, Laravel Echo, the iOS and Android SDKs) and the Pusher server libraries (PHP, Node.js, Python, Ruby, Go and others) work with it unchanged: browsers and apps hold a WebSocket open and subscribe to channels, and your servers publish events to those channels through a signed HTTP API.

What the cloudimg image adds:

  • WSS and HTTPS only, on 443. nginx serves TLS 1.3 and TLS 1.2 (AEAD cipher suites only) on port 443 and passes the WebSocket endpoint (/app/<key>), the HTTP API (/apps/<id>/...) and a health check (/up) to Sockudo, which listens on 127.0.0.1:6001 only. Nothing serves plain HTTP or plain WebSockets: port 80 is closed and plain HTTP sent to 443 is refused.
  • A certificate made on your instance. At first boot the instance gets a TLS key and an end-entity certificate for its own names and addresses. It can only vouch for this server and can never sign other certificates. You pin it in your clients (Step 5), or replace it with one from your own CA or a public CA (Step 12).
  • An app generated for your instance. First boot creates one app with a random id, a 20-character key and a 128-bit secret, stored only in /root/sockudo-credentials.txt (readable by root only) and never on a command line. Sockudo's published sample apps (app-id, app-key, app-secret, demo-app and the like) are refused, so no default credential can ever be configured.
  • App management. sudo sockudo-app lists, adds, rotates, disables, enables and removes apps, and changes their limits (Step 9).
  • A configuration that cannot drift. Sockudo 5.2.0 silently ignores a configuration file it cannot parse and starts with its built-in defaults: every address, metrics open on 9601 and the sample apps. Here a gate runs before every start and refuses anything but the exact rendering of the shipped template and your app store; a guard runs after every start and stops Sockudo if it listens anywhere but 127.0.0.1:6001 or accepts an unsigned request (Step 10).
  • The real client address. nginx sets X-Forwarded-For to the address of the connection itself, never a value a client sends, so Sockudo's per-client rate limits cannot be dodged by forging the header.
  • No instance metadata and no outbound traffic. Sockudo, nginx and every cloudimg service run with the EC2 instance metadata addresses blocked, and a firewall table lets the sockudo user reach loopback only, in IPv4 and IPv6, unless you open a range (Step 11).
  • Built by cloudimg from the v5.2.0 tag, without SurrealDB. Sockudo's own release binaries compile in the SurrealDB client, which is licensed under the Business Source License (BUSL-1.1, not open source). This image's binary is built from the unchanged v5.2.0 source with every other release feature, and its SHA-256 is pinned (Step 13). Sockudo has no telemetry, and the image turns off its metrics, OpenTelemetry and usage reporting.

What is on the image: Sockudo 5.2.0 (/usr/local/bin/sockudo; configuration /etc/sockudo/sockudo.toml, rendered from the app store /etc/sockudo/apps.json), nginx from Ubuntu 24.04 as the TLS front, the cloudimg helpers in /usr/local/sbin (sockudo-app, sockudo-selfcheck, sockudo-set-hostname, sockudo-install-cert, sockudo-egress-apply), the licence, build record and third-party crate list in /usr/share/doc/cloudimg-sockudo/. No Rust toolchain or build cache is on the image. Ubuntu 24.04 LTS is fully patched at build time.

Default user: ubuntu · Architecture: x86_64 · Recommended instance type: m5.large

Prerequisites

  • An AWS account subscribed to the listing, an EC2 key pair and a VPC subnet with a route to the internet (or a private route you use for management).
  • A security group that allows:
Port Protocol Source Purpose
22 TCP your admin network SSH
443 TCP your users (browsers and apps) and your application servers WSS clients and the HTTP API

Nothing else needs to be open. Sockudo's own port 6001 is bound to 127.0.0.1, its metrics port 9601 is off and port 80 is not served, so opening them achieves nothing.

Step 1: Launch the instance

In the AWS Marketplace listing choose Continue to Subscribe, then Continue to Configuration, pick Sockudo 5.2.0 on Ubuntu 24.04 as the software version and your Region, then Launch through EC2. Choose m5.large, your key pair and a security group as above. Sockudo holds every connection in memory; m5.large comfortably serves tens of thousands of idle connections.

With the AWS CLI (replace the values in angle brackets):

aws ec2 run-instances --region <region> --image-id <ami-id-from-the-listing> \
  --instance-type m5.large --key-name <your-key-pair> \
  --security-group-ids <your-security-group> --subnet-id <your-subnet> \
  --metadata-options HttpTokens=required,HttpEndpoint=enabled \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=sockudo}]'

The image requires IMDSv2 (session tokens). First boot takes under a minute after the instance is running: a boot service reads the instance's EC2 names, creates the app and the certificate, loads the firewall table, then Sockudo and nginx start and the guard checks them.

Step 2: Connect to your instance

Version SSH user
Sockudo 5.2.0 on Ubuntu 24.04 ubuntu
ssh -i <your-key.pem> ubuntu@<public-ip>

The login banner shows where everything is:

  Sockudo 5.2.0 on Ubuntu 24.04 (cloudimg)
  App id, key, secret, endpoint, certificate:  sudo cat /root/sockudo-credentials.txt
  Clients: wss://<this host>/app/<key>   API: https://<this host>/apps/<id>/... (443 only, signed)
  Apps: sudo sockudo-app list   Logs: journalctl -u sockudo   Verify: sudo sockudo-selfcheck
  User guide: https://www.cloudimg.co.uk/guides/sockudo-5-2-0-on-ubuntu-24-04-aws/

Step 3: Check the services and the listening set

systemctl is-active sockudo-metadata sockudo-egress sockudo-firstboot sockudo nginx
sudo ss -tlnp | grep -E ':(22|80|443|6001|9601) '
sudo ss -ulnp | grep -E 'sockudo|nginx' || echo 'no UDP socket from sockudo or nginx'
active
active
active
active
active
LISTEN 0      511          0.0.0.0:443       0.0.0.0:*    users:(("nginx",pid=1143,fd=5),("nginx",pid=1142,fd=5),("nginx",pid=1141,fd=5))
LISTEN 0      128        127.0.0.1:6001      0.0.0.0:*    users:(("sockudo",pid=1120,fd=9))
LISTEN 0      4096         0.0.0.0:22        0.0.0.0:*    users:(("sshd",pid=879,fd=3),("systemd",pid=1,fd=195))
LISTEN 0      511             [::]:443          [::]:*    users:(("nginx",pid=1143,fd=6),("nginx",pid=1142,fd=6),("nginx",pid=1141,fd=6))
LISTEN 0      4096            [::]:22           [::]:*    users:(("sshd",pid=879,fd=4),("systemd",pid=1,fd=196))
no UDP socket from sockudo or nginx

sockudo-metadata reads this instance's EC2 names (and nothing else) from the metadata service, sockudo-egress loads the firewall table, sockudo-firstboot prepares the app and the certificate, sockudo is the server and nginx is the TLS front. sockudo-metadata and sockudo-firstboot finish and stay active. Only nginx listens on the network (443, IPv4 and IPv6). Sockudo listens on 127.0.0.1:6001, and a firewall rule lets only nginx's user and root connect to it.

Step 4: Your app id, key and endpoint

Everything generated for your instance is in /root/sockudo-credentials.txt (readable by root only). View it all with sudo cat /root/sockudo-credentials.txt. The lines that are not secret are:

sudo grep -E '^SOCKUDO_(HOST|URL|PRIVATE_IP|APP_ID|APP_KEY|TLS_CA_FILE|TLS_CERT_SHA256|TLS_PUBKEY_SHA256)=' /root/sockudo-credentials.txt
sudo sockudo-app list
SOCKUDO_HOST=<public-ip>
SOCKUDO_URL=https://<public-ip>/
SOCKUDO_PRIVATE_IP=<private-ip>
SOCKUDO_APP_ID=app-<8 hex>
SOCKUDO_APP_KEY=<20 hex>
SOCKUDO_TLS_CA_FILE=/etc/sockudo/tls/cert.pem
SOCKUDO_TLS_CERT_SHA256=<AA:BB:...>
SOCKUDO_TLS_PUBKEY_SHA256=<64 hex>
APP ID           KEY                    ENABLED  MAXCONN  CLIENT USERAUTH
app-<8 hex>      <20 hex>               yes      10000    off    off
(secrets: /root/sockudo-credentials.txt for the first app, /root/sockudo-app-<id>.txt for the others)
  • The key (SOCKUDO_APP_KEY) is public: browsers and apps use it to connect, so it appears in your front-end code.
  • The secret (SOCKUDO_APP_SECRET, also in the file) signs every HTTP API call and every private or presence channel subscription. Keep it on your servers only, never in browser or app code, and never on a command line (a command line is visible to every user on a machine through ps).

Step 5: Check the certificate and pin it in your client

The server's certificate is self-signed, made on your instance:

sudo openssl x509 -in /etc/sockudo/tls/cert.pem -noout -subject -enddate -ext subjectAltName,basicConstraints,extendedKeyUsage
sudo openssl x509 -in /etc/sockudo/tls/cert.pem -noout -fingerprint -sha256
subject=CN = sockudo, O = cloudimg
notAfter=<about 27 months after first boot>
X509v3 Subject Alternative Name:
    IP Address:<public-ip>, DNS:<public-dns-name>, IP Address:<private-ip>, DNS:<private-dns-name>, IP Address:127.0.0.1, DNS:localhost
X509v3 Basic Constraints: critical
    CA:FALSE
X509v3 Extended Key Usage:
    TLS Web Server Authentication
sha256 Fingerprint=<AA:BB:...>

CA:FALSE means it is an end-entity certificate that cannot sign anything else. The SHA-256 fingerprint is the SOCKUDO_TLS_CERT_SHA256 value in your credentials file. The certificate covers the instance's public and private IPv4 addresses and EC2 DNS names, localhost and 127.0.0.1. An EC2 stop and start gives the instance a new public IP. At the next boot the certificate is re-issued for the new address with the same key, so a client that pins the public key (SOCKUDO_TLS_PUBKEY_SHA256) keeps working, and a client that uses the certificate file needs the new copy.

Copy /etc/sockudo/tls/cert.pem to each server that calls the API and trust it for this server only (for example curl --cacert, or the CA option of your Pusher server library). Never add it to a system-wide trust store. Browsers do not accept a self-signed certificate for WebSockets: for browser clients, give the instance a DNS name and a certificate from a CA (Step 12).

Step 6: Publish an event and receive it

The image ships the small client cloudimg uses for its own checks. This subscribes to the channel orders over WSS, publishes one event to it through the signed HTTP API, and shows the subscriber receiving it. Both go through nginx on 443 with the certificate pinned, and the app's secret is read from the credentials file, never from a command line:

P="sudo python3 -I /usr/local/lib/cloudimg/sockudo_probe.py"
O="--target 127.0.0.1:443 --tls --cacert /etc/sockudo/tls/cert.pem --sni localhost --creds /root/sockudo-credentials.txt --channel orders"
$P listen $O --seconds 6 & sleep 2
$P publish $O --event created --data '{"order":42}'
wait
LISTENING orders
EVENT created {"order":42}
HTTP 200

An HTTP API call without a signature is refused (a missing signature gets 400; a wrong secret or a stale timestamp gets 401 or 403), plain HTTP to port 443 is refused and port 80 is closed:

curl -s -o /dev/null -w 'unsigned publish: %{http_code}\n' --cacert /etc/sockudo/tls/cert.pem -H 'Content-Type: application/json' -d '{"name":"x","channel":"orders","data":"{}"}' https://localhost/apps/<SOCKUDO_APP_ID>/events
curl -s -o /dev/null -w 'plain HTTP on 443: %{http_code}\n' http://localhost:443/up
curl -s -o /dev/null -w 'port 80: %{http_code} %{errormsg}\n' http://localhost/up || true
unsigned publish: 400
plain HTTP on 443: 400
port 80: 000 Failed to connect to localhost port 80 after 0 ms: Couldn't connect to server

Step 7: Connect your applications

Point the Pusher libraries at the instance's DNS name on port 443 with TLS. The examples below use <dns-name>, <SOCKUDO_APP_KEY> and <app-id> from Step 4, and the secret from the credentials file.

Browser (pusher-js): the key is public; the secret never goes in browser code. Use a name with a CA certificate (Step 12).

import Pusher from "pusher-js";

const pusher = new Pusher("<SOCKUDO_APP_KEY>", {
  wsHost: "<dns-name>",
  wsPort: 443,
  wssPort: 443,
  forceTLS: true,
  enabledTransports: ["ws", "wss"],
  disableStats: true,
  cluster: "",
});
pusher.subscribe("orders").bind("created", (data) => console.log("order", data));

Your server (the Node.js pusher library): the same settings are available in every Pusher server library.

const Pusher = require("pusher");

const sockudo = new Pusher({
  appId: "<app-id>",
  key: "<SOCKUDO_APP_KEY>",
  secret: process.env.SOCKUDO_APP_SECRET,
  host: "<dns-name>",
  port: "443",
  useTLS: true,
});
await sockudo.trigger("orders", "created", { order: 42 });

Laravel broadcasting (.env, with BROADCAST_CONNECTION=pusher):

PUSHER_APP_ID=<app-id>
PUSHER_APP_KEY=<SOCKUDO_APP_KEY>
PUSHER_APP_SECRET=<the secret, from the credentials file>
PUSHER_HOST=<dns-name>
PUSHER_PORT=443
PUSHER_SCHEME=https

While you still use the self-signed certificate, give server libraries the copied cert.pem as their trusted CA (for the Node.js library, a custom agent with ca; for PHP, Guzzle's verify option).

Step 8: Private and presence channels

A client subscribes to a private- or presence- channel only with a signature from your server: the Pusher client calls your application's auth endpoint, which signs <socket_id>:<channel> with the app's secret (HMAC-SHA256), and Sockudo checks it. Every Pusher server library does this for you (authorizeChannel in Node.js, authorizeChannel / socketAuth in PHP). A subscription without a valid signature is refused, and so is a client event (a message sent by a client rather than your server): client events are off for every app unless you turn them on (Step 9).

Step 9: Manage apps

Each app has its own id, key and secret, its own connection limit and its own switches. Give each application or environment its own app, so you can rotate or remove one without touching the others:

sudo sockudo-app list
sudo sockudo-app 2>&1 | head -n 1 || true
APP ID           KEY                    ENABLED  MAXCONN  CLIENT USERAUTH
app-<8 hex>      <20 hex>               yes      10000    off    off
(secrets: /root/sockudo-credentials.txt for the first app, /root/sockudo-app-<id>.txt for the others)
sockudo-app: REFUSED (nothing changed): usage: sockudo-app list | add [<app-id>] [options] | rotate <app-id> | set <app-id> options | enable <app-id> | disable <app-id> | remove <app-id>

Add an app (its id, key and secret are written to /root/sockudo-app-<id>.txt, readable by root only), rotate an app's key and secret, switch features or limits, disable, enable or remove an app:

sudo sockudo-app add staging --max-connections 2000
sudo cat /root/sockudo-app-staging.txt
sudo sockudo-app rotate staging
sudo sockudo-app set staging --client-messages on --user-auth on --max-client-events 50
sudo sockudo-app disable staging
sudo sockudo-app enable staging
sudo sockudo-app remove staging

Each change is checked first and applied by restarting Sockudo, so connected clients reconnect (the Pusher clients do this by themselves within seconds). rotate on the first app writes the new key and secret to /root/sockudo-credentials.txt. A disabled app is taken out of Sockudo's running configuration altogether (it stays in the app store, marked disabled), so both its WebSocket connections and its API calls are refused until you enable it again. A refused change (an id already in use, a published sample id, a limit out of range, removing or disabling your only enabled app) prints REFUSED (nothing changed) and leaves everything as it was. Apps are stored in /etc/sockudo/apps.json; edit them only with sockudo-app, because the gate refuses a configuration that is not its exact rendering.

Step 10: The server refuses to run unsafely

Upstream, Sockudo listens on every address on port 6001, can open a metrics port, a unix socket, an MCP server and an unauthenticated usage route, and falls back to its built-in defaults (with sample apps) when its configuration file does not parse. On a cloud instance each of those exposes your apps, so this image fixes them:

  • Port 6001: Sockudo listens on 127.0.0.1:6001 only, set in its own configuration, and a firewall rule lets only nginx's user (and root) connect to it, so no other local user can go around nginx's limits.
  • Metrics (9601), the metrics TCP exporter, OpenTelemetry, the unix socket, the MCP server, the AI transport, the Ably-compatible endpoint and the usage route: off, and the gate refuses a configuration that turns one on.
  • Sockudo's own TLS: off. nginx terminates TLS with the cloudimg settings.
  • Rate limits: Sockudo allows 600 API requests and 120 WebSocket connections per client address per minute; nginx allows 20 API requests and 10 WebSocket upgrades per second per address and 200 connections per address, and refuses a body over 1 MB.

sockudo.service runs sockudo-config-gate before every start and sockudo-guard after it, and nginx runs its own gate before every start and reload. Check them, and the whole service as a client sees it:

sudo journalctl -u sockudo -b --no-pager -o cat | grep -E 'sockudo-(config-gate|guard): OK' | tail -n 2
sudo sockudo-selfcheck
sockudo-config-gate: OK (unit): 1 app(s), activity_timeout 114; listen 127.0.0.1:6001; egress default-deny
sockudo-guard: OK (start): sockets tcp:127.0.0.1:6001 only; the running configuration is the rendered one (activity_timeout 114); PROBE OK: 20 cases; egress default-deny
SELFCHECK OK: Sockudo 5.2.0 behind nginx 443 (TLS, certificate AA:BB:...); PROBE OK: 20 cases; /up 200, Sockudo's other routes 404, /app/ without an upgrade 400; ports 80 and 9601 closed

If a change is refused, Sockudo (or nginx) does not start and journalctl -u sockudo (or journalctl -u nginx) shows the reason. If the running Sockudo ever listens anywhere else or answers an unsigned request, the guard stops it. If first boot cannot finish, neither service starts.

Step 11: The instance metadata block and outbound traffic

The EC2 instance metadata service (169.254.169.254) hands out the instance's IAM role credentials to any process that asks. sockudo, nginx and sockudo-firstboot run with the metadata addresses blocked by systemd (IPAddressDeny). Only sockudo-metadata, which reads the instance's names, may reach the metadata service, and it may reach nothing else:

for u in sockudo nginx sockudo-firstboot sockudo-metadata sockudo-egress; do printf '%-18s deny=%s allow=%s\n' "$u" "$(systemctl show -p IPAddressDeny --value "$u")" "$(systemctl show -p IPAddressAllow --value "$u")"; done
sockudo            deny=fd00:ec2::254/128 ::ffff:169.254.169.254/128 168.63.129.16/32 169.254.169.254/32 ::ffff:168.63.129.16/128 allow=
nginx              deny=168.63.129.16/32 ::ffff:169.254.169.254/128 fd00:ec2::254/128 169.254.169.254/32 ::ffff:168.63.129.16/128 allow=
sockudo-firstboot  deny=168.63.129.16/32 fd00:ec2::254/128 169.254.169.254/32 ::ffff:168.63.129.16/128 ::ffff:169.254.169.254/128 allow=
sockudo-metadata   deny=::/0 0.0.0.0/0 allow=fd00:ec2::254/128 169.254.169.254/32
sockudo-egress     deny=::/0 0.0.0.0/0 allow=

On top of that, the nftables table loaded by sockudo-egress lets the sockudo user answer its clients and reach loopback, and refuses everything else in IPv4 and IPv6: the internet, your VPC and instance metadata. Sockudo's built-in features that call out (webhooks, push notifications, Redis, NATS or a database as an adapter) are not configured on this image, so it needs nothing outside. Other users are unaffected:

sudo sockudo-egress-apply --check
for t in 169.254.169.254:80 1.1.1.1:443; do sudo -u sockudo timeout 5 bash -c "exec 3<>/dev/tcp/${t%:*}/${t#*:}" 2>/dev/null && echo "sockudo -> $t: open" || echo "sockudo -> $t: refused"; done
timeout 5 bash -c 'exec 3<>/dev/tcp/1.1.1.1/443' && echo "ubuntu -> 1.1.1.1:443: open"
sockudo-egress: CHECK OK (nothing loaded): 0 drop-in file(s) opening nothing
sockudo -> 169.254.169.254:80: refused
sockudo -> 1.1.1.1:443: refused
ubuntu -> 1.1.1.1:443: open

If you extend the configuration to reach something (a Redis or NATS server for several Sockudo nodes, a webhook receiver), open exactly that range with a root-owned file in /etc/sockudo/egress-allow.d/ ending in .cidr, one network per line, then reload the table:

printf '# the Redis server the Sockudo nodes share\n10.0.5.20/32\n' | sudo tee /etc/sockudo/egress-allow.d/10-redis.cidr
sudo systemctl reload sockudo-egress
sudo sockudo-egress-apply --check

Metadata, link-local, multicast and reserved addresses can never be opened. A refused file leaves the loaded rules unchanged, and journalctl -u sockudo-egress says why. Delete the file and reload to close the range again.

Step 12: Use your own DNS name or a certificate from your CA

Point a DNS name at the instance (an Elastic IP keeps the address across stop and start), then add the name to the certificate:

sudo sockudo-set-hostname <dns-name>

This re-issues the self-signed certificate with the same key to cover the name, updates the endpoint in /root/sockudo-credentials.txt and reloads nginx. Copy the new certificate to servers that pin the certificate file.

For browser clients, use a certificate from a CA (your own, or a public one such as Let's Encrypt). Copy the chain (server certificate first) and its unencrypted PEM key to the instance, then run:

sudo sockudo-install-cert <certificate-chain.pem> <private-key.pem> <dns-name>

Port 443 then serves your certificate, browsers and server libraries trust it without extra settings, and the boot-time renewal never replaces it. sudo sockudo-set-hostname <name> goes back to a new self-signed certificate.

Step 13: About this build, and how to verify it

Sockudo's v5.2.0 release binaries are built with the feature set full, which compiles in the SurrealDB client. SurrealDB is licensed under the Business Source License 1.1, which is not an open source licence, so cloudimg builds Sockudo itself:

  • Source: the v5.2.0 tag, commit 9b4f0476028871a76bb239809a90e2c91d16f648, checked out clean with no source change, using the project's own Cargo.lock.
  • Features: the release's full list minus surrealdb: opentelemetry,v2,versioned-messages,ai-transport,ably-compat,push,push-fcm,push-apns,push-webpush,push-hms,push-wns,mcp,redis,redis-cluster,nats,pulsar,rabbitmq,google-pubsub,kafka,iggy,omq,mysql,postgres,dynamodb,scylladb,sqs,sns,lambda. Every other backend and feature of the release is present; only the SurrealDB app store and cache backends are absent.
  • Build: Rust 1.99.1 on a separate build machine, with the release workflow's settings (thin LTO, 8 codegen units) and its strip step: cargo build -p sockudo --release --locked --features <the list above>.
  • Licences: every one of the 660 crates in that build is under an open source or permissive licence (MIT, Apache-2.0, BSD, ISC, Zlib, the Boost licence BSL-1.0, Unicode-3.0 and a few public-domain or data licences). None is GPL, AGPL, SSPL or BUSL. The list, crate by crate, is /usr/share/doc/cloudimg-sockudo/THIRD-PARTY-CRATES.txt.

The install checks the binary against its pinned SHA-256 and refuses any other file. Check it yourself:

sha256sum /usr/local/bin/sockudo
/usr/local/bin/sockudo --version
sudo grep -E '^(source|commit|toolchain|features|sockudo):' /usr/share/doc/cloudimg-sockudo/BUILD-INFO
grep -ci surrealdb /usr/share/doc/cloudimg-sockudo/THIRD-PARTY-CRATES.txt || true
f8ad7f2db5db6af2acb61ff7a07d9fa022e634c4d1eff6cec26ca9b98820e02b  /usr/local/bin/sockudo
sockudo 5.2.0
source:    https://github.com/sockudo/sockudo tag v5.2.0 (tag object 16cbb8a62e7940e330c5bc0a6bb43852ea2119d1)
commit:    9b4f0476028871a76bb239809a90e2c91d16f648 (clean checkout, no source patch)
toolchain: rustc 1.99.1 (58cf8f9c3 2026-10-13), cargo 1.99.1 (5f94df478 2026-08-27)
features:  upstream's release builds --features full; this build is that list minus surrealdb (the SurrealDB crates ...)
sockudo:   sha256 f8ad7f2db5db6af2acb61ff7a07d9fa022e634c4d1eff6cec26ca9b98820e02b (stripped, x86_64, glibc)
0

The pinned SHA-256 is f8ad7f2db5db6af2acb61ff7a07d9fa022e634c4d1eff6cec26ca9b98820e02b. A rebuild from the tag with the same feature list gives the same program; a byte-identical binary also needs the same Rust toolchain, build path and system packages, and cloudimg has not proven bit-for-bit reproducibility with a second build. /usr/share/doc/cloudimg-sockudo/PROVENANCE records the SHA-256 of every file cloudimg ships.

Logs, files and limits

  • Sockudo log: journalctl -u sockudo (connections, subscriptions and errors; never a secret). nginx access and error logs: /var/log/nginx/ (the access log records request paths, which include your public app keys). First boot: journalctl -u sockudo-firstboot.
  • Configuration: /etc/sockudo/sockudo.toml (root:sockudo 0640, rendered by sockudo-app, checked by the gate on every start). Apps: /etc/sockudo/apps.json (root only). Certificate and key: /etc/sockudo/tls/. Egress drop-ins: /etc/sockudo/egress-allow.d/.
  • Limits per app (change with sockudo-app set): 10,000 connections and 100 client events per second by default; a message may be up to 64 KB. Sockudo keeps channels and presence in memory, so a restart (an app change, a reboot) reconnects every client.
  • Activity timeout: each instance picks a value between 110 and 119 seconds at first boot; clients learn it when they connect.

Support

cloudimg provides support for the image: launch problems, the first-boot setup, the TLS and app configuration and the cloudimg helpers. Contact support@cloudimg.co.uk. Sockudo itself is documented at github.com/sockudo/sockudo.