Continuous deployment is often described as a cultural achievement requiring a build server, a pipeline definition and a team to maintain them. For a small Jakarta EE team it can also be one package: a WildFly server wired to a Git repository, with a Maven build that runs on every push and redeploys the result. This post follows a two-person team adopting it on MassiveGRID PaaS, which is built on Virtuozzo Application Platform, formerly Jelastic.
The team maintains a membership-management application for a professional association we will call the Guild of Assessors: a Jakarta EE WAR with JPA, CDI and JAX-RS, deployed for years by copying a file into a WildFly directory over SSH. The WildFly Continuous Deployment package deploys a WildFly server linked to a Git repository, builds with Maven on each push and redeploys automatically, with a sample project connected so the loop works before a line of the team's code arrives.
What the package sets up
Installing the package produces a WildFly application server on a Java node with an LTS JDK and the admin console over HTTPS, plus a build component linked to a Git repository. On each push to the configured branch the component pulls, runs the Maven build, and deploys the resulting WAR or EAR to WildFly with hot redeploy: the new artefact replaces the old one in the running server. Each run's build log is available in the dashboard. A sample application is connected at install, so the first thing the team saw was a green build of someone else's code, which is the fastest way to trust a pipeline.
Pointing it at the real application
The team replaces the sample's repository URL with their own, on the association's GitLab server, adds a deploy key, and sets the branch to main. Their pom.xml already produced a WAR, so the Maven goals stay clean package. Two adjustments were needed. The application's datasource had been defined in WildFly's configuration by hand on the old server; the team defines it in the new server through the admin console once, pointing at a PostgreSQL cluster in the same environment group over the internal network. And the application read a properties file from a hard-coded path; it now reads environment variables set on the WildFly layer in the dashboard, so the same WAR runs on any clone.
The first real push built in about three minutes, most of it Maven downloading dependencies, and redeployed. The second push, a one-line fix, built in forty seconds because the node's Maven repository was warm.
What continuous deployment changed for a team of two
| Before | After |
|---|---|
| Build on a laptop, copy the WAR over SSH, watch the log | Push to main; the platform builds and redeploys |
| Deploys on Friday evening, because they were scary | Deploys whenever a fix is merged, several a week |
| One person knew the deployment steps | The steps are the package's configuration |
| A failed build was discovered on the server | A failed build leaves the previous deployment running and shows the error in the dashboard |
| No record of what was deployed when | Git history plus the deployment log |
The row about failures is the one that changed the team's behaviour. Because the previous deployment keeps running when a build fails, a push is no longer a risk to the live site; it is an attempt, and the log says why it did not succeed.
Hot redeploy, and its honest limits
Hot redeploy replaces the application inside a running WildFly without restarting the server, and for a WAR of this size it takes seconds. Users with open sessions may see a request fail during the swap, and the team schedules pushes to main for quiet hours out of courtesy, not necessity. Over months, repeated hot redeploys can accumulate memory in some applications (class loader leaks are a known Java phenomenon); the team's mitigation is a monthly container redeploy of the WildFly node from the dashboard, which restarts the JVM cleanly with the data volumes preserved, and a load alert on RAM at 85% that would tell them sooner.
Staging is a clone with a different branch
A clone of the environment gives the team a second WildFly with the same build component; they change the clone's branch to develop and its datasource to the staging PostgreSQL. Feature branches merge to develop and appear on staging within minutes; a merge to main goes live. The staging clone is stopped at night by the Start/Stop Scheduler and costs disk only while stopped.
When to move to the managed domain
The package targets one WildFly server, which is right for the association's few hundred concurrent members. When an application needs several servers, the path is the WildFly Managed Domain Cluster: a domain controller, worker hosts that provision themselves, a load balancer and rolling deployment across a server group. The same Maven build node pattern feeds it, deploying to the domain controller instead of a standalone server. The team wrote that down as the step for when the load alert starts firing, and has not needed it.
Cost for the single server: a WildFly JVM at about 16 cloudlets during the day and 8 at night (a cloudlet is 128 MiB of RAM plus 400 MHz of CPU), plus a small build component and the PostgreSQL cluster, roughly $60 a month before discounts at MassiveGRID's published $0.003372 per cloudlet-hour for the WildFly side. The previous server had been a leased machine that also required someone to know where the WAR went.
Frequently Asked Questions
Which Git hosts work?
Any repository reachable over HTTPS or SSH: GitHub, GitLab.com, Bitbucket, the self-hosted GitLab Server package, or Gitblit. Private repositories use a deploy key or access token stored on the platform.
Can I run tests as part of the build?
Yes. The Maven build runs whatever phases you configure; keep test in the goals and a failing test fails the build, leaving the previous deployment running. For long integration test suites a dedicated CI server such as the Jenkins package is more comfortable, with this package as the deploy step.
Does this replace a proper CI/CD pipeline?
For a small team with one application it is one. For many services, parallel test runners, artefact promotion between environments and approvals, pair it with the GitLab Server or Jenkins package and use the platform's CLI to deploy.
Push to main, and WildFly has it
The WildFly Continuous Deployment package deploys a WildFly server linked to your Git repository on MassiveGRID PaaS, building with Maven and hot-redeploying on every push. Per cloudlet-hour, free 14-day trial, no credit card.
WildFly Continuous Deployment on MassiveGRID PaaS