GitLab CI/CD customization¶
Customize the automated build and deployment pipeline for GitLab Pages.
Overview¶
When you publish a Silex website to GitLab Pages, Silex creates a .gitlab-ci.yml file in your repository. This file defines a CI/CD pipeline that:
- Installs dependencies
- Runs build awesome (powered by Eleventy) to build the static site
- Deploys to GitLab Pages
You can customize the pipeline to add build steps, caching, custom domains, or integration with external services.
Prerequisites¶
- Website stored in GitLab (via GitLab storage connector)
- Basic understanding of GitLab CI/CD
- Knowledge of shell scripts and Node.js
Default pipeline¶
Silex generates a standard .gitlab-ci.yml:
image: node:18
stages:
- build
- deploy
variables:
npm_config_cache: "$CI_PROJECT_DIR/.npm"
cache:
paths:
- .npm
- node_modules
before_script:
- npm ci --prefer-offline --no-audit
build:
stage: build
script:
- npm run build
artifacts:
paths:
- _site/
expire_in: 1 week
pages:
stage: deploy
script:
- echo "Deploying to GitLab Pages"
artifacts:
paths:
- public/
environment:
name: production
url: https://$CI_PROJECT_NAMESPACE.gitlab.io/$CI_PROJECT_NAME
only:
- main
Customizing the pipeline¶
Edit .gitlab-ci.yml directly in your GitLab repository.
Adding a build step¶
Run custom commands after the default build:
build:
stage: build
script:
- npm run build
- npm run lint # Add linting
- npm run test # Add tests
artifacts:
paths:
- _site/
Environment variables¶
Pass secrets or configuration to the pipeline:
Or set in GitLab project settings:
- Go to Settings → CI/CD → Variables
- Add variable:
MY_SECRET=secret-value - Use in pipeline:
$MY_SECRET
Protected variables (only on protected branches):
Artifact retention¶
Control how long build artifacts are kept:
Cache dependencies¶
Speed up builds by caching npm packages:
Or cache only on specific branches:
cache:
key:
files:
- package-lock.json
paths:
- node_modules/
policy: pull # Only pull from cache (never update)
Using different Node versions¶
Build with a specific Node.js version:
Or use a matrix to test multiple versions:
build:
parallel:
matrix:
- NODE_VERSION: [16, 18, 20]
image: node:$NODE_VERSION
script:
- npm run build
Running scripts in parallel¶
Speed up the pipeline by running independent steps in parallel:
stages:
- build
- test
- deploy
build:
stage: build
script:
- npm ci
- npm run build
lint:
stage: test
script:
- npm run lint
test:
stage: test
script:
- npm run test
pages:
stage: deploy
script:
- echo "Deploy"
Conditional execution¶
Only run certain jobs on specific branches:
deploy_production:
stage: deploy
script:
- npm run build:prod
only:
- main # Only on main branch
deploy_staging:
stage: deploy
script:
- npm run build:staging
only:
- develop # Only on develop branch
deploy_manual:
stage: deploy
script:
- npm run build
when: manual # Requires manual trigger
Using Docker images¶
Build with a custom Docker image:
image: mycompany/silex-builder:latest
# Or use multiple images for different jobs
build:
image: node:18-alpine
script:
- npm run build
test:
image: ruby:3.0
script:
- bundle install
- bundle exec rspec
Including external files¶
Share CI/CD configuration across repositories:
include:
- remote: 'https://example.com/ci-templates/silex.yml'
- project: 'my-org/ci-templates'
file: 'silex-base.yml'
- local: '.gitlab/ci-base.yml'
Notifications and integrations¶
Send notifications after builds:
pages:
stage: deploy
script:
- npm run build
after_script:
- 'curl -X POST https://hooks.slack.com/... -d "{"text":"Deployment complete"}"'
Or integrate with external services:
Advanced configuration¶
Custom build for Build awesome¶
If your build awesome setup needs special handling:
build:
stage: build
script:
- npm ci
- npm run eleventy # Custom 11ty build command
- npm run minify-css # Post-processing
artifacts:
paths:
- _site/
Preinstall step¶
Run setup before builds:
Using the silexOverwrite flag¶
Control whether to overwrite existing files on republish:
Set in Silex publishing settings or pass via CI/CD variable.
Custom deployment steps¶
Add cleanup or post-deploy tasks:
pages:
stage: deploy
script:
- echo "Deploying"
after_script:
- echo "Cleaning up"
- rm -rf ./temp/
artifacts:
paths:
- public/
Custom domain configuration¶
Configure a custom domain for GitLab Pages:
pages:
environment:
name: production
url: https://my-custom-domain.com # Custom domain
artifacts:
paths:
- public/
In GitLab project settings, also add the domain:
- Deployments → Pages
- Domains → New domain
- Enter domain and follow DNS setup
URL redirections¶
GitLab Pages supports a _redirects file at the root of the published site, using the same syntax as Netlify redirects. This is useful for:
- Preserving old URLs when you reorganize documentation or pages
- Redirecting short URLs to full paths
- Handling moved content without breaking bookmarks or search engine links
Create a _redirects file in your repository:
Each line has three fields separated by spaces: the old path, the new path, and the HTTP status code (301 for permanent redirect, 302 for temporary).
Make sure the file ends up in the public/ directory after the build. Add a copy step to your pipeline if needed:
pages:
script:
- npm ci
- npx @11ty/eleventy --input=public --output=_site
- cp _redirects _site/ 2>/dev/null || true
- rm -rf public && mv _site public
See GitLab Pages redirects documentation for the full syntax (splat rules, query parameters, forced redirects).
Building and deploying to multiple environments¶
Deploy to production and staging:
stages:
- build
- deploy
build:
stage: build
script:
- npm ci
- npm run build
artifacts:
paths:
- _site/
deploy_prod:
stage: deploy
script:
- echo "Deploy to production"
environment:
name: production
url: https://prod.example.com
only:
- main
deploy_staging:
stage: deploy
script:
- echo "Deploy to staging"
environment:
name: staging
url: https://staging.example.com
only:
- develop
Complete example¶
A full .gitlab-ci.yml with testing, linting, and caching:
image: node:18-alpine
stages:
- install
- build
- test
- deploy
variables:
npm_config_cache: "$CI_PROJECT_DIR/.npm"
NODE_ENV: "production"
cache:
key:
files:
- package-lock.json
paths:
- .npm
- node_modules/
install:
stage: install
script:
- npm ci --prefer-offline --no-audit
build:
stage: build
script:
- npm run build
artifacts:
paths:
- _site/
expire_in: 1 week
lint:
stage: test
script:
- npm run lint:css
- npm run lint:js
allow_failure: true
test:
stage: test
script:
- npm run test
coverage: '/Coverage: (\d+)%/'
pages:
stage: deploy
script:
- mkdir -p public
- cp -r _site/* public/
artifacts:
paths:
- public/
environment:
name: production
url: https://$CI_PROJECT_NAMESPACE.gitlab.io/$CI_PROJECT_NAME
only:
- main
Troubleshooting¶
Pipeline fails with "npm not found"¶
Ensure the Docker image includes Node.js:
Artifacts not deployed¶
Check:
- Artifacts are in
public/directory - Job is in the
deploystage - Job is named
pages onlyrule allows the branch
Pipeline is slow¶
Optimize:
- Add caching for
node_modules/and.npm - Use smaller Docker images (
alpinevariants) - Run jobs in parallel when possible
- Cache external dependencies
Environment URL not working¶
Ensure:
- Domain is correct:
https://username.gitlab.io/project-name - Custom domain DNS is configured
- GitLab Pages is enabled in project settings
See also¶
- GitLab CI/CD docs — Complete reference
- GitLab Pages docs — Pages setup
- build awesome build customization
- Publication hooks