I have a project that requires npm and gradle for build, and docker for building and pushing the image.
At first I thought that I should create my own ubuntu image with gradle and npm setup, but I found out that is not what docker images are for.
So I hoped to run official Gradle and node images as a service so that my script can call those commands, but that is not happening for some reason.
My .gitlab-ci.yml:
variables:
IMAGE_NAME: my.registry.production/project
IMAGE_TAG: $CI_COMMIT_BRANCH
GIT_SUBMODULE_STRATEGY: recursive
stages:
- build
- deploy
build_project:
stage: build
image: ubuntu:jammy
services:
- name: node:12.20
alias: npm
- name: gradle:6.3.0-jre8
alias: gradle
before_script:
- git submodule init && git submodule update --remote --recursive
script:
- cd project-server && npm install && gradle clean build -Pprod -Pwar -x test -x integrationTest
deploy_image:
stage: deploy
image: docker:20.10.17
services:
- name: docker:20.10.17-dind
alias: docker
variables:
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
DOCKER_DRIVER: overlay2
script:
- docker login -u $REGISTRY_USER -p $REGISTRY_PASSWORD my.registry.production
- docker build -t $IMAGE_NAME:$IMAGE_TAG .
- docker push $IMAGE_NAME:$IMAGE_TAG
If anyone has any info on how to solve this I would greatly appreciate it, since I’m a novice DevOps.
CodePudding user response:
As I know, a docker image is equal to one build. So if you have multiple services you need to build each one into docker image then you can encapsulate all images into docker-compose.yml
file.
I think you can do the following:
- Build the npm project into a docker image
- Build the Gradle project into a docker image
- Write the
docker-compose.yml
file and put both images.
Once you have done it, the pipeline calls the docker-compose.yml
file.
I hope this will be helpful.
CodePudding user response:
Consider a few suggestions based on the fundamental concepts about the deployment in your CI/CD pipeline:
- Remove the services keyword. Reference GitLab's official documents on what the
services
keyword insidegitlab-ci.yaml
file is not for. The feature is used to provide network accessable services to your job runtime (like a database): https://docs.gitlab.com/ee/ci/services/index.html - Your project uses
npm
as a dependency management system, Gradle is a build tool. Both of these pieces of software are more than appropriate to run on the host operating system of the container runtime inside GitLab's Pipeline job. You need these tools to assemble some build artifact as a result of the job on the same host your code has been downloaded on in the Runner. - Think about the overall size of the base image in your
build_project
job and consider how time to download the image over the network on to the Runner will impact your job and overall pipeline duration. If performance can be improved by baking build dependencies into a customDockerfile
do this. If your image is too large, instead use shell commands inside thescript
keyword block to download them at the runtime of the job. There can be pros and cons for both. - Break shell scripts to one command per line for easier troubleshooting of failures in your scripts. You will be able to see the line number of the command which returned a non-zero exit code in your job logs:
... script: - cd project-server - npm install - gradle clean build -Pprod -Pwar -x test -x integrationTest ...
- It's recommended to use the Gradle wrapper (
gradlew
) most of the time instead of thegradle
executable directly. Configure this within your project and check the configuration files for the wrapper into your version control system and this will simplify your build dependency: https://docs.gradle.org/current/userguide/gradle_wrapper.html