12. Recap

sudo apt update
sudo apt install -y uidmap
curl https://get.docker.com/rootless |sh
echo 'export PATH=/home/ubuntu/bin:$PATH' >> ~/.profile
echo 'export DOCKER_HOST=unix:///run/user/1000/docker.sock' >> ~/.profile
exit

12.1. Source

sudo apt install openjdk-8-jdk maven
sudo update-alternatives --config java
git clone https://github.com/sages-pl/example-helloworld-java.git src/java
git remote set-url origin http://localhost:3000/root/java.git
mvn compile && mvn test && mvn verify
cp -a ~/.m2 .m2
docker build -f Dockerfile.cicd -t myapp:cicd .
FROM alpine:3.15
RUN apk add --no-cache docker git openjdk8 maven
RUN adduser cicd --disabled-password -u 1000 -h /home
COPY .m2 /home/.m2
FROM alpine:3.15
WORKDIR /data
RUN apk add --no-cache openjdk8 maven
COPY . /data
RUN mvn compile
ENTRYPOINT ["mvn"]
pipeline {
  agent {
    docker 'myapp:cicd'
  }
  stages {
    stage('Environment') {
      steps {
        sh 'hostname'
        sh 'id'
        sh 'ifconfig'
        sh 'cat /etc/os-release'
        sh 'uname -a'
        sh 'env |sort'
        sh 'java -version'
        sh 'mvn --version'
        sh 'pwd'
        sh 'echo $JAVA_HOME'
        sh 'echo $PATH'
      }
    }
    stage('Build') {
      steps {
        sh 'mvn compile'
      }
    }
    stage('Test') {
      stage('Unit Test') {
        steps {
          sh 'mvn test'
        }
      }
      stage('Integration Test') {
        steps {
          sh 'mvn verify'
        }
      }
    }
    stage('Static Code Analysis') {
      steps {
        sh 'mvn compile'
        sh 'mvn test'
        sh 'mvn verify'
        sh 'mvn org.pitest:pitest-maven:mutationCoverage'
        sh 'docker run --rm --network ecosystem -v $(pwd):/usr/src sonarsource/sonar-scanner-cli'
      }
    }
    stage('Upload Artifact') {
      steps {
        sh 'docker build . -f Dockerfile.runtime -t localhost:5000/myapp:$(git log -1 --format="%h")'
        sh 'docker push localhost:5000/myapp:$(git log -1 --format="%h")'
        sh 'docker rmi localhost:5000/myapp:$(git log -1 --format="%h")'
      }
    }
  }
  environment {
    JAVA_HOME = '/usr/lib/jvm/java-1.8-openjdk/'
  }
}
## SonarQube
sonar.host.url=http://sonarqube:9000/
sonar.login=e1feddc7144986696d58eb9575e7c78847fab18c

## Project
sonar.projectKey=myjavaproject

## Language
sonar.language=java
sonar.java.source=8

## Paths
sonar.projectBaseDir=/usr/src/
sonar.sources=src/main/java
sonar.exclusions=**/migrations/**
sonar.java.binaries=target/classes
sonar.working.directory=/tmp/

## Build Breaker
sonar.buildbreaker.skip=false
sonar.buildbreaker.queryInterval=10000
sonar.buildbreaker.queryMaxAttempts=1000

12.2. Gitea

  • Gitea Base URL

  • Change Administrator Account Settings: username, password, email

vim ~/bin/run-gitea.sh
chmod +x ~/bin/run-gitea.sh
~/bin/run-gitea.sh
git push origin -u main
docker network create ecosystem

docker run \
    --name gitea \
    --detach \
    --rm \
    --env USER_UID=1000 \
    --env USER_GID=1000 \
    --network ecosystem \
    --publish 3000:3000 \
    --publish 2222:2222 \
    --volume gitea_data:/var/lib/gitea \
    --volume gitea_config:/etc/gitea \
    --volume /etc/timezone:/etc/timezone:ro \
    --volume /etc/localtime:/etc/localtime:ro \
    gitea/gitea:latest-rootless

12.3. Jenkins

  • Install Docker Pipeline plugin

docker exec -itu root jenkins apk add mvn openjdk8
docker network create ecosystem
# sudo chmod o+rw /run/user/1000/docker.sock
sudo ln -s /home/ubuntu/.local/share/docker/volumes/jenkins/_data /var/jenkins_home

docker run \
    --name jenkins \
    --detach \
    --rm \
    --network ecosystem \
    --publish 8080:8080 \
    --volume jenkins:/var/jenkins_home \
    --volume /run/user/1000/docker.sock:/var/run/docker.sock \
    jenkinsci/blueocean

12.4. SonarQube

  • Create user myjavaproject

  • Create token

  • Add user to the project

  • Edit pom.xml in section: <project><build><plugins> add:

<plugin>
    <groupId>org.pitest</groupId>
    <artifactId>pitest-maven</artifactId>
    <version>1.6.1</version>
    <dependencies>
        <dependency>
            <groupId>org.pitest</groupId>
            <artifactId>pitest-junit5-plugin</artifactId>
            <version>0.12</version>
        </dependency>
    </dependencies>
</plugin>
docker network create ecosystem

docker run \
    --name sonarqube \
    --detach \
    --rm \
    --network ecosystem \
    --publish 9000:9000 \
    --volume sonarqube_data:/opt/sonarqube/data \
    --volume sonarqube_logs:/opt/sonarqube/logs \
    --volume sonarqube_extensions:/opt/sonarqube/extensions \
    sonarqube

12.5. Registry

docker network create ecosystem

docker run \
    --detach \
    --rm \
    --name registry \
    --net ecosystem \
    --publish 5000:5000 \
    --volume registry:/var/lib/registry \
    registry:2

12.6. Registry UI

docker volume create registry_ui
vim /home/ubuntu/.local/share/docker/volumes/registry_ui/_data/config.yml
listen_addr: 0.0.0.0:8888
base_path: /
registry_url: http://registry:5000
verify_tls: true
event_listener_token: token
event_retention_days: 7
event_database_driver: sqlite3
event_database_location: data/registry_events.db
cache_refresh_interval: 10
anyone_can_delete: false
admins: []
debug: true
purge_tags_keep_days: 90
purge_tags_keep_count: 2
# registry_username: user
# registry_password: pass
# event_database_driver: mysql
# event_database_location: user:password@tcp(localhost:3306)/docker_events
docker network create ecosystem

docker run \
    --name=registry-ui \
    --detach \
    --rm \
    --network ecosystem \
    --publish 8888:8888 \
    --volume registry_ui:/opt:ro \
    quiq/docker-registry-ui

12.7. Other

Ping

echo 'net.ipv4.ping_group_range = 0 2147483647' |sudo tee -a /etc/sysctl.d/99-docker.conf
sudo sysctl --system