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 -Dwebswing.server.publicUrl=http://192.168.1.2 -Dwebswing.admin.url=/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.warand startup script exposing port 8080. -
Cluster Server Image: Packaging
webswing.warwithin 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
directTransfermode 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