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
- Why the Default Image Fails
- Installing Node.js Manually
- Better Approach: Use a Node.js Image
- Fast, Clean Pipelines
- Summary Comparison
- 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.
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.
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.
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
Approach | Installation Time | Configuration Complexity | GitLab CI Snippet |
---|---|---|---|
Default Ruby image | N/A (fails) | Low | No image field |
Manual Node.js install | ~30 seconds | High | before_script with apt-get commands |
Official Node.js image | <15 seconds | Low | image: node:20-alpine3.18 |
6. Links and References
- GitLab CI/CD pipelines
- GitLab
.gitlab-ci.yml
Reference - Node.js Docker Images
- Debian NodeSource Repository
Watch Video
Watch video content