<p>I do not know how how about Jenkins, but GitLab CI has feature called <a href="https://docs.gitlab.com/ee/user/project/pipelines/job_artifacts.html" rel="nofollow noreferrer">artifacts</a> which allow you to</p>

<ul>
<li>explitely share some files/directories between builds</li>
<li>download them from GitLab Pipeline view</li>
</ul>

<p>Additional pro is that allows you to make deployments manual actions.</p>

<p>Also if you are building <a href="https://stackoverflow.com/questions/19150811/what-is-a-fat-jar">fat JARs</a> you do not need Docker for your deployments at all.</p>

<p>So the best solution for you is to have separate task for building release and separate for deployment (which can be manual job or not). </p>

CC BY-SA 3.0
2017-09-06T08:56:49.200Z
Jenkins has artifacts, and has the ability to copy artifacts between tasks.
for docker I think it is better to deploy jar in docker then use docker container in production.
Wissam Roujoulah
CC BY-SA 3.0
2017-09-06T09:21:44.690Z
It is not better and this is not worse either. However Inga general it is quite reasonable to use Ockham’s razor and o not spawn beings needlessly. Docker is one of the possible solution but isn’t always the best one or even the right one. Fat JAR solves the same problem as containerization, so think if Docker is what you need, not follow the herd because it is “fashion” now. Check out other solutions like not using containers at all or using different implementation like rkt.
Hauleth
CC BY-SA 3.0
2017-09-06T12:04:23.940Z
@chupasaurus what? Since when? As far as I know this never was a case.
Hauleth
CC BY-SA 3.0
2017-09-06T12:12:06.820Z
@ŁukaszNiemier my bad, garbage collector haven't been run in my head for a long time.
chupasaurus
CC BY-SA 3.0
2017-09-06T08:13:53.357Z
2017-09-06T08:13:53.357Z
Hauleth
<p>So, assuming Docker and Jenkins are set as stated, I would say your approach covers it: Build Jar in one container, grab the Jar and build an image with it, then build containers from that image for your environments.</p>

<p>For some thoughts on how to set it up:</p>

<p>Have a Docker Host (or swarm) running and start a Jenkins service on it. This is a compose file that I have running:</p>

<pre><code>version: '3.7'

services:
  jenkins-local:
    user: root
    image: jenkinsci/blueocean
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ../../..:/var/projects
      - ./jenkins_home:/var/jenkins_home
    ports:
      - "9000:8080"

volumes:
  jenkins-home:
</code></pre>

<p>The important part is the volume where /var/run/docker.sock of the host is mounted to /var/run/docker.sock of the container. This allows Jenkins to access the host's Docker daemon via the Docker socket (make sure "user" is "root"). Find some reading about this here: <a href="https://getintodevops.com/blog/the-simple-way-to-run-docker-in-docker-for-ci" rel="nofollow noreferrer">https://getintodevops.com/blog/the-simple-way-to-run-docker-in-docker-for-ci</a></p>

<p>The reason why I'd choose the jenkinsci/"blueocean" image is because it allows for usage of blueocean pipelines. <a href="https://jenkins.io/projects/blueocean/" rel="nofollow noreferrer">https://jenkins.io/projects/blueocean/</a></p>

<p>Within pipelines you write Jenkinsfiles to define your build pipelines:</p>

<pre><code>node {
    stage('checkout scm') {
        checkout scm
    }
    stage('Build artifact') {
        // Connect to our Nexus Docker repository with the nexus_jenkins_user user credentials managed in Jenkins
        docker.withRegistry('https://registry.swarm', 'nexus_jenkins_user') {
            // Run a Maven builder image and attach it to the nexus network
            // Add a volume to cache the maven-repo in for consecutive runs
            docker.image('registry.swarm/builder/maven:maven-3.3.9').inside('-v maven-repo:/root/.m2 --network=nexus_nexus') {
                sh 'mvn clean package -Dmaven.test.failure.ignore=true'
            }
        }
    }
    stage('archive artifacts and save test results') {
        archiveArtifacts artifacts: "target/*.jar", fingerprint: true
        junit 'target/surefire-reports/*.xml'
    }
    stage('Build run container image, push Docker image to nexus') {
        docker.withRegistry('https://registry.swarm', 'nexus_jenkins_user') {
            docker.build("app/my-service:current").push()
        }
    }
}
</code></pre>

<p>Since everything happens in Jenkins Workspace, the only important line for the Dockerfile is this one:</p>

<pre><code>COPY ./target/my-service-*.jar ./my-service.jar

CMD [ "java", "-Duser.timezone=UTC", "-jar", "my-service.jar"]
</code></pre>

<p>This will grab the jar, copy it over and use it for the run command in the image.</p>

