Skip to content
scalive
Menu
ConnectingLiveReconnectingOffline

Deployment

Prerequisites

This guide starts from the app module created in the quick start. Complete the configuration and client setup first.

Prepare Production Settings

The Quick Start deliberately uses a development signing-secret fallback, fixed port 8080, and secureCookie = false. Do not deploy those settings unchanged. Before packaging, require a stable high-entropy secret, use secureCookie = true for browser-facing HTTPS, and validate application-owned server and service settings at startup. Make the Phoenix client, Live router, static mount, and edge use matching paths.

Environment-variable names are conventions of the application, not Scalive. The Quick Start already reads SCALIVE_TOKEN_SECRET; applications may retain that name or define their own validated configuration contract. Inject real secret values through the deployment platform's secret facility, not source control, an image, logs, or shell history.

Build And Run The Application

A build job needs a JDK and Mill. The Quick Start asset task also needs Node.js and npm because the application resources depend on its browser bundle. Build an executable JAR from the project root:

bash
mill --ticker false app.assembly

The resulting artifact is:

text
out/app/assembly.dest/out.jar

Have the runtime environment provide the application's required settings, then start it with a compatible JRE:

bash
java -jar out/app/assembly.dest/out.jar

The assembly includes the application's JVM dependencies and the browser bundle added by its Mill resources task. Mill, Node.js, npm, and the source tree are build-time requirements, not runtime requirements. If the application uses a different Mill module name, substitute that name in the task and output path.

Scalive does not prescribe a container image, service manager, database migration command, or publication workflow. Package and launch the JAR according to the application's infrastructure while keeping configuration and secrets outside the artifact.

Put An HTTP Edge In Front

Terminate browser-facing TLS at a reverse proxy or load balancer, or configure TLS directly through ZIO HTTP. In either case, set secureCookie = true when the browser uses HTTPS. Scalive does not infer HTTPS from Forwarded, X-Forwarded-Proto, or similar headers.

The edge must route all of the following to the application:

  • ordinary page and form requests;

  • static requests below the configured asset mount; and

  • WebSocket upgrade requests below the configured Live socket mount.

With the default router and new LiveSocket("/live", Socket, ...), the upgrade endpoint is /live/websocket. If the router uses .withSocketPath(PathCodec.empty / "socket"), configure the client with /socket and forward /socket/websocket instead. Preserve the upgrade request's query string and cookie header because LiveView join admission uses both. Allow long-lived WebSocket connections and choose edge and server idle timeouts that do not terminate healthy sockets.

Scalive currently supports WebSocket transport only. There is no long-poll fallback, so a network or edge that blocks WebSocket upgrades leaves the page in its disconnected state. Scalive also has no external-path-prefix setting; an edge that adds a prefix must still expose page, socket, and static paths exactly as the application renders them.

Cache Static Assets

Render asset URLs and serve asset routes from the same loaded StaticAssets value. Digested responses default to public immutable caching for one year; original paths default to no-cache. A CDN or edge may preserve those response headers, but must not apply immutable caching to application HTML or undigested asset paths. See Client setup and static assets for directory sources, digests, and route behavior.

Scale And Roll Out

Each connected LiveView model, along with its tasks, subscriptions, and upload state, lives in the serving process. An established WebSocket remains attached to that process. After a disconnect, restart, or rollout, the client may reach another replica and performs a fresh connected mount.

Persist state that must survive reconnects or process loss in an application-owned shared service. Make mount effects repeatable, and keep route, socket, cookie, asset, token-age, and signing configuration compatible across replicas. A random process-local signing secret prevents replicas from accepting one another's values. Sticky routing can reduce replica changes but does not replace durable state or idempotent mount behavior.

Scalive supplies no cluster membership, general distributed PubSub, shared LiveView model store, or cross-node socket migration. Applications that need cross-node authentication disconnects can provide a LiveDisconnectBus adapter as described in Authentication and sessions; that adapter does not distribute LiveView state. Run the same tested Scalive version across replicas unless a mixed-version rollout has been verified.

Operate And Stop Instances

Scalive does not add liveness or readiness endpoints. Implement them as ordinary ZIO HTTP routes with application-specific semantics. Liveness should report local process health without checking external dependencies. Readiness should become true only after required configuration, assets, and services are available, and should become false before an instance stops accepting traffic when the deployment platform supports that transition.

ZIO HTTP's Server.Config owns the graceful-shutdown timeout and other server limits. Coordinate that timeout with edge deregistration and the platform's termination grace period. Scalive releases socket-owned tasks, subscriptions, and upload resources when a connection closes, but active WebSockets do not migrate to another process; clients reconnect and mount fresh state.

Runtime code emits selected lifecycle failures and diagnostics through ZIO logging. Scalive does not currently expose a complete metrics, tracing, telemetry, or access-log API. Configure request logging and instrumentation in the application and edge, avoid recording credentials or signed values, and add domain and dependency metrics where they are actionable.

Verify The Deployment

Before promoting an instance, verify its public URL end to end:

  • the WebSocket upgrade reaches <socket-path>/websocket with query parameters and cookies intact;

  • HTTPS responses set framework and authentication cookies with Secure;

  • disconnected HTML loads its digested assets with the intended cache policy;

  • liveness, readiness, termination, and reconnect behavior work under the platform's actual proxy and process signals; and

  • a browser can reconnect through another replica without losing state the application promises to preserve.