6
\$\begingroup\$

i would really appreciate if anyone could invest a bit of time to review what i did. Basically this is first time i do this, and that is reason why i need another set of eyes.

I have Spring Boot application and i decided to use docker containers on my server to run applications across multiple environments (DEV, QA and PROD). I invested a lot of time to properly research everything and at the end i was able to achieve what i wanted from the beginning.

Basically my code is on GitLab and instead of using jenkins i wanted to take advantage of GitLab CI and simply automatize deployment of my app.

Lets begin, i will start from Dockerfile and it looks like this:

FROM maven:3.6.3-jdk-11-slim AS MAVEN_BUILD

ARG SPRING_ACTIVE_PROFILE

MAINTAINER jmj
COPY pom.xml /build/
COPY src /build/src/
WORKDIR /build/
RUN mvn clean install -Dspring.profiles.active=$SPRING_ACTIVE_PROFILE && mvn package -B -e -Dspring.profiles.active=$SPRING_ACTIVE_PROFILE
FROM openjdk:11-slim
WORKDIR /app

COPY --from=MAVEN_BUILD /build/target/storm-*.jar /app/storm.jar
ENTRYPOINT ["java", "-jar", "storm.jar"]

Dockerfile notes: I had one major issue here, and that is passing dynamically ARG in ENTRYPOINT, to be more specific i wanted to pass active profile, i was able to fix it by passing active profile when doing docker run, which you will see below. Dockerfile question: I am using Java 11 on my project, because it is last LTS version of Java, what i have noticed compared when i used Java 8, is that docker image is really large, a lot of larger than when using Java 8. If i am correct, that is because there is no safe and tested Java 11 alpine image, which at the end produce smaller docker images. My actual question here is: Is my choice of images fine, and is it expected to have image size of ~450MB (on java 8 it was below ~200)

Next lets jump on my .gitlab-ci.yml file.

services:
  - docker:19.03.7-dind

stages:
  - build and push docker image
  - deploy

docker build:
  image: docker:stable
  stage: build and push docker image
  before_script:
    - source .${CI_COMMIT_REF_NAME}.env
  script:
    - docker build --build-arg SPRING_ACTIVE_PROFILE=$SPRING_ACTIVE_PROFILE -t $DOCKER_REPO .
    - docker login -u $DOCKER_USER -p $DOCKER_PASSWORD docker.io
    - docker push $DOCKER_REPO

deploy:
  image: ubuntu:latest
  stage: deploy
  before_script:
    - 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
    - mkdir -p ~/.ssh
    - chmod 700 ~/.ssh
    - echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
    - source .${CI_COMMIT_REF_NAME}.env
  script:
    - ssh root@$SERVER "docker stop $APP_NAME; docker system prune -a -f; docker pull $DOCKER_REPO; docker container run -d --name $APP_NAME -p $PORT:8080 -e SPRING_PROFILES_ACTIVE=$SPRING_ACTIVE_PROFILE $DOCKER_REPO"

Its important to mention that as extension for this file i also have 3 files, with names: .develop.env,.qa.env and .master.env. They represent dynamic variables that i need on different enviorements.

export SPRING_ACTIVE_PROFILE='development'
export DOCKER_REPO="$DOCKER_DEV_REPO"
export APP_NAME="$DEV_APP_NAME"
export PORT='8080'

That is basically it, if anyone can see something that i could improve please let me know. Thank you all in advance.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Fair play, you've clearly done your research here, to answer your first question about the image size, I think 450MB is fine, in my current role, since we're hardening our containers & strapping tonnes of other stuff in, the size of our images gets pretty huge, pretty quickly, but I work for an international financial company so security & enterprise are both must haves. The only thing I can think to suggest is to have all your env files as one, perhaps having pipeline variables to take care of the difference? - But that's optional really, maybe even a matter of opinion & taste. \$\endgroup\$ – JO3-W3B-D3V Mar 19 '20 at 7:48
  • \$\begingroup\$ I have an additional question, why isn't the maven build a part of the Gitlab CI? Rather, it is a part of your container building process...; this would create an additional layer in your docker image, ultimately making it heavier. Is there a specific reason to do so? You could build the jar in the CI, and then just simply copy the jar file from the CI to the image's /app folder. \$\endgroup\$ – Samridh Tuladhar Dec 21 '20 at 6:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.