Webswing Standalone in Docker
Dockerfile
You can find an example Dockerfile in the standard Webswing distribution with examples. In case you need to create a Docker image with Webswing you can do so by using&extending it. Extract the distribution.zip file and execute:
docker build -t webswing .
docker run -d -p 8080:8080 webswing
These images are not meant for cluster deployment, please refer to Cluster Deployment section if you need docker images for cluster deployment. This is a standard Dockerfile which is meant to run demos bundled in the distribution with examples:
FROM openjdk:11-jdk-bullseye
RUN apt-get update && apt-get install --no-install-recommends -y \
wget \
unzip \
xvfb \
libxext6 \
libxi6 \
libxtst6 \
libxrender1 \
libpangoft2-1.0-0
COPY . /opt/webswing/
ENV WEBSWING_HOME=/opt/webswing \
DISPLAY=:99 \
WEBSWING_OPTS="-h 0.0.0.0 -j /opt/webswing/jetty.properties -serveradmin -pfa /opt/webswing/admin/webswing-admin.properties -adminctx /admin -aw admin/webswing-admin-server.war" \
WEBSWING_JAVA_OPTS="-Xmx256M -Djava.net.preferIPv4Stack=true -Dwebswing.admin.url=http://localhost:8080/admin"
WORKDIR /opt/webswing
RUN mkdir -p /etc/service/xvfb && \
echo "#!/bin/sh\nexec Xvfb :99" > /etc/service/xvfb/run && \
chmod +x /etc/service/xvfb/run
RUN mkdir /etc/service/webswing && \
echo "#!/bin/sh\ncd $WEBSWING_HOME\nexec $JAVA_HOME/bin/java \$WEBSWING_JAVA_OPTS -jar $WEBSWING_HOME/server/webswing-jetty-launcher.jar -w $WEBSWING_HOME/webswing-server.war \$WEBSWING_OPTS" > /etc/service/webswing/run && \
chmod +x /etc/service/webswing/run
EXPOSE 8080
RUN echo "#!/bin/sh" > ./start.sh && \
echo "rm -f /tmp/.X99-lock" >> ./start.sh && \
echo "/etc/service/xvfb/run & /etc/service/webswing/run" >> ./start.sh && \
chmod +x ./start.sh
CMD ./start.sh
Quick startup
Running locally:
docker run -d --rm -p 8080:8080 webswing
Running on a server:
docker run -d --rm -e WEBSWING_JAVA_OPTS="-Xmx256M -Djava.net.preferIPv4Stack=true -Dwebswing.admin.url=/admin -Dwebswing.server.publicUrl=http://192.168.1.88:8080" -p 8080:8080 webswing
Docker Compose Example:
Create docker-compose.yml file:
services:
webswing:
image: webswing
restart: always
environment:
- WEBSWING_OPTS=-c /opt/webswing/host/webswing.config -h 0.0.0.0 -j /opt/webswing/jetty.properties -serveradmin -pfa /opt/webswing/host/webswing-admin.properties -adminctx /admin -aw admin/webswing-admin-server.war
- WEBSWING_JAVA_OPTS=-Xms1G -Xmx1G -Djava.net.preferIPv4Stack=true -Dwebswing.propertiesFile=/opt/webswing/webswing.properties
- WEBSWING_ADMIN_URL=http://192.168.0.128:8080/admin
volumes:
- ./webswing:/opt/webswing/host
ports:
- "80:8080"
Environment variable WEBSWING_OPTS
specifies startup arguments for the server.
You can reference your webswing.config
here. Volume syncs container with host, so your config survives the restart of container.
Environment variable WEBSWING_JAVA_OPTS
is for specifying all the system properties that needs to be changed. The most important one in docker context is webswing.admin.url
that is mapped in webswing.config
. This URL link is behind the Manage
button in the application selector screen.
Please note that admin console can run in a different container/host/server, or not run if it is not needed.
In the docker-compose example file we expect that the server has IP address 192.168.1.2.
Docker ports are of "host:container" syntax. So with "80:8080" your app will be accessible without specifying port number.
On your host create folder /opt/app
and place there application jar and dependencies in /opt/app/lib
.
Copy webswing.config
from your DEV machine to /opt/app/webswing.config
.
To configure your app setup the classpath like following:
"classPathEntries" : [ "/opt/app/lib/*.jar", "/opt/app/MySwingApp.jar" ]
Run
docker-compose up -d
Here’s a polished documentation-style guide for configuring Webswing Cluster using Docker. It walks you through architecture, config files, Docker images, and best practices—all in one place.
Webswing Cluster in Docker: Architecture & Overview
Webswing Cluster modularizes deployment into three distinct components:
-
Cluster Server: A stateless gateway managing browser connections, load balancing across Session Pools, and web-level configuration (security, SSL, static resources).
-
Session Pool: Stateful handlers that launch and manage Java desktop application instances. They connect via WebSocket to all Cluster Servers and maintain session-level state.
-
Admin Console: A centralized interface offering monitoring, configuration, REST API access, log viewing, and Cluster management tools.
Why Run in Docker?
-
Modules are packaged independently using Docker images, simplifying deployment, scaling, and configuration management, especially in container orchestration environments like Kubernetes.
-
Docker supports isolating Cluster Servers, Session Pools, and Admin Console into lightweight, reproducible containers.
Docker Setup & Image Guidance
For Kubernetes or Docker-based deployments, Webswing provides example Dockerfiles:
-
Admin Console Image: Based on OpenJDK 11, includes the
webswing-admin-server.war
and startup script exposing port 8080. -
Cluster Server Image: Packaging
webswing.war
within the cluster distribution and launching the cluster module via the Jetty launcher. -
Session Pool Image: Adds Xvfb and related display libraries to support headless Java Swing applications, runs within Docker, and starts the session-pool module.
These can be used as reference or extended to suit your base OS, Java version, or architecture.
Configuration Files & Their Roles
Webswing Cluster relies on several important JSON config files:
- webswing-server.config (Cluster Server)
Defines web-level settings: paths, security, CORS, datastore, and upload limits.
Example snippet:
{
"/": {
"path": "/",
"security": { /* users, roles... */ },
"dataStore": {
"module": "FILESYSTEM",
"config": { "transferFolder": "/data/transfer" }
},
"allowedCorsOrigins": ["*"]
},
"/app": { "enabled": true, "maxClients": 100, ... }
}
- webswing-app.config (Session Pool)
Contains Swing/JavaFX-specific application definitions: launcher config, timeouts, UI features, file upload/download flags, etc.
Example snippet:
{
"/app": {
"jreExecutable": "/usr/bin/java",
"launcherConfig": { "mainClass": "com.example.Main" },
"allowUpload": true,
"directdraw": true,
"jsLinkWhitelist": ["*"]
}
}
- webswing-sessionpool.properties
Handles cluster connectivity and pool behavior: secret key (shared among all modules), WebSocket URLs, session pool ID, reconnection settings.
Key settings:
webswing.connection.secret=ALPHANUMERICKEY
webswing.server.websocketUrl=ws://cluster-server:8080
sessionpool.instances.max=10
- webswing.properties
Defines shared security, WebSocket secrets, and load-balancing strategies. For instance, to change load balancing from round-robin to active-sessions-based:
org.webswing.server.api.service.sessionpool.loadbalance.LoadBalanceResolver=org.webswing.server.core.services.sessionpool.loadbalance.ActiveSessionsCountLoadBalanceResolver
Docker Configuration Workflow
Step 1: Build Images
Build images using provided Dockerfile templates:
webswing-admin
→ Admin Console
FROM eclipse-temurin:21-jdk
RUN apt-get update && apt-get install --no-install-recommends -y \
wget \
unzip \
less \
nano \
procps \
dos2unix
COPY *.zip /opt/webswing-admin/dist.zip
RUN unzip /opt/webswing-admin/dist.zip -d /opt/webswing-admin && \
mv /opt/webswing-admin/webswing-admin-*/* /opt/webswing-admin && \
rm -d /opt/webswing-admin/dist.zip /opt/webswing-admin/webswing-admin-*/
COPY *.war /opt/webswing-admin/webswing-admin-server.war
ENV WEBSWING_HOME=/opt/webswing-admin
COPY docker/docker.tgz .
RUN tar xzvf docker.tgz --strip 1 -C /usr/local/bin docker/docker && rm docker.tgz
WORKDIR $WEBSWING_HOME
RUN mkdir -p /etc/service/webswing-admin && \
echo "#!/bin/sh\ncd $WEBSWING_HOME\nexec $JAVA_HOME/bin/java \$1 -jar $WEBSWING_HOME/server/webswing-jetty-launcher.jar -admin \$2" > /etc/service/webswing-admin/run && \
chmod +x /etc/service/webswing-admin/run
COPY ./webswing-admin.properties /opt/webswing-admin/webswing-admin.properties
COPY ./webswing-autoscaling.config /opt/webswing-admin/webswing-autoscaling.config
COPY ./start_sp.sh /opt/webswing-admin/start_sp.sh
COPY ./stop_sp.sh /opt/webswing-admin/stop_sp.sh
COPY ./secret.key /opt/webswing-admin/secret.key
RUN dos2unix /opt/webswing-admin/start_sp.sh
RUN dos2unix /opt/webswing-admin/stop_sp.sh
EXPOSE 8080
CMD /etc/service/webswing-admin/run "$ADMIN_JAVA_OPTS" "$ADMIN_OPTS"
webswing-server
→ Cluster Server
FROM eclipse-temurin:21-jre
RUN apt-get update && apt-get install --no-install-recommends -y \
wget \
unzip \
less \
nano \
procps
COPY *.zip /opt/webswing-cluster/dist.zip
RUN unzip /opt/webswing-cluster/dist.zip -d /opt/webswing-cluster && \
mv /opt/webswing-cluster/webswing-cluster-*/* /opt/webswing-cluster && \
rm -d /opt/webswing-cluster/dist.zip /opt/webswing-cluster/webswing-cluster-*/
COPY *.war /opt/webswing-cluster/webswing.war
ENV WEBSWING_HOME=/opt/webswing-cluster
WORKDIR $WEBSWING_HOME
RUN mkdir -p /etc/service/webswing-cluster && \
echo "#!/bin/sh\ncd $WEBSWING_HOME\nexec $JAVA_HOME/bin/java \$1 -jar $WEBSWING_HOME/server/webswing-jetty-launcher.jar \$2" > /etc/service/webswing-cluster/run && \
chmod +x /etc/service/webswing-cluster/run
EXPOSE 8080
COPY ./webswing.properties /opt/webswing-cluster/webswing.properties
COPY ./webswing-server.config /opt/webswing-cluster/webswing-server.config
COPY ./secret.key /opt/webswing-cluster/secret.key
COPY ./apps /opt/webswing-cluster/apps
CMD /etc/service/webswing-cluster/run "$WEBSWING_JAVA_OPTS" "$WEBSWING_OPTS"
webswing-session
→ Session Pool
FROM eclipse-temurin:21-jdk
RUN apt-get update && apt-get install --no-install-recommends -y \
wget \
unzip \
xvfb \
libxext6 \
libxi6 \
libxtst6 \
libxrender1 \
libpangoft2-1.0-0 \
dos2unix \
less \
nano \
procps
COPY *.zip /opt/webswing-sessionpool/dist.zip
RUN unzip /opt/webswing-sessionpool/dist.zip -d /opt/webswing-sessionpool && \
mv /opt/webswing-sessionpool/webswing-cluster-*/* /opt/webswing-sessionpool && \
rm -d /opt/webswing-sessionpool/dist.zip /opt/webswing-sessionpool/webswing-cluster-*/
COPY *.war /opt/webswing-sessionpool/webswing.war
ENV WEBSWING_HOME=/opt/webswing-sessionpool \
DISPLAY=:99
WORKDIR $WEBSWING_HOME
RUN mkdir -p /etc/service/xvfb && \
echo "#!/bin/sh\nexec Xvfb :99" > /etc/service/xvfb/run && \
chmod +x /etc/service/xvfb/run
RUN mkdir -p /etc/service/webswing-sessionpool && \
echo "#!/bin/sh\ncd $WEBSWING_HOME\nexec $JAVA_HOME/bin/java \$1 -jar $WEBSWING_HOME/webswing.war \$2" > /etc/service/webswing-sessionpool/run && \
chmod +x /etc/service/webswing-sessionpool/run
COPY ./webswing-app.config /opt/webswing-sessionpool/webswing-app.config
COPY ./webswing-session.properties /opt/webswing-sessionpool/webswing-sessionpool.properties
COPY ./secret.key /opt/webswing-sessionpool/secret.key
COPY ./apps /opt/webswing-sessionpool/apps/
COPY ./fonts /opt/webswing-sessionpool/fonts/
RUN echo "#!/bin/sh" > ./start.sh && \
echo "rm -f /tmp/.X99-lock" >> ./start.sh && \
echo "/etc/service/xvfb/run & /etc/service/webswing/run" >> ./start.sh && \
chmod +x ./start.sh
CMD ./start.sh
Step 2: Provide Config Files
Mount all required config files into each container:
- Cluster Server:
webswing-server.config
,webswing.properties
,jetty.properties
, TLS certs, etc. - Session Pool:
webswing-app.config
,webswing-sessionpool.properties
, plus app binaries and fonts. - Admin Console:
webswing-admin.properties
, REST config, etc.
These files can be also part of the images created in Step 1
Step 3: Environment Variables & Secrets
Set WEBSWING_OPTS
, WEBSPING_JAVA_OPTS
, and ensure webswing.connection.secret
is consistent across modules. Map volumes for persistent storage or shared transfer folders.
Step 4: Networking & Service Exposure
- Expose ports, e.g., 8080 for Cluster Server and Admin Console.
- Connect Session Pools via WebSocket to Cluster Server using defined URLs.
- In orchestration (e.g., Docker Compose or Kubernetes), manage service names and ports accordingly.
Step 5: Scaling & High Availability
- Cluster Server: Stateless—spin up multiple replicas for load balancing.
- Session Pool: Scale based on load; each pool manages its own app instances.
- Admin Console remains singleton or backed with shared state.
Step 6: Monitor & Tune
- Use hardware guidance: ~$300 MB RAM & 1 CPU per 50 users; plan with metrics
- Enable verbose logging (
-v
) or via Admin UI for debugging cluster behavior
Sample Docker Compose Snippet (Simplified)
version: "3.8"
services:
cluster:
image: your/webswing-cluster:latest
volumes:
- ./config/webswing-server.config:/opt/webswing/webswing-server.config
- ./config/webswing.properties:/opt/webswing/webswing.properties
ports:
- "8080:8080"
sessionpool:
image: your/webswing-session:latest
volumes:
- ./config/webswing-app.config:/opt/webswing/webswing-app.config
- ./config/webswing-sessionpool.properties:/opt/webswing/webswing-sessionpool.properties
- ./app:/opt/webswing/apps
depends_on:
- cluster
admin:
image: your/webswing-admin:latest
volumes:
- ./config/webswing-admin.properties:/opt/webswing/webswing.properties
ports:
- "8081:8080"
Summary Table
Component | Config Files | Key Responsibilities |
---|---|---|
Cluster Server | webswing-server.config , webswing.properties |
Routing, load balancing, session tracking, web exposure |
Session Pool | webswing-app.config , webswing-sessionpool.properties |
Launching Java apps, managing app sessions |
Admin Console | webswing-admin.properties |
Monitoring, configuration, UI dashboard, REST API |
Final Tips
- Secret key consistency is critical across cluster, session-pool, and admin modules to secure WebSocket communication and session tokens (JWT)
- Use shared filesystem (e.g., Docker volumes or host paths) for data store (uploads, thread dumps), or rely on
directTransfer
mode which uses websocket streams instead of HTTP - Monitor resource consumption—Webswing recommends empirical testing rather than fixed AML values
- Additional examples can be found in our source code under the following path:
webswing-examples\webswing-examples-assembly\src\main\dev-docker