GitLab CI/CD: Architecting, Deploying, and Optimizing Pipelines

Architecture Core Concepts

Use Job Images

In this guide, you’ll learn how to run GitLab CI jobs inside a specific Docker image. We’ll demonstrate why relying on the default Ruby image fails for Node.js projects, how to install Node.js manually, and finally how to streamline your pipelines by choosing the right Docker image.

Table of Contents

  1. Why the Default Image Fails
  2. Installing Node.js Manually
  3. Better Approach: Use a Node.js Image
  4. Fast, Clean Pipelines
  5. Summary Comparison
  6. Links and References

1. Why the Default Image Fails

By default, GitLab CI/CD uses the Ruby image. If your job script invokes node -v or npm -v, you’ll see:

workflow:
  name: Exploring GitLab CI Concepts
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      variables:
        DEPLOY_VARIABLE: "~~~~~PRODUCTION~~~~~"

deploy-job:
  resource_group: production
  script:
    - node -v
    - npm -v

Running this produces:

$ node -v
/usr/bin/bash: line 140: node: command not found
ERROR: Job failed: exit code 1

Warning

The default Ruby image does not include Node.js or npm. Always specify an appropriate image or install dependencies yourself.

The image shows a GitLab CI/CD pipeline interface with a project titled "Exploring Gitlab CI Concepts." It displays a running pipeline with a "deploy-job" under the "test" stage.


2. Installing Node.js Manually

A common workaround is to install Node.js in a before_script. First, gather the shell commands:

apt-get update && apt-get install -y ca-certificates curl gnupg
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
  | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] \
  https://deb.nodesource.com/node_20.x nodistro main" \
  | tee /etc/apt/sources.list.d/nodesource.list
apt-get update && apt-get install -y nodejs

Embed these commands in your CI configuration:

workflow:
  name: Exploring GitLab CI Concepts
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      variables:
        DEPLOY_VARIABLE: "~~~~~PRODUCTION~~~~~"

deploy-job:
  resource_group: production
  before_script: |
    apt-get update && apt-get install -y ca-certificates curl gnupg
    curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \
      | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg
    echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] \
      https://deb.nodesource.com/node_20.x nodistro main" \
      | tee /etc/apt/sources.list.d/nodesource.list
    apt-get update && apt-get install -y nodejs
  script:
    - node -v
    - npm -v

Committing this will install Node.js at runtime, but it adds roughly 30 seconds to your job duration.

Note

We removed all sudo references because the default Ruby container lacks sudo.


3. Better Approach: Use a Node.js Image

Instead of installing Node.js on-the-fly, leverage an official Node.js Docker image by specifying the image keyword. This reduces complexity and speeds up execution.

The image shows a GitLab documentation page for CI/CD YAML syntax reference, detailing configuration options and keywords for the `.gitlab-ci.yml` file.

workflow:
  name: Exploring GitLab CI Concepts
  rules:
    - if: '$CI_COMMIT_BRANCH == "main"'
      variables:
        DEPLOY_VARIABLE: "~~~~~PRODUCTION~~~~~"

deploy-job:
  resource_group: production
  image: node:20-alpine3.18
  script:
    - node -v
    - npm -v

4. Fast, Clean Pipelines

With no manual installation steps, your job starts and finishes quickly.

The image shows a GitLab CI/CD pipeline dashboard with a list of pipeline statuses, including running, passed, failed, and canceled. The interface includes options for managing and running pipelines.

Runner output:

Using Docker executor with image node:20-alpine3.18 ...
...
$ node -v
v20.11.0
$ npm -v
10.2.4
Job succeeded

5. Summary Comparison

ApproachInstallation TimeConfiguration ComplexityGitLab CI Snippet
Default Ruby imageN/A (fails)LowNo image field
Manual Node.js install~30 secondsHighbefore_script with apt-get commands
Official Node.js image<15 secondsLowimage: node:20-alpine3.18

Watch Video

Watch video content

Previous
Use Job Timeout