CC BY-SA 4.0
2019-01-29T19:01:24.393Z
2019-01-29T19:01:24.393Z
Worp
<p>I have a java project, and I'm generating <code>.jar</code> file.
My question is what is the best practice to use docker and jenkins for build and deploy the project?
Is it build the jar with one docker image, then put the Jar file in another docker image and run a container from the last image in the production env or is there a better way to do that?</p>

<jenkins><docker>
What is the best way to deploy a compiled language project with docker and jenkins?
Wissam Roujoulah
# What is the best way to deploy a compiled language project with docker and jenkins?

(Asked by: username_0 on 2017-09-06)

I have a java project, and I'm generating `.jar` file.
My question is what is the best practice to use docker and jenkins for build and deploy the project?
Is it build the jar with one docker image, then put the Jar file in another docker image and run a container from the last image in the production env or is there a better way to do that?

**Tags:** jenkins, docker


---

## 2 answers

### Answer by username_1 on 2017-09-06. Score: 2

I do not know how how about Jenkins, but GitLab CI has feature called [artifacts](https://docs.gitlab.com/ee/user/project/pipelines/job_artifacts.html) which allow you to

* explitely share some files/directories between builds
* download them from GitLab Pipeline view

Additional pro is that allows you to make deployments manual actions.

Also if you are building [fat JARs](https://stackoverflow.com/questions/19150811/what-is-a-fat-jar) you do not need Docker for your deployments at all.

So the best solution for you is to have separate task for building release and separate for deployment (which can be manual job or not).

> **Comments:**
> **username_0**: Jenkins has artifacts, and has the ability to copy artifacts between tasks. for docker I think it is better to deploy jar in docker then use docker container in production.  
> **username_1**: It is not better and this is not worse either. However Inga general it is quite reasonable to use Ockham’s razor and o not spawn beings needlessly. Docker is one of the possible solution but isn’t always the best one or even the right one. Fat JAR solves the same problem as containerization, so think if Docker is what you need, not follow the herd because it is “fashion” now. Check out other solutions like not using containers at all or using different implementation like rkt.  
> **username_1**: @username_2 what? Since when? As far as I know this never was a case.  
> **username_2**: @ŁukaszNiemier my bad, garbage collector haven't been run in my head for a long time.  

---

### Answer by username_3 on 2019-01-29. Score: 0

So, assuming Docker and Jenkins are set as stated, I would say your approach covers it: Build Jar in one container, grab the Jar and build an image with it, then build containers from that image for your environments.
For some thoughts on how to set it up:
Have a Docker Host (or swarm) running and start a Jenkins service on it. This is a compose file that I have running:
version: '3.7'

services:
  jenkins-local:
    user: root
    image: jenkinsci/blueocean
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - ../../..:/var/projects
      - ./jenkins_home:/var/jenkins_home
    ports:
      - "9000:8080"

volumes:
  jenkins-home:

The important part is the volume where /var/run/docker.sock of the host is mounted to /var/run/docker.sock of the container. This allows Jenkins to access the host's Docker daemon via the Docker socket (make sure "user" is "root"). Find some reading about this here: https://getintodevops.com/blog/the-simple-way-to-run-docker-in-docker-for-ci
The reason why I'd choose the jenkinsci/"blueocean" image is because it allows for usage of blueocean pipelines. https://jenkins.io/projects/blueocean/
Within pipelines you write Jenkinsfiles to define your build pipelines:
node {
    stage('checkout scm') {
        checkout scm
    }
    stage('Build artifact') {
        // Connect to our Nexus Docker repository with the nexus_jenkins_user user credentials managed in Jenkins
        docker.withRegistry('https://registry.swarm', 'nexus_jenkins_user') {
            // Run a Maven builder image and attach it to the nexus network
            // Add a volume to cache the maven-repo in for consecutive runs
            docker.image('registry.swarm/builder/maven:maven-3.3.9').inside('-v maven-repo:/root/.m2 --network=nexus_nexus') {
                sh 'mvn clean package -Dmaven.test.failure.ignore=true'
            }
        }
    }
    stage('archive artifacts and save test results') {
        archiveArtifacts artifacts: "target/*.jar", fingerprint: true
        junit 'target/surefire-reports/*.xml'
    }
    stage('Build run container image, push Docker image to nexus') {
        docker.withRegistry('https://registry.swarm', 'nexus_jenkins_user') {
            docker.build("app/my-service:current").push()
        }
    }
}

Since everything happens in Jenkins Workspace, the only important line for the Dockerfile is this one:
COPY ./target/my-service-*.jar ./my-service.jar

CMD [ "java", "-Duser.timezone=UTC", "-jar", "my-service.jar"]

This will grab the jar, copy it over and use it for the run command in the image.


---

