0

We're using Gitlab for CI/CD. I'll include the script which we're using gitlab ci-cd file

   services:
  - docker:19.03.11-dind
before_script:
  - apk update && apk add bash
  - apk update && apk add gettext  
workflow:
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH == "developer" || $CI_COMMIT_BRANCH == "stage"|| ($CI_COMMIT_BRANCH =~ (/^([A-Z]([0-9][-_])?)?SPRINT(([-_][A-Z][0-9])?)+/i))
      when: always
    - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH || $CI_COMMIT_BRANCH != "developer" || $CI_COMMIT_BRANCH != "stage"|| ($CI_COMMIT_BRANCH !~ (/^([A-Z]([0-9][-_])?)?SPRINT(([-_][A-Z][0-9])?)+/i))
      when: never 
stages:
  - build
  - Publish
  - deploy
cache:
  paths:
    - .m2/repository
    - target

build_jar:
  image: maven:3.8.3-jdk-11
  stage: build
  script: 
    - mvn clean install package -DskipTests=true
  artifacts:
    paths:
      - target/*.jar

docker_build_dev:
  stage: Publish
  image: docker:19.03.11
  services:
    - docker:19.03.11-dind      
  variables:
    IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
  script: 
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $IMAGE_TAG .
    - docker push $IMAGE_TAG
  only:
    - /^([A-Z]([0-9][-_])?)?SPRINT(([-_][A-Z][0-9])?)+/i
    - developer

docker_build_stage:
  stage: Publish
  image: docker:19.03.11
  services:
    - docker:19.03.11-dind   
  variables:
    IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA
  script: 
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $IMAGE_TAG .
    - docker push $IMAGE_TAG   
  only:
    - stage

deploy_dev:
  stage: deploy
  image: stellacenter/aws-helm-kubectl
  variables:
    ENV_VAR_NAME: development
  before_script:
    - aws configure set aws_access_key_id ${DEV_AWS_ACCESS_KEY_ID}
    - aws configure set aws_secret_access_key ${DEV_AWS_SECRET_ACCESS_KEY}
    - aws configure set region ${DEV_AWS_DEFAULT_REGION}
  script:
    - sed -i "s/<VERSION>/${CI_COMMIT_SHORT_SHA}/g" patient-service.yml     
    - mkdir -p  $HOME/.kube
    - cp $KUBE_CONFIG_DEV $HOME/.kube/config
    - chown $(id -u):$(id -g) $HOME/.kube/config 
    - export KUBECONFIG=$HOME/.kube/config
    - cat patient-service.yml | envsubst | kubectl apply -f patient-service.yml -n ${KUBE_NAMESPACE_DEV}
  only:
    - /^([A-Z]([0-9][-_])?)?SPRINT(([-_][A-Z][0-9])?)+/i
    - developer

deploy_stage:
  stage: deploy
  image: stellacenter/aws-helm-kubectl
  variables:
    ENV_VAR_NAME: stage
  before_script:
    - aws configure set aws_access_key_id ${DEV_AWS_ACCESS_KEY_ID}
    - aws configure set aws_secret_access_key ${DEV_AWS_SECRET_ACCESS_KEY}
    - aws configure set region ${DEV_AWS_DEFAULT_REGION}
  script:
    - sed -i "s/<VERSION>/${CI_COMMIT_SHORT_SHA}/g" patient-service.yml    
    - mkdir -p  $HOME/.kube
    - cp $KUBE_CONFIG_STAGE $HOME/.kube/config
    - chown $(id -u):$(id -g) $HOME/.kube/config 
    - export KUBECONFIG=$HOME/.kube/config
    - cat patient-service.yml | envsubst | kubectl apply -f patient-service.yml -n ${KUBE_NAMESPACE_STAGE}
  only:
    - stage

According to the script, we just merged the script not to face conflicts/clashes for stage and development while deployment. Previously, we having each docker files for each environment(stage and developer). Now I want to merge the dockerfile also, I merged, but the dockerfile is not fetching. Having clashes (warning shows after pipeline succeeds) in Kubernetes. I don't know how to clear the warning in Kubernetes. I'll enclose the docker file which I merged.

FROM maven:3.8.3-jdk-11 AS MAVEN_BUILD
COPY pom.xml /build/
COPY src /build/src/
WORKDIR /build/
RUN mvn clean install package -DskipTests=true
FROM openjdk:11
ARG environment_name 
WORKDIR /app
COPY --from=MAVEN_BUILD /build/target/patient-service-*.jar /app/patient-service.jar
ENV PORT 8094
ENV env_var_name=$environment_name
EXPOSE $PORT
ENTRYPOINT ["java","-Dspring.profiles.active= $env_var_name","-jar","/app/patient-service.jar"]

the last line, we used before,

ENTRYPOINT ["java","-Dspring.profiles.active=development","-jar","/app/patient-service.jar"] -for developer dockerfile
ENTRYPOINT ["java","-Dspring.profiles.active=stage","-jar","/app/patient-service.jar"] - for stage dockerfile 

At the time, its working fine, I'm not facing any issue on Kubernetes. I'd just add environment variable to fetch along with whether development or stage. You can check ,my script after the docker build. After adding the variable only, we began facing the clashes. Please help me to sort this out. Thanks in advance.

Yaml file

apiVersion: apps/v1
kind: Deployment
metadata:
  name: patient-app
  labels:
    app: patient-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app : patient-app
  template:
    metadata:
      labels:
        app: patient-app
    spec:
      containers:
      - name: patient-app
        image: registry.gitlab.com/stella-center/backend-services/patient-service:<VERSION>
        imagePullPolicy: Always
        ports:
          - containerPort: 8094
      imagePullSecrets:
        - name:  gitlab-registry-token-auth

---

apiVersion: v1
kind: Service
metadata:
  name:  patient-service
spec:
  type: NodePort
  selector:
    app:  patient-app
  ports:
  - port:  8094
    targetPort:  8094
Cyril I
  • 273
  • 3
  • 16
  • What have you tested ? – Bguess May 23 '22 at 10:52
  • I just run the pipeline , through the ci-cd yaml script. Pipeline was succeed but while checking with the pods , which I rans , its showing some warning like clashes of two environment(developer and stage) @bguess – Cyril I May 23 '22 at 11:23
  • check docker build locally first with env it's working or not, if it;s working locally by passing environment you can check into k8s you are missing env in yaml config as suggested in answer. – Harsh Manvar May 25 '22 at 08:36
  • yes but If I add also it is not working for me! kindly check the below answer which I tried – Cyril I May 25 '22 at 09:41
  • Pipeline has passed , but its showing some warning in k8's (pods) – Cyril I May 25 '22 at 10:09
  • in script wise , its working but again its showing the warning message "back-off restarting failed container" while adding environment variable for docker file – Cyril I May 25 '22 at 13:11

1 Answers1

0

As I understood you want to run the same image built from this docker file in both environments using the variable in the docker file, I would suggest following below:

1- remove "ENV env_var_name=$environment_name" and add ENV_VAR_NAME directly in the ENTRYPOIT (make sure the variable is upper case) as below .

ENV PORT 8094
EXPOSE $PORT
ENTRYPOINT ["java","-Dspring.profiles.active= $ENV_VAR_NAME","-jar","/app/patient-service.jar"]

2- Add this variable as an environment variable in patient-service.yml:

    ...
apiVersion: apps/v1
kind: Deployment
metadata:
  name: patient-app
  labels:
    app: patient-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app : patient-app
  template:
    metadata:
      labels:
        app: patient-app
    spec:
      containers:
      - name: patient-app
        image: registry.gitlab.com/stella-center/backend-services/patient-service:<VERSION>
        imagePullPolicy: Always
        ports:
          - containerPort: 8094
        env:
        - name: ENV_VAR_NAME
          value: "${ENV_VAR_NAME}"
      imagePullSecrets:
        - name:  gitlab-registry-token-auth

3- specify the variable in the GitLab ci yml file each stage with its value and use envsubst with the deployment command:

deploy_dev:
  stage: deploy
  image: stellacenter/aws-helm-kubectl
  variables:
    ENV_VAR_NAME: development
  before_script:
    - apk update && apk add gettext
  ..
  script:
  ..
    - cat patient-service.yml | envsubst | kubectl apply -f -n ${KUBE_NAMESPACE_STAGE} - 
  ...
mohalahmad
  • 76
  • 5
  • In docker build , stage : publish , what should I give? in the script? @mohalahmad – Cyril I May 23 '22 at 12:18
  • "- docker build --build-arg environment_name=development -t $IMAGE_TAG ." "- docker build --build-arg environment_name=stage -t $IMAGE_TAG ." What is the change to be done in this line in publish stage – Cyril I May 23 '22 at 12:32
  • in yaml file, both (kind:deployment) & (kind:service) I want to update env or in one ? – Cyril I May 23 '22 at 12:40
  • Please help me to add the spec content in the yml file which I inserted – Cyril I May 24 '22 at 05:20
  • 1
    for the build no need to pass the env with build command to keep the image general and you can use it in both development and stage environments, this will also require only one build stage instead of two which will make the cicd faster. and regarding the YAML file only adding env to the deployment, I have edited my answer according to the YAML file you added. – mohalahmad May 24 '22 at 05:50
  • $ cat patient-service.yml | envsubst | kubectl apply -f -n ${KUBE_NAMESPACE_DEV} /usr/bin/bash: line 154: envsubst: command not found – Cyril I May 24 '22 at 05:55
  • Please help me to sort this out... !!! For your reference -https://stackoverflow.com/questions/64112268/gitlab-deploy-script-envsubst-command-not-found – Cyril I May 24 '22 at 06:09
  • you can install "gettext" in before_script part of the deploy stage. if the base image is alpine add: apk add gettext – mohalahmad May 24 '22 at 06:11
  • the link in your comment suggests the same thing. – mohalahmad May 24 '22 at 06:12
  • Please help me to add in the script @mohalahmad I'm not have much knowledge in script – Cyril I May 24 '22 at 06:13
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/244969/discussion-between-mohalahmad-and-cyril-i). – mohalahmad May 24 '22 at 06:15
  • in script wise , its working but again its showing the warning message "back-off restarting failed container" – Cyril I May 25 '22 at 13:12