Zero‑Touch Java Deployment with Docker: A Four‑Step Guide
This article walks through a practical Docker‑based continuous deployment pipeline for a Java application, showing how Git, Jenkins, and Docker Registry can be configured to automatically build, test, and deploy code without manual intervention, complete with screenshots and FAQs.
This is the sixth article in the "Efficient Operations Best Practices" column, originally written by Xiao Tianguo and republished with permission.
Preface
There are countless Docker articles, but most are translations and lack practical, hands‑on guidance. While Docker is touted as ideal for CI/CD, real‑world, actionable examples are rare.
This piece is an exception: a step‑by‑step case study showing how a Java project can achieve continuous deployment with Docker in just four simple steps.
Developers push code to Git; Git and Jenkins cooperate to automatically deploy and release the application without any operations staff involvement.
This container‑level implementation not only boosts efficiency but also transforms the development workflow.
Developers become truly responsible for their code, bypassing traditional operations and testing hand‑offs and managing their own runtime environments.
With four straightforward configurations, you can elegantly implement continuous deployment. Below is the article outline.
Technical approach to continuous deployment Result demonstration Configuring Git‑Jenkins integration Configuring Jenkins for automatic code updates Detailed visual walkthrough FAQ
1. Technical Approach to Continuous Deployment
Assume the Java project is named hello . The overall idea is illustrated below.
The code resides on git.oschina.com, while Jenkins and a private Docker Registry run in separate containers. The Java application itself runs in its own hello container.
The deployment pulls images from the private Docker Registry. An alternative approach of mounting host‑side code into the container is discouraged because it violates Docker’s container principle and adds unnecessary complexity.
Separating code from the container increases handling complexity; treating the container as the whole unit is more economical and aligns with true container‑level migration.
Containers are processes. Their lifecycle should be much shorter than that of virtual machines, and any issues should lead to immediate termination rather than recovery attempts.
2. Result Demonstration
The final effect of the implementation is shown below.
2.1 Before code update
2.2 Submitting code update
The homepage timestamp is changed from 201506181750 to 201506191410 as shown.
2.3 Uploading new code to Git
Execute the following steps and enter the correct Git credentials.
After that, simply wait a few minutes for the automatic deployment to complete.
The process takes 3–5 minutes because the Java project downloads Maven packages from abroad. In production, you would host Maven mirrors locally to speed up the build.
2.4 After code update
After a short wait, the new code is automatically deployed.
The implementation requires only a few configuration steps.
3. Configuring Git‑Jenkins Integration
The process consists of three main steps.
3.1 Jenkins configures Git source
Create a new Jenkins job java-app and set it to pull code from Git.
3.2 Jenkins configures remote build
Set a token in Jenkins for remote Git triggers.
3.3 Enable Git hook
Configure Git hooks to notify Jenkins after each push.
4. Configuring Jenkins for Automatic Code Updates
Jenkins receives the Git hook, triggers a remote build on the target server, and executes a predefined task list to rebuild the container.
The critical shell script (Docker operations) is shown below.
5. Detailed Visual Walkthrough
In section 2.3 we uploaded new code to Git. The following screenshots illustrate the subsequent actions.
5.1 Code uploaded to Git
The upload completes, and the backend process begins.
5.2 Jenkins interaction
Jenkins automatically creates a build task, pulls Maven packages, builds the new hello image, pushes it to the private registry, and finally restarts the container.
1) Build task appears:
2) Build logs show Git trigger:
3) Maven packages download (slow step):
4) Maven builds new hello package:
5) New image is pushed to the private registry:
6) Container is restarted with the new image:
FAQ
Question 1
Q: Is this complex approach required because the project is Java? Could a PHP project simply use host‑side code with volume mapping?
A: Splitting code from the container violates container principles and adds handling complexity. All versions should be containerized; even large WAR files (50‑100 MB) are manageable with proper network and performance tuning.
Question 2
Q: What if the code exceeds 500 MB or 1 GB? Should the container be split from the code?
A: If your code reaches 500 MB, it indicates the need for architectural refactoring.
Question 3
Q: In production, is it wasteful for each container to contain the full code base? Would using a shared storage with volume mounts be better?
A: Consistent environments have long been a challenge. While scripts can provide quick fixes, they rarely evolve into robust products. The key is deciding whether containers serve as scheduling units or deployment units.
Additional Note: Scripts often reflect a quick‑and‑dirty ops mindset, lacking scalability and long‑term maintainability.
http://gops2016-shenzhen-tcxtg.eventdove.comSigned-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Efficient Ops
This public account is maintained by Xiaotianguo and friends, regularly publishing widely-read original technical articles. We focus on operations transformation and accompany you throughout your operations career, growing together happily.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
