Skip to content

ArsenSysyn/docker_gerrit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Docker build and run a Gerrit applicaton

For build, test and deploy Gerrit application we use docker containers and docker-compose for more comfortable work with its. And all pipeline for CI/CD is defained in Jenkinsfile.


Dockerfile - build

Dockerfile

So there you can see a Dockerfile for creating our build image based on centos:7 image.

FROM centos:7

WORKDIR /app

COPY . .

RUN yum install curl git zip unzip maven python3 java-11-openjdk-devel -y && \
    curl -fsSL https://rpm.nodesource.com/setup_17.x | bash - && \
    yum install nodejs -y && \
    yum install gcc-c++ make -y && \
    npm install -g bower @bazel/bazelisk && \
    yum remove java-1.8.0-openjdk-devel -y && \
    yum clean all -y

VOLUME ["/root/.cache/bazel/_bazel_root"]

CMD ["/bin/bash", "/app/entrypoint.sh"]
Work directory and install necessary tools

As a work directory we use /app directory which is storing in our repository and copy from them an entrypoint.sh script as an entrypoint step in our image. And the RUN step for installing all necessary tools for build.

Entrypoint

There you can see an entrypoint.sh script there

#!/bin/bash

git clone --recurse-submodules https://gerrit.googlesource.com/gerrit
cd gerrit && bazel build :release

There are some few commands - for cloning repository with application code including submodules and start build application using bazel tool(tool for building and testing code powered by Google).

Volume

And also you can see a volume VOLUME ["/root/.cache/bazel/_bazel_root"] it is using for storing build-cache. But we need it? Because bazel for building code using cache and it rebuild only these things which were changed, so it reduce build and test time.


Dockerfile - app

Dockerfile

So there you can see a Dockerfile for creating our application image based on centos:7 image.

FROM centos:7

ADD entrypoint.sh /
ADD gerrit.war /var/gerrit/bin/gerrit.war

RUN yum -y install initscripts && \
    yum -y install java-11-openjdk && \
    yum -y install git  && \
    yum -y install openssh-server && \
    /entrypoint.sh init && \
    rm -f /var/gerrit/etc/{ssh,secure}* && rm -Rf /var/gerrit/{static,index,logs,data,index,cache,git,db,tmp}/* && \
    yum -y clean all

ENV CANONICAL_WEB_URL=
ENV HTTPD_LISTEN_URL=

# Allow incoming traffic
EXPOSE 29418 8080

VOLUME ["/var/gerrit/git", "/var/gerrit/index", "/var/gerrit/cache", "/var/gerrit/db", "/var/gerrit/etc"]

ENTRYPOINT ["/bin/bash","/entrypoint.sh"]
Work directory and install necessary tools

As a work directory we use /app directory which is storing in our repository and copy from them an entrypoint.sh script as an entrypoint step in our image. And the RUN step for installing all necessary tools for succesful running Gerrit application.

Entrypoint

There you can see an entrypoint.sh script there

#!/bin/bash -e

export JAVA_OPTS='--add-opens java.base/java.net=ALL-UNNAMED --add-opens java.base/java.lang.invoke=ALL-UNNAMED'

if [ ! -d /var/gerrit/git/All-Projects.git ] || [ "$1" == "init" ]
then
  echo "Initializing Gerrit site ..."
  java $JAVA_OPTS -jar /var/gerrit/bin/gerrit.war init --batch --dev -d /var/gerrit
  java $JAVA_OPTS -jar /var/gerrit/bin/gerrit.war reindex -d /var/gerrit
  git config -f /var/gerrit/etc/gerrit.config --add auth.type "DEVELOPMENT_BECOME_ANY_ACCOUNT"
fi

git config -f /var/gerrit/etc/gerrit.config gerrit.canonicalWebUrl "$CANONICAL_WEB_URL"
if [ "$1" != "init" ]
then
  echo "Running Gerrit ..."
  exec /var/gerrit/bin/gerrit.sh run
fi

These commands are using for initialization our application and configuring some necessary options. And the final step - run the application.

Expose

And the EXPOSE 29418 8080 command are necessary for accessing to our application, 8080 - for WEB UI, 29418 - for SSH actions with application.

Volume

And also you can see a volumes

VOLUME ["/var/gerrit/git", 
        "/var/gerrit/index", 
        "/var/gerrit/cache", 
        "/var/gerrit/db", 
        "/var/gerrit/etc"]

These volumes are needed for storing all application data.


Docker-compose

So for more comfortable work with multiple containers we use docker-compose tool. And there you can see a docker-compose.yml

version: "3.7"

services:
   bazel_build:
     build:
        context: ./build
     image: bazel_build
     volumes:
        - bazel_cache:/root/.cache/bazel/_bazel_root
   
   app:
     build: 
        context: ./app 
     image: application 
     volumes:
        - git:/var/gerrit/git
        - etc:/var/gerrit/etc
        - db:/var/gerrit/db
        - index:/var/gerrit/index
        - cache:/var/gerrit/cache
     ports:
        - 8080:8080
        - 29418:29418

volumes:
   bazel_cache:
   git:
   etc:
   db:
   index:
   cache:

So there you can see two services - bazel_build and app, it have all necessary options like working directories, name of future images which will be created using docker-compose build app/bazel_build command from our Dockerfiles, volumes for storing data, and ports for accessing to application.

P.S. docker-compose command we run in our Jenkins


Jenkinsfile

So for our CI/CD process we using Jenkins and there you can see a Jenkinsfile

pipeline{

  agent {label 'arsen'}
  
  environment {
     IP_REMOTE_HOST='10.26.0.246'
  
  }

  stages {


    stage('Test application and build WAR file') {

      steps {
                    sh 'docker-compose -f docker/docker-compose.yml up bazel_test'
          sh 'docker container cp docker_bazel_test_1:/app/gerrit2/bazel-bin/release.war docker/app/gerrit.war'
      }
    }

    stage('Build application image') {

      steps {
          sh 'docker-compose -f docker/docker-compose.yml build app'
      sh 'docker save -o application.tar application'
      }
    }

    stage('Deploy application to remote host') {

      steps {
        sh 'scp application.tar root@${IP_REMOTE_HOST}:/root/application.tar'
      sh 'ssh root@${IP_REMOTE_HOST} docker load -i /root/application.tar'
      sh 'ssh root@${IP_REMOTE_HOST} docker ps -f name=docker_app_1 -q | xargs --no-run-if-empty docker container stop'
      sh 'ssh root@${IP_REMOTE_HOST} docker container ls -a -fname=docker_app_1 -q | xargs -r docker container rm'
      
          sh 'DOCKER_HOST=ssh://root@${IP_REMOTE_HOST} docker-compose -f docker/docker-compose.yml up -d app'
      }
    }

    }

  post {
    always {
           sh 'docker rm docker_bazel_test_1'
            cleanWs(cleanWhenAborted: true, cleanWhenFailure: true, cleanWhenNotBuilt: true, cleanWhenSuccess: true, cleanWhenUnstable: true)
        }
    }

}

But for better understanding of commands I transform it to text and show the result of it. Also a small detail that I used docker-agent with installed docker and docker-compose and also I have an another remote host with it too, where I run my application image. jenkinsfile

About

Build, run and test Gerrit using Docker.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published