GitLab Pages
DETAILS: Tier: Free, Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated
With GitLab Pages, you can publish static websites directly from a repository in GitLab.
- Use for any personal or business website.
- Use any Static Site Generator (SSG) or plain HTML.
- Create websites for your projects, groups, or user account.
- Host your site on your own GitLab instance or on GitLab.com for free.
- Connect your custom domains and TLS certificates.
- Attribute any license to your content.
To publish a website with Pages, you can use any static site generator, like Gatsby, Jekyll, Hugo, Middleman, Harp, Hexo, or Brunch. You can also publish any website written directly in plain HTML, CSS, and JavaScript.
Pages does not support dynamic server-side processing, for instance, as .php
and .asp
requires.
For more information, see
Static vs dynamic websites.
Getting started
To create a GitLab Pages website:
Document | Description |
---|---|
Use the GitLab UI to create a simple .gitlab-ci.yml |
Add a Pages site to an existing project. Use the UI to set up a simple .gitlab-ci.yml . |
Create a .gitlab-ci.yml file from scratch |
Add a Pages site to an existing project. Learn how to create and configure your own CI file. |
Use a .gitlab-ci.yml template |
Add a Pages site to an existing project. Use a pre-populated CI template file. |
Fork a sample project | Create a new project with Pages already configured by forking a sample project. |
Use a project template | Create a new project with Pages already configured by using a template. |
To update a GitLab Pages website:
Document | Description |
---|---|
GitLab Pages domain names, URLs, and base URLs | Learn about GitLab Pages default domains. |
Explore GitLab Pages | Requirements, technical aspects, specific GitLab CI/CD configuration options, Access Control, custom 404 pages, limitations, and FAQ. |
Custom domains and SSL/TLS Certificates | Custom domains and subdomains, DNS records, and SSL/TLS certificates. |
Let's Encrypt integration | Secure your Pages sites with Let's Encrypt certificates, which are automatically obtained and renewed by GitLab. |
Redirects | Set up HTTP redirects to forward one page to another. |
For more information, see:
Document | Description |
---|---|
Static vs dynamic websites | Static versus dynamic site overview. |
Modern static site generators | SSG overview. |
Build any SSG site with GitLab Pages | Use SSGs for GitLab Pages. |
How it works
To use GitLab Pages, you must create a project in GitLab to upload your website's files to. These projects can be either public, internal, or private.
GitLab always deploys your website from a specific folder called public
in your
repository. When you create a new project in GitLab, a repository
becomes available automatically.
To deploy your site, GitLab uses its built-in tool called GitLab CI/CD
to build your site and publish it to the GitLab Pages server. The sequence of
scripts that GitLab CI/CD runs to accomplish this task is created from a file named
.gitlab-ci.yml
, which you can create and modify.
A specific job
called pages
in the configuration file makes GitLab aware that you're deploying a
GitLab Pages website.
You can either use the GitLab default domain for GitLab Pages websites,
*.gitlab.io
, or your own domain (example.com
). In that case, you
must be an administrator in your domain's registrar (or control panel) to set it up with Pages.
The following diagrams show the workflows you might follow to get started with Pages.
Access to your Pages site
If you're using GitLab Pages default domain (.gitlab.io
), your website is
automatically secure and available under HTTPS. If you're using your own custom
domain, you can optionally secure it with SSL/TLS certificates.
If you're using GitLab.com, your website is publicly available to the internet. To restrict access to your website, enable GitLab Pages Access Control.
If you're using a self-managed instance, your websites are published on your own server, according to the Pages settings chosen by your sysadmin, who can make them public or internal.
Pages examples
These GitLab Pages website examples can teach you advanced techniques to use and adapt for your own needs:
- Posting to your GitLab Pages blog from iOS.
- GitLab CI: Run jobs sequentially, in parallel, or build a custom pipeline.
- GitLab CI: Deployment & environments.
- Building a new GitLab docs site with Nanoc, GitLab CI, and GitLab Pages.
- Publish code coverage reports with GitLab Pages.
Administer GitLab Pages for self-managed instances
If you are running a self-managed instance of GitLab, follow the administration steps to configure Pages.
Watch a video tutorial about how to get started with GitLab Pages administration.
Configure GitLab Pages in a Helm Chart (Kubernetes) instance
To configure GitLab Pages on instances deployed via Helm chart (Kubernetes), use either:
Security for GitLab Pages
.
Namespaces that contain If your username is example
, your GitLab Pages website is located at example.gitlab.io
.
GitLab allows usernames to contain a .
, so a user named bar.example
could create
a GitLab Pages website bar.example.gitlab.io
that effectively is a subdomain of your
example.gitlab.io
website. Be careful if you use JavaScript to set cookies for your website.
The safe way to manually set cookies with JavaScript is to not specify the domain
at all:
// Safe: This cookie is only visible to example.gitlab.io
document.cookie = "key=value";
// Unsafe: This cookie is visible to example.gitlab.io and its subdomains,
// regardless of the presence of the leading dot.
document.cookie = "key=value;domain=.example.gitlab.io";
document.cookie = "key=value;domain=example.gitlab.io";
This issue doesn't affect users with a custom domain, or users who don't set any cookies manually with JavaScript.
Shared cookies
By default, every project in a group shares the same domain, for example, group.gitlab.io
. This means that cookies are also shared for all projects in a group.
To ensure each project uses different cookies, enable the Pages unique domains feature for your project.
Unique domains
- Introduced in GitLab 15.9 with a flag named
pages_unique_domain
. Disabled by default.- Enabled by default in GitLab 15.11.
- Feature flag removed in GitLab 16.3.
By default, every new project uses pages unique domain. This is to avoid projects on the same group to share cookies.
The project maintainer can disable this feature on:
- On the left sidebar, select Search or go to and find your project.
- Select Deploy > Pages.
- Deselect the Use unique domain checkbox.
- Select Save changes.
Create multiple deployments
DETAILS: Tier: Premium, Ultimate Offering: GitLab.com, Self-managed, GitLab Dedicated Status: Experiment
- Introduced in GitLab 16.7 as an experiment with a flag named
pages_multiple_versions_setting
, disabled by default.
FLAG:
On self-managed GitLab, by default this feature is not available. To make it available,
an administrator can enable the feature flag named
pages_multiple_versions_setting
. On GitLab.com and GitLab Dedicated, this feature is not available. This feature is not ready for production use.
Use the pages.path_prefix
CI/CD option to configure a prefix for the GitLab Pages URL.
A prefix allows you to differentiate between multiple GitLab Pages deployments:
- Main Pages deployment: a Pages deployment created with a blank
path_prefix
. - Extra Pages deployment: a Pages deployment created with a non-blank
path_prefix
The value of pages.path_prefix
is:
- Converted to lowercase.
- Shortened to 63 bytes.
- Any character except numbers (
0-9
) and letter (a-z
) is replaced with a hyphen (-
). - Leading and trailing hyphens (
-
) are removed.
Example configuration
Consider a project such as https://gitlab.example.com/namespace/project
. By default, its main Pages deployment can be accessed through:
- When using a unique domain:
https://project-namespace-uniqueid.gitlab.io/
. - When not using a unique domain:
https://namespace.gitlab.io/project
.
If a pages.path_prefix
is configured to the project branch names,
like path_prefix = $CI_COMMIT_BRANCH
, and there's a
branch named username/testing_feature
, this extra Pages deployment would be accessible through:
- When using a unique domain:
https://project-namespace-uniqueid.gitlab.io/username-testing-feature
. - When not using a unique domain:
https://namespace.gitlab.io/project/username-testing-feature
.
Enable multiple deployments
To enable multiple GitLab Pages deployments:
- On the left sidebar, select Search or go to and find your project.
- Select Deploy > Pages.
- Select Use multiple deployments.
Limits
The number of extra deployments is limited by the root-level namespace. For specific limits for:
- GitLab.com, see Other limits.
- Self-managed GitLab instances, see Number of extra Pages deployments when using multiple deployments.
Path clash
pages.path_prefix
can take dynamic values from CI/CD variables
that can create pages deployments which could clash with existing paths in your site.
For example, given an existing GitLab Pages site with the following paths:
/index.html
/documents/index.html
If a pages.path_prefix
is documents
, that version will override the existing path.
In other words, https://namespace.gitlab.io/project/documents/index.html
will point to the
/index.html
on the documents
deployment of the site, instead of documents/index.html
of the
main
deployment of the site.
Mixing CI/CD variables with other strings can reduce the path clash possibility. For example:
pages:
stage: deploy
script:
- echo "Pages accessible through ${CI_PAGES_URL}/${PAGES_PREFIX}"
variables:
PAGES_PREFIX: "" # No prefix by default (master)
pages:
path_prefix: "$PAGES_PREFIX"
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run on default branch (with default PAGES_PREFIX)
- if: $CI_COMMIT_BRANCH == "staging" # Run on master (with default PAGES_PREFIX)
variables:
PAGES_PREFIX: '-stg-' # Prefix with -stg- for the staging branch
- if: $CI_PIPELINE_SOURCE == "merge_request_event" # Conditionally change the prefix for Merge Requests
when: manual # Run pages manually on Merge Requests
variables:
PAGES_PREFIX: 'mr-$CI_MERGE_REQUEST_IID' # Prefix with the mr-<iid>, like `mr-123`
Some other examples of mixing variables with strings for dynamic prefixes:
-
pages.path_prefix: 'mr-$CI_COMMIT_REF_SLUG'
: Branch or tag name prefixed withmr-
, likemr-branch-name
. -
pages.path_prefix: '-${CI_MERGE_REQUEST_IID}-'
: Merge request number prefixed and suffixed with-
, like-123-
.
Use multiple deployments to create pages environments
You can use multiple GitLab Pages deployments to create a new environment. For example:
pages:
stage: deploy
script:
- echo "Pages accessible through ${CI_PAGES_URL}/${PAGES_PREFIX}"
variables:
PAGES_PREFIX: "" # no prefix by default (master)
pages:
path_prefix: "$PAGES_PREFIX"
environment:
name: "Pages ${PAGES_PREFIX}"
url: "${CI_PAGES_URL}/${PAGES_PREFIX}"
artifacts:
paths:
- public
rules:
- if: $CI_COMMIT_BRANCH == "staging" # ensure to run on master (with default PAGES_PREFIX)
variables:
PAGES_PREFIX: '-stg' # prefix with _stg for the staging branch
- if: $CI_PIPELINE_SOURCE == "merge_request_event" # conditionally change the prefix on Merge Requests
when: manual # run pages manually on Merge Requests
variables:
PAGES_PREFIX: 'mr-$CI_MERGE_REQUEST_IID' # prefix with the mr-<iid>, like `mr-123`
With this configuration, users will have the access to each GitLab Pages deployment through the UI. When using environments for pages, all pages environments are listed on the project environment list.
Deployments deletion
Auto-clean
Extra Pages deployments, created by a merge request with a path_prefix
, are automatically deleted when the
merge request is closed or merged.