Commit 2d80d052 authored by Achilleas Pipinellis's avatar Achilleas Pipinellis

Move all Pages related content to a single location

parent cd92c84b
...@@ -5,4 +5,6 @@ ...@@ -5,4 +5,6 @@
.panel-body .panel-body
%p %p
Learn how to upload your static site and have it served by Learn how to upload your static site and have it served by
GitLab by following the #{link_to "documentation on GitLab Pages", "http://doc.gitlab.com/ee/pages/README.html", target: :blank}. GitLab by following the
= succeed '.' do
= link_to 'documentation on GitLab Pages', help_page_path('user/project/pages/index.md'), target: '_blank'
This document was moved to [pages/index.md](../user/project/pages/index.md).
# GitLab Pages from A to Z: Part 1 This document was moved to [another location](../user/project/pages/getting_started_part_one.md).
- **Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates**
- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_
- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_
----
This is a comprehensive guide, made for those who want to
publish a website with GitLab Pages but aren't familiar with
the entire process involved.
To **enable** GitLab Pages for GitLab CE (Community Edition)
and GitLab EE (Enterprise Edition), please read the
[admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html),
and/or watch this [video tutorial](https://youtu.be/dD8c7WNcc6s).
>**Note:**
For this guide, we assume you already have GitLab Pages
server up and running for your GitLab instance.
## What you need to know before getting started
Before we begin, let's understand a few concepts first.
### Static sites
GitLab Pages only supports static websites, meaning,
your output files must be HTML, CSS, and JavaScript only.
To create your static site, you can either hardcode in HTML,
CSS, and JS, or use a [Static Site Generator (SSG)](https://www.staticgen.com/)
to simplify your code and build the static site for you,
which is highly recommendable and much faster than hardcoding.
---
- Read through this technical overview on [Static versus Dynamic Websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/)
- Understand [how modern Static Site Generators work](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/) and what you can add to your static site
- You can use [any SSG with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/)
- Fork an [example project](https://gitlab.com/pages) to build your website based upon
### GitLab Pages domain
If you set up a GitLab Pages project on GitLab.com,
it will automatically be accessible under a
[subdomain of `namespace.pages.io`](https://docs.gitlab.com/ce/user/project/pages/).
The `namespace` is defined by your username on GitLab.com,
or the group name you created this project under.
>**Note:**
If you use your own GitLab instance to deploy your
site with GitLab Pages, check with your sysadmin what's your
Pages wildcard domain. This guide is valid for any GitLab instance,
you just need to replace Pages wildcard domain on GitLab.com
(`*.gitlab.io`) with your own.
#### Practical examples
**Project Websites:**
- You created a project called `blog` under your username `john`,
therefore your project URL is `https://gitlab.com/john/blog/`.
Once you enable GitLab Pages for this project, and build your site,
it will be available under `https://john.gitlab.io/blog/`.
- You created a group for all your websites called `websites`,
and a project within this group is called `blog`. Your project
URL is `https://gitlab.com/websites/blog/`. Once you enable
GitLab Pages for this project, the site will live under
`https://websites.gitlab.io/blog/`.
**User and Group Websites:**
- Under your username, `john`, you created a project called
`john.gitlab.io`. Your project URL will be `https://gitlab.com/john/john.gitlab.io`.
Once you enable GitLab Pages for your project, your website
will be published under `https://john.gitlab.io`.
- Under your group `websites`, you created a project called
`websites.gitlab.io`. your project's URL will be `https://gitlab.com/websites/websites.gitlab.io`. Once you enable GitLab Pages for your project,
your website will be published under `https://websites.gitlab.io`.
**General example:**
- On GitLab.com, a project site will always be available under
`https://namespace.gitlab.io/project-name`
- On GitLab.com, a user or group website will be available under
`https://namespace.gitlab.io/`
- On your GitLab instance, replace `gitlab.io` above with your
Pages server domain. Ask your sysadmin for this information.
### DNS Records
A Domain Name System (DNS) web service routes visitors to websites
by translating domain names (such as `www.example.com`) into the
numeric IP addresses (such as `192.0.2.1`) that computers use to
connect to each other.
A DNS record is created to point a (sub)domain to a certain location,
which can be an IP address or another domain. In case you want to use
GitLab Pages with your own (sub)domain, you need to access your domain's
registrar control panel to add a DNS record pointing it back to your
GitLab Pages site.
Note that **how to** add DNS records depends on which server your domain
is hosted on. Every control panel has its own place to do it. If you are
not an admin of your domain, and don't have access to your registrar,
you'll need to ask for the technical support of your hosting service
to do it for you.
To help you out, we've gathered some instructions on how to do that
for the most popular hosting services:
- [Amazon](http://docs.aws.amazon.com/gettingstarted/latest/swh/getting-started-configure-route53.html)
- [Bluehost](https://my.bluehost.com/cgi/help/559)
- [CloudFlare](https://support.cloudflare.com/hc/en-us/articles/200169096-How-do-I-add-A-records-)
- [cPanel](https://documentation.cpanel.net/display/ALD/Edit+DNS+Zone)
- [DreamHost](https://help.dreamhost.com/hc/en-us/articles/215414867-How-do-I-add-custom-DNS-records-)
- [Go Daddy](https://www.godaddy.com/help/add-an-a-record-19238)
- [Hostgator](http://support.hostgator.com/articles/changing-dns-records)
- [Inmotion hosting](https://my.bluehost.com/cgi/help/559)
- [Media Temple](https://mediatemple.net/community/products/dv/204403794/how-can-i-change-the-dns-records-for-my-domain)
- [Microsoft](https://msdn.microsoft.com/en-us/library/bb727018.aspx)
If your hosting service is not listed above, you can just try to
search the web for "how to add dns record on <my hosting service>".
#### DNS A record
In case you want to point a root domain (`example.com`) to your
GitLab Pages site, deployed to `namespace.gitlab.io`, you need to
log into your domain's admin control panel and add a DNS `A` record
pointing your domain to Pages' server IP address. For projects on
GitLab.com, this IP is `104.208.235.32`. For projects leaving in
other GitLab instances (CE or EE), please contact your sysadmin
asking for this information (which IP address is Pages server
running on your instance).
**Practical Example:**
![DNS A record pointing to GitLab.com Pages server](img/dns_a_record_example.png)
#### DNS CNAME record
In case you want to point a subdomain (`hello-world.example.com`)
to your GitLab Pages site initially deployed to `namespace.gitlab.io`,
you need to log into your domain's admin control panel and add a DNS
`CNAME` record pointing your subdomain to your website URL
(`namespace.gitlab.io`) address.
Notice that, despite it's a user or project website, the `CNAME`
should point to your Pages domain (`namespace.gitlab.io`),
without any `/project-name`.
**Practical Example:**
![DNS CNAME record pointing to GitLab.com project](img/dns_cname_record_example.png)
#### TL;DR
| From | DNS Record | To |
| ---- | ---------- | -- |
| domain.com | A | 104.208.235.32 |
| subdomain.domain.com | CNAME | namespace.gitlab.io |
> **Notes**:
>
> - **Do not** use a CNAME record if you want to point your
`domain.com` to your GitLab Pages site. Use an `A` record instead.
> - **Do not** add any special chars after the default Pages
domain. E.g., **do not** point your `subdomain.domain.com` to
`namespace.gitlab.io.` or `namespace.gitlab.io/`.
### SSL/TLS Certificates
Every GitLab Pages project on GitLab.com will be available under
HTTPS for the default Pages domain (`*.gitlab.io`). Once you set
up your Pages project with your custom (sub)domain, if you want
it secured by HTTPS, you will have to issue a certificate for that
(sub)domain and install it on your project.
>**Note:**
Certificates are NOT required to add to your custom
(sub)domain on your GitLab Pages project, though they are
highly recommendable.
The importance of having any website securely served under HTTPS
is explained on the introductory section of the blog post
[Secure GitLab Pages with StartSSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/#https-a-quick-overview).
The reason why certificates are so important is that they encrypt
the connection between the **client** (you, me, your visitors)
and the **server** (where you site lives), through a keychain of
authentications and validations.
### Issuing Certificates
GitLab Pages accepts [PEM](https://support.quovadisglobal.com/kb/a37/what-is-pem-format.aspx) certificates issued by
[Certificate Authorities (CA)](https://en.wikipedia.org/wiki/Certificate_authority)
and self-signed certificates. Of course,
[you'd rather issue a certificate than generate a self-signed](https://en.wikipedia.org/wiki/Self-signed_certificate),
for security reasons and for having browsers trusting your
site's certificate.
There are several different kinds of certificates, each one
with certain security level. A static personal website will
not require the same security level as an online banking web app,
for instance. There are a couple Certificate Authorities that
offer free certificates, aiming to make the internet more secure
to everyone. The most popular is [Let's Encrypt](https://letsencrypt.org/),
which issues certificates trusted by most of browsers, it's open
source, and free to use. Please read through this tutorial to
understand [how to secure your GitLab Pages website with Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/).
With the same popularity, there are [certificates issued by CloudFlare](https://www.cloudflare.com/ssl/),
which also offers a [free CDN service](https://blog.cloudflare.com/cloudflares-free-cdn-and-you/).
Their certs are valid up to 15 years. Read through the tutorial on
[how to add a CloudFlare Certificate to your GitLab Pages website](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/).
### Adding certificates to your project
Regardless the CA you choose, the steps to add your certificate to
your Pages project are the same.
#### What do you need
1. A PEM certificate
1. An intermediate certificate
1. A public key
![Pages project - adding certificates](img/add_certificate_to_pages.png)
These fields are found under your **Project**'s **Settings** > **Pages** > **New Domain**.
#### What's what?
- A PEM certificate is the certificate generated by the CA,
which needs to be added to the field **Certificate (PEM)**.
- An [intermediate certificate](https://en.wikipedia.org/wiki/Intermediate_certificate_authority) (aka "root certificate") is
the part of the encryption keychain that identifies the CA.
Usually it's combined with the PEM certificate, but there are
some cases in which you need to add them manually.
[CloudFlare certs](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/)
are one of these cases.
- A public key is an encrypted key which validates
your PEM against your domain.
#### Now what?
Now that you hopefully understand why you need all
of this, it's simple:
- Your PEM certificate needs to be added to the first field
- If your certificate is missing its intermediate, copy
and paste the root certificate (usually available from your CA website)
and paste it in the [same field as your PEM certificate](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/),
just jumping a line between them.
- Copy your public key and paste it in the last field
>**Note:**
**Do not** open certificates or encryption keys in
regular text editors. Always use code editors (such as
Sublime Text, Atom, Dreamweaver, Brackets, etc).
|||
|:--|--:|
||[**Part 2: Quick start guide - Setting up GitLab Pages →**](getting_started_part_two.md)|
# GitLab Pages from A to Z: Part 3 This document was moved to [another location](../user/project/pages/getting_started_part_three.md).
- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_
- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_
- **Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages**
---
## Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages
[GitLab CI](https://about.gitlab.com/gitlab-ci/) serves
numerous purposes, to build, test, and deploy your app
from GitLab through
[Continuous Integration, Continuous Delivery, and Continuous Deployment](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/)
methods. You will need it to build your website with GitLab Pages,
and deploy it to the Pages server.
What this file actually does is telling the
[GitLab Runner](https://docs.gitlab.com/runner/) to run scripts
as you would do from the command line. The Runner acts as your
terminal. GitLab CI tells the Runner which commands to run.
Both are built-in in GitLab, and you don't need to set up
anything for them to work.
Explaining [every detail of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html)
and GitLab Runner is out of the scope of this guide, but we'll
need to understand just a few things to be able to write our own
`.gitlab-ci.yml` or tweak an existing one. It's an
[Yaml](http://docs.ansible.com/ansible/YAMLSyntax.html) file,
with its own syntax. You can always check your CI syntax with
the [GitLab CI Lint Tool](https://gitlab.com/ci/lint).
**Practical Example:**
Let's consider you have a [Jekyll](https://jekyllrb.com/) site.
To build it locally, you would open your terminal, and run `jekyll build`.
Of course, before building it, you had to install Jekyll in your computer.
For that, you had to open your terminal and run `gem install jekyll`.
Right? GitLab CI + GitLab Runner do the same thing. But you need to
write in the `.gitlab-ci.yml` the script you want to run so
GitLab Runner will do it for you. It looks more complicated then it
is. What you need to tell the Runner:
```
$ gem install jekyll
$ jekyll build
```
### Script
To transpose this script to Yaml, it would be like this:
```yaml
script:
- gem install jekyll
- jekyll build
```
### Job
So far so good. Now, each `script`, in GitLab is organized by
a `job`, which is a bunch of scripts and settings you want to
apply to that specific task.
```yaml
job:
script:
- gem install jekyll
- jekyll build
```
For GitLab Pages, this `job` has a specific name, called `pages`,
which tells the Runner you want that task to deploy your website
with GitLab Pages:
```yaml
pages:
script:
- gem install jekyll
- jekyll build
```
### The `public` directory
We also need to tell Jekyll where do you want the website to build,
and GitLab Pages will only consider files in a directory called `public`.
To do that with Jekyll, we need to add a flag specifying the
[destination (`-d`)](https://jekyllrb.com/docs/usage/) of the
built website: `jekyll build -d public`. Of course, we need
to tell this to our Runner:
```yaml
pages:
script:
- gem install jekyll
- jekyll build -d public
```
### Artifacts
We also need to tell the Runner that this _job_ generates
_artifacts_, which is the site built by Jekyll.
Where are these artifacts stored? In the `public` directory:
```yaml
pages:
script:
- gem install jekyll
- jekyll build -d public
artifacts:
paths:
- public
```
The script above would be enough to build your Jekyll
site with GitLab Pages. But, from Jekyll 3.4.0 on, its default
template originated by `jekyll new project` requires
[Bundler](http://bundler.io/) to install Jekyll dependencies
and the default theme. To adjust our script to meet these new
requirements, we only need to install and build Jekyll with Bundler:
```yaml
pages:
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
```
That's it! A `.gitlab-ci.yml` with the content above would deploy
your Jekyll 3.4.0 site with GitLab Pages. This is the minimum
configuration for our example. On the steps below, we'll refine
the script by adding extra options to our GitLab CI.
### Image
At this point, you probably ask yourself: "okay, but to install Jekyll
I need Ruby. Where is Ruby on that script?". The answer is simple: the
first thing GitLab Runner will look for in your `.gitlab-ci.yml` is a
[Docker](https://www.docker.com/) image specifying what do you need in
your container to run that script:
```yaml
image: ruby:2.3
pages:
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
```
In this case, you're telling the Runner to pull this image, which
contains Ruby 2.3 as part of its file system. When you don't specify
this image in your configuration, the Runner will use a default
image, which is Ruby 2.1.
If your SSG needs [NodeJS](https://nodejs.org/) to build, you'll
need to specify which image you want to use, and this image should
contain NodeJS as part of its file system. E.g., for a
[Hexo](https://gitlab.com/pages/hexo) site, you can use `image: node:4.2.2`.
>**Note:**
We're not trying to explain what a Docker image is,
we just need to introduce the concept with a minimum viable
explanation. To know more about Docker images, please visit
their website or take a look at a
[summarized explanation](http://paislee.io/how-to-automate-docker-deployments/) here.
Let's go a little further.
### Branching
If you use GitLab as a version control platform, you will have your
branching strategy to work on your project. Meaning, you will have
other branches in your project, but you'll want only pushes to the
default branch (usually `master`) to be deployed to your website.
To do that, we need to add another line to our CI, telling the Runner
to only perform that _job_ called `pages` on the `master` branch `only`:
```yaml
image: ruby:2.3
pages:
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
```
### Stages
Another interesting concept to keep in mind are build stages.
Your web app can pass through a lot of tests and other tasks
until it's deployed to staging or production environments.
There are three default stages on GitLab CI: build, test,
and deploy. To specify which stage your _job_ is running,
simply add another line to your CI:
```yaml
image: ruby:2.3
pages:
stage: deploy
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
```
You might ask yourself: "why should I bother with stages
at all?" Well, let's say you want to be able to test your
script and check the built site before deploying your site
to production. You want to run the test exactly as your
script will do when you push to `master`. It's simple,
let's add another task (_job_) to our CI, telling it to
test every push to other branches, `except` the `master` branch:
```yaml
image: ruby:2.3
pages:
stage: deploy
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
test:
stage: test
script:
- bundle install
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
```
The `test` job is running on the stage `test`, Jekyll
will build the site in a directory called `test`, and
this job will affect all the branches except `master`.
The best benefit of applying _stages_ to different
_jobs_ is that every job in the same stage builds in
parallel. So, if your web app needs more than one test
before being deployed, you can run all your test at the
same time, it's not necessary to wait one test to finish
to run the other. Of course, this is just a brief
introduction of GitLab CI and GitLab Runner, which are
tools much more powerful than that. This is what you
need to be able to create and tweak your builds for
your GitLab Pages site.
### Before Script
To avoid running the same script multiple times across
your _jobs_, you can add the parameter `before_script`,
in which you specify which commands you want to run for
every single _job_. In our example, notice that we run
`bundle install` for both jobs, `pages` and `test`.
We don't need to repeat it:
```yaml
image: ruby:2.3
before_script:
- bundle install
pages:
stage: deploy
script:
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
test:
stage: test
script:
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
```
### Caching Dependencies
If you want to cache the installation files for your
projects dependencies, for building faster, you can
use the parameter `cache`. For this example, we'll
cache Jekyll dependencies in a `vendor` directory
when we run `bundle install`:
```yaml
image: ruby:2.3
cache:
paths:
- vendor/
before_script:
- bundle install --path vendor
pages:
stage: deploy
script:
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
test:
stage: test
script:
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
```
For this specific case, we need to exclude `/vendor`
from Jekyll `_config.yml` file, otherwise Jekyll will
understand it as a regular directory to build
together with the site:
```yml
exclude:
- vendor
```
There we go! Now our GitLab CI not only builds our website,
but also **continuously test** pushes to feature-branches,
**caches** dependencies installed with Bundler, and
**continuously deploy** every push to the `master` branch.
## Advanced GitLab CI for GitLab Pages
What you can do with GitLab CI is pretty much up to your
creativity. Once you get used to it, you start creating
awesome scripts that automate most of tasks you'd do
manually in the past. Read through the
[documentation of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html)
to understand how to go even further on your scripts.
- On this blog post, understand the concept of
[using GitLab CI `environments` to deploy your
web app to staging and production](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/).
- On this post, learn [how to run jobs sequentially,
in parallel, or build a custom pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/)
- On this blog post, we go through the process of
[pulling specific directories from different projects](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/)
to deploy this website you're looking at, docs.gitlab.com.
- On this blog post, we teach you [how to use GitLab Pages to produce a code coverage report](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/).
|||
|:--|--:|
|[**← Part 2: Quick start guide - Setting up GitLab Pages**](getting_started_part_two.md)||
# GitLab Pages from A to Z: Part 2 This document was moved to [another location](../user/project/pages/getting_started_part_two.md).
> Type: user guide
>
> Level: beginner
- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_
- **Part 2: Quick Start Guide - Setting Up GitLab Pages**
- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_
----
## Setting up GitLab Pages
For a complete step-by-step tutorial, please read the
blog post [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/). The following sections will explain
what do you need and why do you need them.
## What you need to get started
1. A project
1. A configuration file (`.gitlab-ci.yml`) to deploy your site
1. A specific `job` called `pages` in the configuration file
that will make GitLab aware that you are deploying a GitLab Pages website
Optional Features:
1. A custom domain or subdomain
1. A DNS pointing your (sub)domain to your Pages site
1. **Optional**: an SSL/TLS certificate so your custom
domain is accessible under HTTPS.
## Project
Your GitLab Pages project is a regular project created the
same way you do for the other ones. To get started with GitLab Pages, you have two ways:
- Fork one of the templates from Page Examples, or
- Create a new project from scratch
Let's go over both options.
### Fork a project to get started from
To make things easy for you, we've created this
[group](https://gitlab.com/pages) of default projects
containing the most popular SSGs templates.
Watch the [video tutorial](https://youtu.be/TWqh9MtT4Bg) we've
created for the steps below.
1. Choose your SSG template
1. Fork a project from the [Pages group](https://gitlab.com/pages)
1. Remove the fork relationship by navigating to your **Project**'s **Settings** > **Edit Project**
![remove fork relashionship](img/remove_fork_relashionship.png)
1. Enable Shared Runners for your fork: navigate to your **Project**'s **Settings** > **CI/CD Pipelines**
1. Trigger a build (push a change to any file)
1. As soon as the build passes, your website will have been deployed with GitLab Pages. Your website URL will be available under your **Project**'s **Settings** > **Pages**
To turn a **project website** forked from the Pages group into a **user/group** website, you'll need to:
- Rename it to `namespace.gitlab.io`: navigate to **Project**'s **Settings** > **Edit Project** > **Rename repository**
- Adjust your SSG's [base URL](#urls-and-baseurls) to from `"project-name"` to `""`. This setting will be at a different place for each SSG, as each of them have their own structure and file tree. Most likelly, it will be in the SSG's config file.
> **Notes:**
>
>1. Why do I need to remove the fork relationship?
>
> Unless you want to contribute to the original project,
you won't need it connected to the upstream. A
[fork](https://about.gitlab.com/2016/12/01/how-to-keep-your-fork-up-to-date-with-its-origin/#fork)
is useful for submitting merge requests to the upstream.
>
> 2. Why do I need to enable Shared Runners?
>
> Shared Runners will run the script set by your GitLab CI
configuration file. They're enabled by default to new projects,
but not to forks.
### Create a project from scratch
1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**,
click **New project**, and name it considering the
[practical examples](getting_started_part_one.md#practical-examples).
1. Clone it to your local computer, add your website
files to your project, add, commit and push to GitLab.
1. From the your **Project**'s page, click **Set up CI**:
![setup GitLab CI](img/setup_ci.png)
1. Choose one of the templates from the dropbox menu.
Pick up the template corresponding to the SSG you're using (or plain HTML).
![gitlab-ci templates](img/choose_ci_template.png)
Once you have both site files and `.gitlab-ci.yml` in your project's
root, GitLab CI will build your site and deploy it with Pages.
Once the first build passes, you see your site is live by
navigating to your **Project**'s **Settings** > **Pages**,
where you'll find its default URL.
> **Notes:**
>
> - GitLab Pages [supports any SSG](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/), but,
if you don't find yours among the templates, you'll need
to configure your own `.gitlab-ci.yml`. Do do that, please
read through the article [Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md). New SSGs are very welcome among
the [example projects](https://gitlab.com/pages). If you set
up a new one, please
[contribute](https://gitlab.com/pages/pages.gitlab.io/blob/master/CONTRIBUTING.md)
to our examples.
>
> - The second step _"Clone it to your local computer"_, can be done
differently, achieving the same results: instead of cloning the bare
repository to you local computer and moving your site files into it,
you can run `git init` in your local website directory, add the
remote URL: `git remote add origin git@gitlab.com:namespace/project-name.git`,
then add, commit, and push.
### URLs and Baseurls
Every Static Site Generator (SSG) default configuration expects
to find your website under a (sub)domain (`example.com`), not
in a subdirectory of that domain (`example.com/subdir`). Therefore,
whenever you publish a project website (`namespace.gitlab.io/project-name`),
you'll have to look for this configuration (base URL) on your SSG's
documentation and set it up to reflect this pattern.
For example, for a Jekyll site, the `baseurl` is defined in the Jekyll
configuration file, `_config.yml`. If your website URL is
`https://john.gitlab.io/blog/`, you need to add this line to `_config.yml`:
```yaml
baseurl: "/blog"
```
On the contrary, if you deploy your website after forking one of
our [default examples](https://gitlab.com/pages), the baseurl will
already be configured this way, as all examples there are project
websites. If you decide to make yours a user or group website, you'll
have to remove this configuration from your project. For the Jekyll
example we've just mentioned, you'd have to change Jekyll's `_config.yml` to:
```yaml
baseurl: ""
```
|||
|:--|--:|
|[**← Part 1: Static sites, domains, DNS records, and SSL/TLS certificates**](getting_started_part_one.md)|[**Part 3: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages →**](getting_started_part_three.md)|
# All you need to know about GitLab Pages
With GitLab Pages you can create static websites for your GitLab projects,
groups, or user accounts. You can use any static website generator: Jekyll,
Middleman, Hexo, Hugo, Pelican, you name it! Connect as many customs domains
as you like and bring your own TLS certificate to secure them.
Here's some info we have gathered to get you started.
## General info
- [Product webpage](https://pages.gitlab.io)
- [We're bringing GitLab Pages to CE](https://about.gitlab.com/2016/12/24/were-bringing-gitlab-pages-to-community-edition/)
- [Pages group - templates](https://gitlab.com/pages)
## Getting started
- GitLab Pages from A to Z
- [Part 1: Static sites, domains, DNS records, and SSL/TLS certificates](getting_started_part_one.md)
- [Part 2: Quick start guide - Setting up GitLab Pages](getting_started_part_two.md)
- [Part 3: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)
- [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) a comprehensive step-by-step guide
- Secure GitLab Pages custom domain with SSL/TLS certificates
- [Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/)
- [CloudFlare](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/)
- [StartSSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/)
- Static Site Generators - Blog posts series
- [SSGs part 1: Static vs dynamic websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/)
- [SSGs part 2: Modern static site generators](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/)
- [SSGs part 3: Build any SSG site with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/)
- [Posting to your GitLab Pages blog from iOS](https://about.gitlab.com/2016/08/19/posting-to-your-gitlab-pages-blog-from-ios/)
## Video tutorials
- [How to publish a website with GitLab Pages on GitLab.com: from a forked project](https://youtu.be/TWqh9MtT4Bg)
- [How to Enable GitLab Pages for GitLab CE and EE](https://youtu.be/dD8c7WNcc6s)
## Advanced use
- Blog Posts:
- [GitLab CI: Run jobs sequentially, in parallel, or build a custom pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/)
- [GitLab CI: Deployment & environments](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/)
- [Building a new GitLab docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/)
- [Publish code coverage reports with GitLab Pages](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/)
## Specific documentation
- [User docs](../user/project/pages/index.md)
- [Admin docs](../administration/pages/index.md)
# GitLab Pages from A to Z: Part 1
- **Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates**
- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_
- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_
----
This is a comprehensive guide, made for those who want to
publish a website with GitLab Pages but aren't familiar with
the entire process involved.
To **enable** GitLab Pages for GitLab CE (Community Edition)
and GitLab EE (Enterprise Edition), please read the
[admin documentation](https://docs.gitlab.com/ce/administration/pages/index.html),
and/or watch this [video tutorial](https://youtu.be/dD8c7WNcc6s).
>**Note:**
For this guide, we assume you already have GitLab Pages
server up and running for your GitLab instance.
## What you need to know before getting started
Before we begin, let's understand a few concepts first.
### Static sites
GitLab Pages only supports static websites, meaning,
your output files must be HTML, CSS, and JavaScript only.
To create your static site, you can either hardcode in HTML,
CSS, and JS, or use a [Static Site Generator (SSG)](https://www.staticgen.com/)
to simplify your code and build the static site for you,
which is highly recommendable and much faster than hardcoding.
---
- Read through this technical overview on [Static versus Dynamic Websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/)
- Understand [how modern Static Site Generators work](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/) and what you can add to your static site
- You can use [any SSG with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/)
- Fork an [example project](https://gitlab.com/pages) to build your website based upon
### GitLab Pages domain
If you set up a GitLab Pages project on GitLab.com,
it will automatically be accessible under a
[subdomain of `namespace.pages.io`](https://docs.gitlab.com/ce/user/project/pages/).
The `namespace` is defined by your username on GitLab.com,
or the group name you created this project under.
>**Note:**
If you use your own GitLab instance to deploy your
site with GitLab Pages, check with your sysadmin what's your
Pages wildcard domain. This guide is valid for any GitLab instance,
you just need to replace Pages wildcard domain on GitLab.com
(`*.gitlab.io`) with your own.
#### Practical examples
**Project Websites:**
- You created a project called `blog` under your username `john`,
therefore your project URL is `https://gitlab.com/john/blog/`.
Once you enable GitLab Pages for this project, and build your site,
it will be available under `https://john.gitlab.io/blog/`.
- You created a group for all your websites called `websites`,
and a project within this group is called `blog`. Your project
URL is `https://gitlab.com/websites/blog/`. Once you enable
GitLab Pages for this project, the site will live under
`https://websites.gitlab.io/blog/`.
**User and Group Websites:**
- Under your username, `john`, you created a project called
`john.gitlab.io`. Your project URL will be `https://gitlab.com/john/john.gitlab.io`.
Once you enable GitLab Pages for your project, your website
will be published under `https://john.gitlab.io`.
- Under your group `websites`, you created a project called
`websites.gitlab.io`. your project's URL will be `https://gitlab.com/websites/websites.gitlab.io`. Once you enable GitLab Pages for your project,
your website will be published under `https://websites.gitlab.io`.
**General example:**
- On GitLab.com, a project site will always be available under
`https://namespace.gitlab.io/project-name`
- On GitLab.com, a user or group website will be available under
`https://namespace.gitlab.io/`
- On your GitLab instance, replace `gitlab.io` above with your
Pages server domain. Ask your sysadmin for this information.
### DNS Records
A Domain Name System (DNS) web service routes visitors to websites
by translating domain names (such as `www.example.com`) into the
numeric IP addresses (such as `192.0.2.1`) that computers use to
connect to each other.
A DNS record is created to point a (sub)domain to a certain location,
which can be an IP address or another domain. In case you want to use
GitLab Pages with your own (sub)domain, you need to access your domain's
registrar control panel to add a DNS record pointing it back to your
GitLab Pages site.
Note that **how to** add DNS records depends on which server your domain
is hosted on. Every control panel has its own place to do it. If you are
not an admin of your domain, and don't have access to your registrar,
you'll need to ask for the technical support of your hosting service
to do it for you.
To help you out, we've gathered some instructions on how to do that
for the most popular hosting services:
- [Amazon](http://docs.aws.amazon.com/gettingstarted/latest/swh/getting-started-configure-route53.html)
- [Bluehost](https://my.bluehost.com/cgi/help/559)
- [CloudFlare](https://support.cloudflare.com/hc/en-us/articles/200169096-How-do-I-add-A-records-)
- [cPanel](https://documentation.cpanel.net/display/ALD/Edit+DNS+Zone)
- [DreamHost](https://help.dreamhost.com/hc/en-us/articles/215414867-How-do-I-add-custom-DNS-records-)
- [Go Daddy](https://www.godaddy.com/help/add-an-a-record-19238)
- [Hostgator](http://support.hostgator.com/articles/changing-dns-records)
- [Inmotion hosting](https://my.bluehost.com/cgi/help/559)
- [Media Temple](https://mediatemple.net/community/products/dv/204403794/how-can-i-change-the-dns-records-for-my-domain)
- [Microsoft](https://msdn.microsoft.com/en-us/library/bb727018.aspx)
If your hosting service is not listed above, you can just try to
search the web for "how to add dns record on <my hosting service>".
#### DNS A record
In case you want to point a root domain (`example.com`) to your
GitLab Pages site, deployed to `namespace.gitlab.io`, you need to
log into your domain's admin control panel and add a DNS `A` record
pointing your domain to Pages' server IP address. For projects on
GitLab.com, this IP is `104.208.235.32`. For projects leaving in
other GitLab instances (CE or EE), please contact your sysadmin
asking for this information (which IP address is Pages server
running on your instance).
**Practical Example:**
![DNS A record pointing to GitLab.com Pages server](img/dns_a_record_example.png)
#### DNS CNAME record
In case you want to point a subdomain (`hello-world.example.com`)
to your GitLab Pages site initially deployed to `namespace.gitlab.io`,
you need to log into your domain's admin control panel and add a DNS
`CNAME` record pointing your subdomain to your website URL
(`namespace.gitlab.io`) address.
Notice that, despite it's a user or project website, the `CNAME`
should point to your Pages domain (`namespace.gitlab.io`),
without any `/project-name`.
**Practical Example:**
![DNS CNAME record pointing to GitLab.com project](img/dns_cname_record_example.png)
#### TL;DR
| From | DNS Record | To |
| ---- | ---------- | -- |
| domain.com | A | 104.208.235.32 |
| subdomain.domain.com | CNAME | namespace.gitlab.io |
> **Notes**:
>
> - **Do not** use a CNAME record if you want to point your
`domain.com` to your GitLab Pages site. Use an `A` record instead.
> - **Do not** add any special chars after the default Pages
domain. E.g., **do not** point your `subdomain.domain.com` to
`namespace.gitlab.io.` or `namespace.gitlab.io/`.
### SSL/TLS Certificates
Every GitLab Pages project on GitLab.com will be available under
HTTPS for the default Pages domain (`*.gitlab.io`). Once you set
up your Pages project with your custom (sub)domain, if you want
it secured by HTTPS, you will have to issue a certificate for that
(sub)domain and install it on your project.
>**Note:**
Certificates are NOT required to add to your custom
(sub)domain on your GitLab Pages project, though they are
highly recommendable.
The importance of having any website securely served under HTTPS
is explained on the introductory section of the blog post
[Secure GitLab Pages with StartSSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/#https-a-quick-overview).
The reason why certificates are so important is that they encrypt
the connection between the **client** (you, me, your visitors)
and the **server** (where you site lives), through a keychain of
authentications and validations.
### Issuing Certificates
GitLab Pages accepts [PEM](https://support.quovadisglobal.com/kb/a37/what-is-pem-format.aspx) certificates issued by
[Certificate Authorities (CA)](https://en.wikipedia.org/wiki/Certificate_authority)
and self-signed certificates. Of course,
[you'd rather issue a certificate than generate a self-signed](https://en.wikipedia.org/wiki/Self-signed_certificate),
for security reasons and for having browsers trusting your
site's certificate.
There are several different kinds of certificates, each one
with certain security level. A static personal website will
not require the same security level as an online banking web app,
for instance. There are a couple Certificate Authorities that
offer free certificates, aiming to make the internet more secure
to everyone. The most popular is [Let's Encrypt](https://letsencrypt.org/),
which issues certificates trusted by most of browsers, it's open
source, and free to use. Please read through this tutorial to
understand [how to secure your GitLab Pages website with Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/).
With the same popularity, there are [certificates issued by CloudFlare](https://www.cloudflare.com/ssl/),
which also offers a [free CDN service](https://blog.cloudflare.com/cloudflares-free-cdn-and-you/).
Their certs are valid up to 15 years. Read through the tutorial on
[how to add a CloudFlare Certificate to your GitLab Pages website](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/).
### Adding certificates to your project
Regardless the CA you choose, the steps to add your certificate to
your Pages project are the same.
#### What do you need
1. A PEM certificate
1. An intermediate certificate
1. A public key
![Pages project - adding certificates](img/add_certificate_to_pages.png)
These fields are found under your **Project**'s **Settings** > **Pages** > **New Domain**.
#### What's what?
- A PEM certificate is the certificate generated by the CA,
which needs to be added to the field **Certificate (PEM)**.
- An [intermediate certificate](https://en.wikipedia.org/wiki/Intermediate_certificate_authority) (aka "root certificate") is
the part of the encryption keychain that identifies the CA.
Usually it's combined with the PEM certificate, but there are
some cases in which you need to add them manually.
[CloudFlare certs](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/)
are one of these cases.
- A public key is an encrypted key which validates
your PEM against your domain.
#### Now what?
Now that you hopefully understand why you need all
of this, it's simple:
- Your PEM certificate needs to be added to the first field
- If your certificate is missing its intermediate, copy
and paste the root certificate (usually available from your CA website)
and paste it in the [same field as your PEM certificate](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/),
just jumping a line between them.
- Copy your public key and paste it in the last field
>**Note:**
**Do not** open certificates or encryption keys in
regular text editors. Always use code editors (such as
Sublime Text, Atom, Dreamweaver, Brackets, etc).
|||
|:--|--:|
||[**Part 2: Quick start guide - Setting up GitLab Pages →**](getting_started_part_two.md)|
# GitLab Pages from A to Z: Part 3
- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_
- _[Part 2: Quick Start Guide - Setting Up GitLab Pages](getting_started_part_two.md)_
- **Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages**
---
## Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages
[GitLab CI](https://about.gitlab.com/gitlab-ci/) serves
numerous purposes, to build, test, and deploy your app
from GitLab through
[Continuous Integration, Continuous Delivery, and Continuous Deployment](https://about.gitlab.com/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/)
methods. You will need it to build your website with GitLab Pages,
and deploy it to the Pages server.
What this file actually does is telling the
[GitLab Runner](https://docs.gitlab.com/runner/) to run scripts
as you would do from the command line. The Runner acts as your
terminal. GitLab CI tells the Runner which commands to run.
Both are built-in in GitLab, and you don't need to set up
anything for them to work.
Explaining [every detail of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html)
and GitLab Runner is out of the scope of this guide, but we'll
need to understand just a few things to be able to write our own
`.gitlab-ci.yml` or tweak an existing one. It's an
[Yaml](http://docs.ansible.com/ansible/YAMLSyntax.html) file,
with its own syntax. You can always check your CI syntax with
the [GitLab CI Lint Tool](https://gitlab.com/ci/lint).
**Practical Example:**
Let's consider you have a [Jekyll](https://jekyllrb.com/) site.
To build it locally, you would open your terminal, and run `jekyll build`.
Of course, before building it, you had to install Jekyll in your computer.
For that, you had to open your terminal and run `gem install jekyll`.
Right? GitLab CI + GitLab Runner do the same thing. But you need to
write in the `.gitlab-ci.yml` the script you want to run so
GitLab Runner will do it for you. It looks more complicated then it
is. What you need to tell the Runner:
```
$ gem install jekyll
$ jekyll build
```
### Script
To transpose this script to Yaml, it would be like this:
```yaml
script:
- gem install jekyll
- jekyll build
```
### Job
So far so good. Now, each `script`, in GitLab is organized by
a `job`, which is a bunch of scripts and settings you want to
apply to that specific task.
```yaml
job:
script:
- gem install jekyll
- jekyll build
```
For GitLab Pages, this `job` has a specific name, called `pages`,
which tells the Runner you want that task to deploy your website
with GitLab Pages:
```yaml
pages:
script:
- gem install jekyll
- jekyll build
```
### The `public` directory
We also need to tell Jekyll where do you want the website to build,
and GitLab Pages will only consider files in a directory called `public`.
To do that with Jekyll, we need to add a flag specifying the
[destination (`-d`)](https://jekyllrb.com/docs/usage/) of the
built website: `jekyll build -d public`. Of course, we need
to tell this to our Runner:
```yaml
pages:
script:
- gem install jekyll
- jekyll build -d public
```
### Artifacts
We also need to tell the Runner that this _job_ generates
_artifacts_, which is the site built by Jekyll.
Where are these artifacts stored? In the `public` directory:
```yaml
pages:
script:
- gem install jekyll
- jekyll build -d public
artifacts:
paths:
- public
```
The script above would be enough to build your Jekyll
site with GitLab Pages. But, from Jekyll 3.4.0 on, its default
template originated by `jekyll new project` requires
[Bundler](http://bundler.io/) to install Jekyll dependencies
and the default theme. To adjust our script to meet these new
requirements, we only need to install and build Jekyll with Bundler:
```yaml
pages:
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
```
That's it! A `.gitlab-ci.yml` with the content above would deploy
your Jekyll 3.4.0 site with GitLab Pages. This is the minimum
configuration for our example. On the steps below, we'll refine
the script by adding extra options to our GitLab CI.
### Image
At this point, you probably ask yourself: "okay, but to install Jekyll
I need Ruby. Where is Ruby on that script?". The answer is simple: the
first thing GitLab Runner will look for in your `.gitlab-ci.yml` is a
[Docker](https://www.docker.com/) image specifying what do you need in
your container to run that script:
```yaml
image: ruby:2.3
pages:
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
```
In this case, you're telling the Runner to pull this image, which
contains Ruby 2.3 as part of its file system. When you don't specify
this image in your configuration, the Runner will use a default
image, which is Ruby 2.1.
If your SSG needs [NodeJS](https://nodejs.org/) to build, you'll
need to specify which image you want to use, and this image should
contain NodeJS as part of its file system. E.g., for a
[Hexo](https://gitlab.com/pages/hexo) site, you can use `image: node:4.2.2`.
>**Note:**
We're not trying to explain what a Docker image is,
we just need to introduce the concept with a minimum viable
explanation. To know more about Docker images, please visit
their website or take a look at a
[summarized explanation](http://paislee.io/how-to-automate-docker-deployments/) here.
Let's go a little further.
### Branching
If you use GitLab as a version control platform, you will have your
branching strategy to work on your project. Meaning, you will have
other branches in your project, but you'll want only pushes to the
default branch (usually `master`) to be deployed to your website.
To do that, we need to add another line to our CI, telling the Runner
to only perform that _job_ called `pages` on the `master` branch `only`:
```yaml
image: ruby:2.3
pages:
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
```
### Stages
Another interesting concept to keep in mind are build stages.
Your web app can pass through a lot of tests and other tasks
until it's deployed to staging or production environments.
There are three default stages on GitLab CI: build, test,
and deploy. To specify which stage your _job_ is running,
simply add another line to your CI:
```yaml
image: ruby:2.3
pages:
stage: deploy
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
```
You might ask yourself: "why should I bother with stages
at all?" Well, let's say you want to be able to test your
script and check the built site before deploying your site
to production. You want to run the test exactly as your
script will do when you push to `master`. It's simple,
let's add another task (_job_) to our CI, telling it to
test every push to other branches, `except` the `master` branch:
```yaml
image: ruby:2.3
pages:
stage: deploy
script:
- bundle install
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
test:
stage: test
script:
- bundle install
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
```
The `test` job is running on the stage `test`, Jekyll
will build the site in a directory called `test`, and
this job will affect all the branches except `master`.
The best benefit of applying _stages_ to different
_jobs_ is that every job in the same stage builds in
parallel. So, if your web app needs more than one test
before being deployed, you can run all your test at the
same time, it's not necessary to wait one test to finish
to run the other. Of course, this is just a brief
introduction of GitLab CI and GitLab Runner, which are
tools much more powerful than that. This is what you
need to be able to create and tweak your builds for
your GitLab Pages site.
### Before Script
To avoid running the same script multiple times across
your _jobs_, you can add the parameter `before_script`,
in which you specify which commands you want to run for
every single _job_. In our example, notice that we run
`bundle install` for both jobs, `pages` and `test`.
We don't need to repeat it:
```yaml
image: ruby:2.3
before_script:
- bundle install
pages:
stage: deploy
script:
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
test:
stage: test
script:
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
```
### Caching Dependencies
If you want to cache the installation files for your
projects dependencies, for building faster, you can
use the parameter `cache`. For this example, we'll
cache Jekyll dependencies in a `vendor` directory
when we run `bundle install`:
```yaml
image: ruby:2.3
cache:
paths:
- vendor/
before_script:
- bundle install --path vendor
pages:
stage: deploy
script:
- bundle exec jekyll build -d public
artifacts:
paths:
- public
only:
- master
test:
stage: test
script:
- bundle exec jekyll build -d test
artifacts:
paths:
- test
except:
- master
```
For this specific case, we need to exclude `/vendor`
from Jekyll `_config.yml` file, otherwise Jekyll will
understand it as a regular directory to build
together with the site:
```yml
exclude:
- vendor
```
There we go! Now our GitLab CI not only builds our website,
but also **continuously test** pushes to feature-branches,
**caches** dependencies installed with Bundler, and
**continuously deploy** every push to the `master` branch.
## Advanced GitLab CI for GitLab Pages
What you can do with GitLab CI is pretty much up to your
creativity. Once you get used to it, you start creating
awesome scripts that automate most of tasks you'd do
manually in the past. Read through the
[documentation of GitLab CI](https://docs.gitlab.com/ce/ci/yaml/README.html)
to understand how to go even further on your scripts.
- On this blog post, understand the concept of
[using GitLab CI `environments` to deploy your
web app to staging and production](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/).
- On this post, learn [how to run jobs sequentially,
in parallel, or build a custom pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/)
- On this blog post, we go through the process of
[pulling specific directories from different projects](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/)
to deploy this website you're looking at, docs.gitlab.com.
- On this blog post, we teach you [how to use GitLab Pages to produce a code coverage report](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/).
|||
|:--|--:|
|[**← Part 2: Quick start guide - Setting up GitLab Pages**](getting_started_part_two.md)||
# GitLab Pages from A to Z: Part 2
> Type: user guide
>
> Level: beginner
- _[Part 1: Static Sites, Domains, DNS Records, and SSL/TLS Certificates](getting_started_part_one.md)_
- **Part 2: Quick Start Guide - Setting Up GitLab Pages**
- _[Part 3: Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)_
----
## Setting up GitLab Pages
For a complete step-by-step tutorial, please read the
blog post [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/). The following sections will explain
what do you need and why do you need them.
## What you need to get started
1. A project
1. A configuration file (`.gitlab-ci.yml`) to deploy your site
1. A specific `job` called `pages` in the configuration file
that will make GitLab aware that you are deploying a GitLab Pages website
Optional Features:
1. A custom domain or subdomain
1. A DNS pointing your (sub)domain to your Pages site
1. **Optional**: an SSL/TLS certificate so your custom
domain is accessible under HTTPS.
## Project
Your GitLab Pages project is a regular project created the
same way you do for the other ones. To get started with GitLab Pages, you have two ways:
- Fork one of the templates from Page Examples, or
- Create a new project from scratch
Let's go over both options.
### Fork a project to get started from
To make things easy for you, we've created this
[group](https://gitlab.com/pages) of default projects
containing the most popular SSGs templates.
Watch the [video tutorial](https://youtu.be/TWqh9MtT4Bg) we've
created for the steps below.
1. Choose your SSG template
1. Fork a project from the [Pages group](https://gitlab.com/pages)
1. Remove the fork relationship by navigating to your **Project**'s **Settings** > **Edit Project**
![remove fork relashionship](img/remove_fork_relashionship.png)
1. Enable Shared Runners for your fork: navigate to your **Project**'s **Settings** > **CI/CD Pipelines**
1. Trigger a build (push a change to any file)
1. As soon as the build passes, your website will have been deployed with GitLab Pages. Your website URL will be available under your **Project**'s **Settings** > **Pages**
To turn a **project website** forked from the Pages group into a **user/group** website, you'll need to:
- Rename it to `namespace.gitlab.io`: navigate to **Project**'s **Settings** > **Edit Project** > **Rename repository**
- Adjust your SSG's [base URL](#urls-and-baseurls) to from `"project-name"` to `""`. This setting will be at a different place for each SSG, as each of them have their own structure and file tree. Most likelly, it will be in the SSG's config file.
> **Notes:**
>
>1. Why do I need to remove the fork relationship?
>
> Unless you want to contribute to the original project,
you won't need it connected to the upstream. A
[fork](https://about.gitlab.com/2016/12/01/how-to-keep-your-fork-up-to-date-with-its-origin/#fork)
is useful for submitting merge requests to the upstream.
>
> 2. Why do I need to enable Shared Runners?
>
> Shared Runners will run the script set by your GitLab CI
configuration file. They're enabled by default to new projects,
but not to forks.
### Create a project from scratch
1. From your **Project**'s **[Dashboard](https://gitlab.com/dashboard/projects)**,
click **New project**, and name it considering the
[practical examples](getting_started_part_one.md#practical-examples).
1. Clone it to your local computer, add your website
files to your project, add, commit and push to GitLab.
1. From the your **Project**'s page, click **Set up CI**:
![setup GitLab CI](img/setup_ci.png)
1. Choose one of the templates from the dropbox menu.
Pick up the template corresponding to the SSG you're using (or plain HTML).
![gitlab-ci templates](img/choose_ci_template.png)
Once you have both site files and `.gitlab-ci.yml` in your project's
root, GitLab CI will build your site and deploy it with Pages.
Once the first build passes, you see your site is live by
navigating to your **Project**'s **Settings** > **Pages**,
where you'll find its default URL.
> **Notes:**
>
> - GitLab Pages [supports any SSG](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/), but,
if you don't find yours among the templates, you'll need
to configure your own `.gitlab-ci.yml`. Do do that, please
read through the article [Creating and Tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md). New SSGs are very welcome among
the [example projects](https://gitlab.com/pages). If you set
up a new one, please
[contribute](https://gitlab.com/pages/pages.gitlab.io/blob/master/CONTRIBUTING.md)
to our examples.
>
> - The second step _"Clone it to your local computer"_, can be done
differently, achieving the same results: instead of cloning the bare
repository to you local computer and moving your site files into it,
you can run `git init` in your local website directory, add the
remote URL: `git remote add origin git@gitlab.com:namespace/project-name.git`,
then add, commit, and push.
### URLs and Baseurls
Every Static Site Generator (SSG) default configuration expects
to find your website under a (sub)domain (`example.com`), not
in a subdirectory of that domain (`example.com/subdir`). Therefore,
whenever you publish a project website (`namespace.gitlab.io/project-name`),
you'll have to look for this configuration (base URL) on your SSG's
documentation and set it up to reflect this pattern.
For example, for a Jekyll site, the `baseurl` is defined in the Jekyll
configuration file, `_config.yml`. If your website URL is
`https://john.gitlab.io/blog/`, you need to add this line to `_config.yml`:
```yaml
baseurl: "/blog"
```
On the contrary, if you deploy your website after forking one of
our [default examples](https://gitlab.com/pages), the baseurl will
already be configured this way, as all examples there are project
websites. If you decide to make yours a user or group website, you'll
have to remove this configuration from your project. For the Jekyll
example we've just mentioned, you'd have to change Jekyll's `_config.yml` to:
```yaml
baseurl: ""
```
|||
|:--|--:|
|[**← Part 1: Static sites, domains, DNS records, and SSL/TLS certificates**](getting_started_part_one.md)|[**Part 3: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages →**](getting_started_part_three.md)|
# GitLab Pages # All you need to know about GitLab Pages
> **Notes:** With GitLab Pages you can create static websites for your GitLab projects,
> - This feature was [introduced][ee-80] in GitLab EE 8.3. groups, or user accounts. You can use any static website generator: Jekyll,
> - Custom CNAMEs with TLS support were [introduced][ee-173] in GitLab EE 8.5. Middleman, Hexo, Hugo, Pelican, you name it! Connect as many customs domains
> - GitLab Pages [were ported][ce-14605] to Community Edition in GitLab 8.17. as you like and bring your own TLS certificate to secure them.
> - This document is about the user guide. To learn how to enable GitLab Pages
> across your GitLab instance, visit the [administrator documentation](../../../administration/pages/index.md).
With GitLab Pages you can host for free your static websites on GitLab. Here's some info we have gathered to get you started.
Combined with the power of [GitLab CI] and the help of [GitLab Runner] you can
deploy static pages for your individual projects, your user or your group.
Read [GitLab Pages on GitLab.com](#gitlab-pages-on-gitlab-com) for specific ## General info
information, if you are using GitLab.com to host your website.
Read through [All you Need to Know About GitLab Pages][pages-index-guide] for a list of all learning materials we have prepared for GitLab Pages (webpages, articles, guides, blog posts, video tutorials). - [Product webpage](https://pages.gitlab.io)
- [We're bringing GitLab Pages to CE](https://about.gitlab.com/2016/12/24/were-bringing-gitlab-pages-to-community-edition/)
- [Pages group - templates](https://gitlab.com/pages)
## Getting started with GitLab Pages ## Getting started
> **Note:** - GitLab Pages from A to Z
> In the rest of this document we will assume that the general domain name that - [Part 1: Static sites, domains, DNS records, and SSL/TLS certificates](getting_started_part_one.md)
> is used for GitLab Pages is `example.io`. - [Part 2: Quick start guide - Setting up GitLab Pages](getting_started_part_two.md)
- [Part 3: Creating and tweaking `.gitlab-ci.yml` for GitLab Pages](getting_started_part_three.md)
- [Hosting on GitLab.com with GitLab Pages](https://about.gitlab.com/2016/04/07/gitlab-pages-setup/) a comprehensive step-by-step guide
- Secure GitLab Pages custom domain with SSL/TLS certificates
- [Let's Encrypt](https://about.gitlab.com/2016/04/11/tutorial-securing-your-gitlab-pages-with-tls-and-letsencrypt/)
- [CloudFlare](https://about.gitlab.com/2017/02/07/setting-up-gitlab-pages-with-cloudflare-certificates/)
- [StartSSL](https://about.gitlab.com/2016/06/24/secure-gitlab-pages-with-startssl/)
- Static Site Generators - Blog posts series
- [SSGs part 1: Static vs dynamic websites](https://about.gitlab.com/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/)
- [SSGs part 2: Modern static site generators](https://about.gitlab.com/2016/06/10/ssg-overview-gitlab-pages-part-2/)
- [SSGs part 3: Build any SSG site with GitLab Pages](https://about.gitlab.com/2016/06/17/ssg-overview-gitlab-pages-part-3-examples-ci/)
- [Posting to your GitLab Pages blog from iOS](https://about.gitlab.com/2016/08/19/posting-to-your-gitlab-pages-blog-from-ios/)
In general there are two types of pages one might create: ## Video tutorials
- Pages per user (`username.example.io`) or per group (`groupname.example.io`) - [How to publish a website with GitLab Pages on GitLab.com: from a forked project](https://youtu.be/TWqh9MtT4Bg)
- Pages per project (`username.example.io/projectname` or `groupname.example.io/projectname`) - [How to Enable GitLab Pages for GitLab CE and EE](https://youtu.be/dD8c7WNcc6s)
In GitLab, usernames and groupnames are unique and we often refer to them ## Advanced use
as namespaces. There can be only one namespace in a GitLab instance. Below you
can see the connection between the type of GitLab Pages, what the project name
that is created on GitLab looks like and the website URL it will be ultimately
be served on.
| Type of GitLab Pages | The name of the project created in GitLab | Website URL | - Blog Posts:
| -------------------- | ------------ | ----------- | - [GitLab CI: Run jobs sequentially, in parallel, or build a custom pipeline](https://about.gitlab.com/2016/07/29/the-basics-of-gitlab-ci/)
| User pages | `username.example.io` | `http(s)://username.example.io` | - [GitLab CI: Deployment & environments](https://about.gitlab.com/2016/08/26/ci-deployment-and-environments/)
| Group pages | `groupname.example.io` | `http(s)://groupname.example.io` | - [Building a new GitLab docs site with Nanoc, GitLab CI, and GitLab Pages](https://about.gitlab.com/2016/12/07/building-a-new-gitlab-docs-site-with-nanoc-gitlab-ci-and-gitlab-pages/)
| Project pages owned by a user | `projectname` | `http(s)://username.example.io/projectname` | - [Publish code coverage reports with GitLab Pages](https://about.gitlab.com/2016/11/03/publish-code-coverage-report-with-gitlab-pages/)
| Project pages owned by a group | `projectname` | `http(s)://groupname.example.io/projectname`|
> **Warning:** ## Specific documentation
> There are some known [limitations](#limitations) regarding namespaces served
> under the general domain name and HTTPS. Make sure to read that section.
### GitLab Pages requirements - [User docs](introduction.md)
- [Admin docs](../../../administration/pages/index.md)
In brief, this is what you need to upload your website in GitLab Pages:
1. Find out the general domain name that is used for GitLab Pages
(ask your administrator). This is very important, so you should first make
sure you get that right.
1. Create a project
1. Push a [`.gitlab-ci.yml` file][yaml] in the root directory
of your repository with a specific job named [`pages`][pages]
1. Set up a GitLab Runner to build your website
> **Note:**
If [shared runners](../../../ci/runners/README.md) are enabled by your GitLab
administrator, you should be able to use them instead of bringing your own.
### User or group Pages
For user and group pages, the name of the project should be specific to the
username or groupname and the general domain name that is used for GitLab Pages.
Head over your GitLab instance that supports GitLab Pages and create a
repository named `username.example.io`, where `username` is your username on
GitLab. If the first part of the project name doesn't match exactly your
username, it won’t work, so make sure to get it right.
To create a group page, the steps are the same like when creating a website for
users. Just make sure that you are creating the project within the group's
namespace.
![Create a user-based pages project](img/pages_create_user_page.png)
---
After you push some static content to your repository and GitLab Runner uploads
the artifacts to GitLab CI, you will be able to access your website under
`http(s)://username.example.io`. Keep reading to find out how.
>**Note:**
If your username/groupname contains a dot, for example `foo.bar`, you will not
be able to use the wildcard domain HTTPS, read more at [limitations](#limitations).
### Project Pages
GitLab Pages for projects can be created by both user and group accounts.
The steps to create a project page for a user or a group are identical:
1. Create a new project
1. Push a [`.gitlab-ci.yml` file][yaml] in the root directory
of your repository with a specific job named [`pages`][pages].
1. Set up a GitLab Runner to build your website
A user's project will be served under `http(s)://username.example.io/projectname`
whereas a group's project under `http(s)://groupname.example.io/projectname`.
## Quick Start
Read through [GitLab Pages Quick Start Guide][pages-quick] or watch the video tutorial on
[how to publish a website with GitLab Pages on GitLab.com from a forked project][video-pages-fork].
See also [All you Need to Know About GitLab Pages][pages-index-guide] for a list with all the resources we have for GitLab Pages.
### Explore the contents of `.gitlab-ci.yml`
The key thing about GitLab Pages is the `.gitlab-ci.yml` file, something that
gives you absolute control over the build process. You can actually watch your
website being built live by following the CI job traces.
> **Note:**
> Before reading this section, make sure you familiarize yourself with GitLab CI
> and the specific syntax of[`.gitlab-ci.yml`][yaml] by
> following our [quick start guide].
To make use of GitLab Pages, the contents of `.gitlab-ci.yml` must follow the
rules below:
1. A special job named [`pages`][pages] must be defined
1. Any static content which will be served by GitLab Pages must be placed under
a `public/` directory
1. `artifacts` with a path to the `public/` directory must be defined
In its simplest form, `.gitlab-ci.yml` looks like:
```yaml
pages:
script:
- my_commands
artifacts:
paths:
- public
```
When the Runner reaches to build the `pages` job, it executes whatever is
defined in the `script` parameter and if the job completes with a non-zero
exit status, it then uploads the `public/` directory to GitLab Pages.
The `public/` directory should contain all the static content of your website.
Depending on how you plan to publish your website, the steps defined in the
[`script` parameter](../../../ci/yaml/README.md#script) may differ.
Be aware that Pages are by default branch/tag agnostic and their deployment
relies solely on what you specify in `.gitlab-ci.yml`. If you don't limit the
`pages` job with the [`only` parameter](../../../ci/yaml/README.md#only-and-except),
whenever a new commit is pushed to whatever branch or tag, the Pages will be
overwritten. In the example below, we limit the Pages to be deployed whenever
a commit is pushed only on the `master` branch:
```yaml
pages:
script:
- my_commands
artifacts:
paths:
- public
only:
- master
```
We then tell the Runner to treat the `public/` directory as `artifacts` and
upload it to GitLab. And since all these parameters were all under a `pages`
job, the contents of the `public` directory will be served by GitLab Pages.
#### How `.gitlab-ci.yml` looks like when the static content is in your repository
Supposedly your repository contained the following files:
```
├── index.html
├── css
│   └── main.css
└── js
└── main.js
```
Then the `.gitlab-ci.yml` example below simply moves all files from the root
directory of the project to the `public/` directory. The `.public` workaround
is so `cp` doesn't also copy `public/` to itself in an infinite loop:
```yaml
pages:
script:
- mkdir .public
- cp -r * .public
- mv .public public
artifacts:
paths:
- public
only:
- master
```
#### How `.gitlab-ci.yml` looks like when using a static generator
In general, GitLab Pages support any kind of [static site generator][staticgen],
since `.gitlab-ci.yml` can be configured to run any possible command.
In the root directory of your Git repository, place the source files of your
favorite static generator. Then provide a `.gitlab-ci.yml` file which is
specific to your static generator.
The example below, uses [Jekyll] to build the static site:
```yaml
image: ruby:2.1 # the script will run in Ruby 2.1 using the Docker image ruby:2.1
pages: # the build job must be named pages
script:
- gem install jekyll # we install jekyll
- jekyll build -d public/ # we tell jekyll to build the site for us
artifacts:
paths:
- public # this is where the site will live and the Runner uploads it in GitLab
only:
- master # this script is only affecting the master branch
```
Here, we used the Docker executor and in the first line we specified the base
image against which our jobs will run.
You have to make sure that the generated static files are ultimately placed
under the `public` directory, that's why in the `script` section we run the
`jekyll` command that jobs the website and puts all content in the `public/`
directory. Depending on the static generator of your choice, this command will
differ. Search in the documentation of the static generator you will use if
there is an option to explicitly set the output directory. If there is not
such an option, you can always add one more line under `script` to rename the
resulting directory in `public/`.
We then tell the Runner to treat the `public/` directory as `artifacts` and
upload it to GitLab.
---
See the [jekyll example project][pages-jekyll] to better understand how this
works.
For a list of Pages projects, see the [example projects](#example-projects) to
get you started.
#### How to set up GitLab Pages in a repository where there's also actual code
Remember that GitLab Pages are by default branch/tag agnostic and their
deployment relies solely on what you specify in `.gitlab-ci.yml`. You can limit
the `pages` job with the [`only` parameter](../../../ci/yaml/README.md#only-and-except),
whenever a new commit is pushed to a branch that will be used specifically for
your pages.
That way, you can have your project's code in the `master` branch and use an
orphan branch (let's name it `pages`) that will host your static generator site.
You can create a new empty branch like this:
```bash
git checkout --orphan pages
```
The first commit made on this new branch will have no parents and it will be
the root of a new history totally disconnected from all the other branches and
commits. Push the source files of your static generator in the `pages` branch.
Below is a copy of `.gitlab-ci.yml` where the most significant line is the last
one, specifying to execute everything in the `pages` branch:
```
image: ruby:2.1
pages:
script:
- gem install jekyll
- jekyll build -d public/
artifacts:
paths:
- public
only:
- pages
```
See an example that has different files in the [`master` branch][jekyll-master]
and the source files for Jekyll are in a [`pages` branch][jekyll-pages] which
also includes `.gitlab-ci.yml`.
[jekyll-master]: https://gitlab.com/pages/jekyll-branched/tree/master
[jekyll-pages]: https://gitlab.com/pages/jekyll-branched/tree/pages
## Next steps
So you have successfully deployed your website, congratulations! Let's check
what more you can do with GitLab Pages.
### Example projects
Below is a list of example projects for GitLab Pages with a plain HTML website
or various static site generators. Contributions are very welcome.
- [Plain HTML](https://gitlab.com/pages/plain-html)
- [Jekyll](https://gitlab.com/pages/jekyll)
- [Hugo](https://gitlab.com/pages/hugo)
- [Middleman](https://gitlab.com/pages/middleman)
- [Hexo](https://gitlab.com/pages/hexo)
- [Brunch](https://gitlab.com/pages/brunch)
- [Metalsmith](https://gitlab.com/pages/metalsmith)
- [Harp](https://gitlab.com/pages/harp)
Visit the GitLab Pages group for a full list of example projects:
<https://gitlab.com/groups/pages>.
### Add a custom domain to your Pages website
If this setting is enabled by your GitLab administrator, you should be able to
see the **New Domain** button when visiting your project's settings through the
gear icon in the top right and then navigating to **Pages**.
![New domain button](img/pages_new_domain_button.png)
---
You can add multiple domains pointing to your website hosted under GitLab.
Once the domain is added, you can see it listed under the **Domains** section.
![Pages multiple domains](img/pages_multiple_domains.png)
---
As a last step, you need to configure your DNS and add a CNAME pointing to your
user/group page. Click on the **Details** button of a domain for further
instructions.
![Pages DNS details](img/pages_dns_details.png)
---
>**Note:**
Currently there is support only for custom domains on per-project basis. That
means that if you add a custom domain (`example.com`) for your user website
(`username.example.io`), a project that is served under `username.example.io/foo`,
will not be accessible under `example.com/foo`.
### Secure your custom domain website with TLS
When you add a new custom domain, you also have the chance to add a TLS
certificate. If this setting is enabled by your GitLab administrator, you
should be able to see the option to upload the public certificate and the
private key when adding a new domain.
![Pages upload cert](img/pages_upload_cert.png)
### Custom error codes pages
You can provide your own 403 and 404 error pages by creating the `403.html` and
`404.html` files respectively in the root directory of the `public/` directory
that will be included in the artifacts. Usually this is the root directory of
your project, but that may differ depending on your static generator
configuration.
If the case of `404.html`, there are different scenarios. For example:
- If you use project Pages (served under `/projectname/`) and try to access
`/projectname/non/exsiting_file`, GitLab Pages will try to serve first
`/projectname/404.html`, and then `/404.html`.
- If you use user/group Pages (served under `/`) and try to access
`/non/existing_file` GitLab Pages will try to serve `/404.html`.
- If you use a custom domain and try to access `/non/existing_file`, GitLab
Pages will try to serve only `/404.html`.
### Remove the contents of your pages
If you ever feel the need to purge your Pages content, you can do so by going
to your project's settings through the gear icon in the top right, and then
navigating to **Pages**. Hit the **Remove pages** button and your Pages website
will be deleted. Simple as that.
![Remove pages](img/pages_remove.png)
## GitLab Pages on GitLab.com
If you are using GitLab.com to host your website, then:
- The general domain name for GitLab Pages on GitLab.com is `gitlab.io`.
- Custom domains and TLS support are enabled.
- Shared runners are enabled by default, provided for free and can be used to
build your website. If you want you can still bring your own Runner.
The rest of the guide still applies.
## Limitations
When using Pages under the general domain of a GitLab instance (`*.example.io`),
you _cannot_ use HTTPS with sub-subdomains. That means that if your
username/groupname contains a dot, for example `foo.bar`, the domain
`https://foo.bar.example.io` will _not_ work. This is a limitation of the
[HTTP Over TLS protocol][rfc]. HTTP pages will continue to work provided you
don't redirect HTTP to HTTPS.
[rfc]: https://tools.ietf.org/html/rfc2818#section-3.1 "HTTP Over TLS RFC"
## Redirects in GitLab Pages
Since you cannot use any custom server configuration files, like `.htaccess` or
any `.conf` file for that matter, if you want to redirect a web page to another
location, you can use the [HTTP meta refresh tag][metarefresh].
Some static site generators provide plugins for that functionality so that you
don't have to create and edit HTML files manually. For example, Jekyll has the
[redirect-from plugin](https://github.com/jekyll/jekyll-redirect-from).
## Frequently Asked Questions
### Can I download my generated pages?
Sure. All you need to do is download the artifacts archive from the job page.
### Can I use GitLab Pages if my project is private?
Yes. GitLab Pages don't care whether you set your project's visibility level
to private, internal or public.
### Do I need to create a user/group website before creating a project website?
No, you don't. You can create your project first and it will be accessed under
`http(s)://namespace.example.io/projectname`.
## Known issues
For a list of known issues, visit GitLab's [public issue tracker].
---
[jekyll]: http://jekyllrb.com/
[ee-80]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/80
[ee-173]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/173
[pages-daemon]: https://gitlab.com/gitlab-org/gitlab-pages
[gitlab ci]: https://about.gitlab.com/gitlab-ci
[gitlab runner]: https://docs.gitlab.com/runner
[pages]: ../../../ci/yaml/README.md#pages
[yaml]: ../../../ci/yaml/README.md
[staticgen]: https://www.staticgen.com/
[pages-jekyll]: https://gitlab.com/pages/jekyll
[metarefresh]: https://en.wikipedia.org/wiki/Meta_refresh
[public issue tracker]: https://gitlab.com/gitlab-org/gitlab-ee/issues?label_name=Pages
[ce-14605]: https://gitlab.com/gitlab-org/gitlab-ce/issues/14605
[quick start guide]: ../../../ci/quick_start/README.md
[pages-index-guide]: ../../../pages/index.md
[pages-quick]: ../../../pages/getting_started_part_one.md
[video-pages-fork]: https://youtu.be/TWqh9MtT4Bg
# GitLab Pages
> **Notes:**
> - This feature was [introduced][ee-80] in GitLab EE 8.3.
> - Custom CNAMEs with TLS support were [introduced][ee-173] in GitLab EE 8.5.
> - GitLab Pages [were ported][ce-14605] to Community Edition in GitLab 8.17.
> - This document is about the user guide. To learn how to enable GitLab Pages
> across your GitLab instance, visit the [administrator documentation](../../../administration/pages/index.md).
With GitLab Pages you can host for free your static websites on GitLab.
Combined with the power of [GitLab CI] and the help of [GitLab Runner] you can
deploy static pages for your individual projects, your user or your group.
Read [GitLab Pages on GitLab.com](#gitlab-pages-on-gitlab-com) for specific
information, if you are using GitLab.com to host your website.
Read through [All you Need to Know About GitLab Pages][pages-index-guide] for a list of all learning materials we have prepared for GitLab Pages (webpages, articles, guides, blog posts, video tutorials).
## Getting started with GitLab Pages
> **Note:**
> In the rest of this document we will assume that the general domain name that
> is used for GitLab Pages is `example.io`.
In general there are two types of pages one might create:
- Pages per user (`username.example.io`) or per group (`groupname.example.io`)
- Pages per project (`username.example.io/projectname` or `groupname.example.io/projectname`)
In GitLab, usernames and groupnames are unique and we often refer to them
as namespaces. There can be only one namespace in a GitLab instance. Below you
can see the connection between the type of GitLab Pages, what the project name
that is created on GitLab looks like and the website URL it will be ultimately
be served on.
| Type of GitLab Pages | The name of the project created in GitLab | Website URL |
| -------------------- | ------------ | ----------- |
| User pages | `username.example.io` | `http(s)://username.example.io` |
| Group pages | `groupname.example.io` | `http(s)://groupname.example.io` |
| Project pages owned by a user | `projectname` | `http(s)://username.example.io/projectname` |
| Project pages owned by a group | `projectname` | `http(s)://groupname.example.io/projectname`|
> **Warning:**
> There are some known [limitations](#limitations) regarding namespaces served
> under the general domain name and HTTPS. Make sure to read that section.
### GitLab Pages requirements
In brief, this is what you need to upload your website in GitLab Pages:
1. Find out the general domain name that is used for GitLab Pages
(ask your administrator). This is very important, so you should first make
sure you get that right.
1. Create a project
1. Push a [`.gitlab-ci.yml` file][yaml] in the root directory
of your repository with a specific job named [`pages`][pages]
1. Set up a GitLab Runner to build your website
> **Note:**
If [shared runners](../../../ci/runners/README.md) are enabled by your GitLab
administrator, you should be able to use them instead of bringing your own.
### User or group Pages
For user and group pages, the name of the project should be specific to the
username or groupname and the general domain name that is used for GitLab Pages.
Head over your GitLab instance that supports GitLab Pages and create a
repository named `username.example.io`, where `username` is your username on
GitLab. If the first part of the project name doesn't match exactly your
username, it won’t work, so make sure to get it right.
To create a group page, the steps are the same like when creating a website for
users. Just make sure that you are creating the project within the group's
namespace.
![Create a user-based pages project](img/pages_create_user_page.png)
---
After you push some static content to your repository and GitLab Runner uploads
the artifacts to GitLab CI, you will be able to access your website under
`http(s)://username.example.io`. Keep reading to find out how.
>**Note:**
If your username/groupname contains a dot, for example `foo.bar`, you will not
be able to use the wildcard domain HTTPS, read more at [limitations](#limitations).
### Project Pages
GitLab Pages for projects can be created by both user and group accounts.
The steps to create a project page for a user or a group are identical:
1. Create a new project
1. Push a [`.gitlab-ci.yml` file][yaml] in the root directory
of your repository with a specific job named [`pages`][pages].
1. Set up a GitLab Runner to build your website
A user's project will be served under `http(s)://username.example.io/projectname`
whereas a group's project under `http(s)://groupname.example.io/projectname`.
## Quick Start
Read through [GitLab Pages Quick Start Guide][pages-quick] or watch the video tutorial on
[how to publish a website with GitLab Pages on GitLab.com from a forked project][video-pages-fork].
See also [All you Need to Know About GitLab Pages][pages-index-guide] for a list with all the resources we have for GitLab Pages.
### Explore the contents of `.gitlab-ci.yml`
The key thing about GitLab Pages is the `.gitlab-ci.yml` file, something that
gives you absolute control over the build process. You can actually watch your
website being built live by following the CI job traces.
> **Note:**
> Before reading this section, make sure you familiarize yourself with GitLab CI
> and the specific syntax of[`.gitlab-ci.yml`][yaml] by
> following our [quick start guide].
To make use of GitLab Pages, the contents of `.gitlab-ci.yml` must follow the
rules below:
1. A special job named [`pages`][pages] must be defined
1. Any static content which will be served by GitLab Pages must be placed under
a `public/` directory
1. `artifacts` with a path to the `public/` directory must be defined
In its simplest form, `.gitlab-ci.yml` looks like:
```yaml
pages:
script:
- my_commands
artifacts:
paths:
- public
```
When the Runner reaches to build the `pages` job, it executes whatever is
defined in the `script` parameter and if the job completes with a non-zero
exit status, it then uploads the `public/` directory to GitLab Pages.
The `public/` directory should contain all the static content of your website.
Depending on how you plan to publish your website, the steps defined in the
[`script` parameter](../../../ci/yaml/README.md#script) may differ.
Be aware that Pages are by default branch/tag agnostic and their deployment
relies solely on what you specify in `.gitlab-ci.yml`. If you don't limit the
`pages` job with the [`only` parameter](../../../ci/yaml/README.md#only-and-except),
whenever a new commit is pushed to whatever branch or tag, the Pages will be
overwritten. In the example below, we limit the Pages to be deployed whenever
a commit is pushed only on the `master` branch:
```yaml
pages:
script:
- my_commands
artifacts:
paths:
- public
only:
- master
```
We then tell the Runner to treat the `public/` directory as `artifacts` and
upload it to GitLab. And since all these parameters were all under a `pages`
job, the contents of the `public` directory will be served by GitLab Pages.
#### How `.gitlab-ci.yml` looks like when the static content is in your repository
Supposedly your repository contained the following files:
```
├── index.html
├── css
│   └── main.css
└── js
└── main.js
```
Then the `.gitlab-ci.yml` example below simply moves all files from the root
directory of the project to the `public/` directory. The `.public` workaround
is so `cp` doesn't also copy `public/` to itself in an infinite loop:
```yaml
pages:
script:
- mkdir .public
- cp -r * .public
- mv .public public
artifacts:
paths:
- public
only:
- master
```
#### How `.gitlab-ci.yml` looks like when using a static generator
In general, GitLab Pages support any kind of [static site generator][staticgen],
since `.gitlab-ci.yml` can be configured to run any possible command.
In the root directory of your Git repository, place the source files of your
favorite static generator. Then provide a `.gitlab-ci.yml` file which is
specific to your static generator.
The example below, uses [Jekyll] to build the static site:
```yaml
image: ruby:2.1 # the script will run in Ruby 2.1 using the Docker image ruby:2.1
pages: # the build job must be named pages
script:
- gem install jekyll # we install jekyll
- jekyll build -d public/ # we tell jekyll to build the site for us
artifacts:
paths:
- public # this is where the site will live and the Runner uploads it in GitLab
only:
- master # this script is only affecting the master branch
```
Here, we used the Docker executor and in the first line we specified the base
image against which our jobs will run.
You have to make sure that the generated static files are ultimately placed
under the `public` directory, that's why in the `script` section we run the
`jekyll` command that jobs the website and puts all content in the `public/`
directory. Depending on the static generator of your choice, this command will
differ. Search in the documentation of the static generator you will use if
there is an option to explicitly set the output directory. If there is not
such an option, you can always add one more line under `script` to rename the
resulting directory in `public/`.
We then tell the Runner to treat the `public/` directory as `artifacts` and
upload it to GitLab.
---
See the [jekyll example project][pages-jekyll] to better understand how this
works.
For a list of Pages projects, see the [example projects](#example-projects) to
get you started.
#### How to set up GitLab Pages in a repository where there's also actual code
Remember that GitLab Pages are by default branch/tag agnostic and their
deployment relies solely on what you specify in `.gitlab-ci.yml`. You can limit
the `pages` job with the [`only` parameter](../../../ci/yaml/README.md#only-and-except),
whenever a new commit is pushed to a branch that will be used specifically for
your pages.
That way, you can have your project's code in the `master` branch and use an
orphan branch (let's name it `pages`) that will host your static generator site.
You can create a new empty branch like this:
```bash
git checkout --orphan pages
```
The first commit made on this new branch will have no parents and it will be
the root of a new history totally disconnected from all the other branches and
commits. Push the source files of your static generator in the `pages` branch.
Below is a copy of `.gitlab-ci.yml` where the most significant line is the last
one, specifying to execute everything in the `pages` branch:
```
image: ruby:2.1
pages:
script:
- gem install jekyll
- jekyll build -d public/
artifacts:
paths:
- public
only:
- pages
```
See an example that has different files in the [`master` branch][jekyll-master]
and the source files for Jekyll are in a [`pages` branch][jekyll-pages] which
also includes `.gitlab-ci.yml`.
[jekyll-master]: https://gitlab.com/pages/jekyll-branched/tree/master
[jekyll-pages]: https://gitlab.com/pages/jekyll-branched/tree/pages
## Next steps
So you have successfully deployed your website, congratulations! Let's check
what more you can do with GitLab Pages.
### Example projects
Below is a list of example projects for GitLab Pages with a plain HTML website
or various static site generators. Contributions are very welcome.
- [Plain HTML](https://gitlab.com/pages/plain-html)
- [Jekyll](https://gitlab.com/pages/jekyll)
- [Hugo](https://gitlab.com/pages/hugo)
- [Middleman](https://gitlab.com/pages/middleman)
- [Hexo](https://gitlab.com/pages/hexo)
- [Brunch](https://gitlab.com/pages/brunch)
- [Metalsmith](https://gitlab.com/pages/metalsmith)
- [Harp](https://gitlab.com/pages/harp)
Visit the GitLab Pages group for a full list of example projects:
<https://gitlab.com/groups/pages>.
### Add a custom domain to your Pages website
If this setting is enabled by your GitLab administrator, you should be able to
see the **New Domain** button when visiting your project's settings through the
gear icon in the top right and then navigating to **Pages**.
![New domain button](img/pages_new_domain_button.png)
---
You can add multiple domains pointing to your website hosted under GitLab.
Once the domain is added, you can see it listed under the **Domains** section.
![Pages multiple domains](img/pages_multiple_domains.png)
---
As a last step, you need to configure your DNS and add a CNAME pointing to your
user/group page. Click on the **Details** button of a domain for further
instructions.
![Pages DNS details](img/pages_dns_details.png)
---
>**Note:**
Currently there is support only for custom domains on per-project basis. That
means that if you add a custom domain (`example.com`) for your user website
(`username.example.io`), a project that is served under `username.example.io/foo`,
will not be accessible under `example.com/foo`.
### Secure your custom domain website with TLS
When you add a new custom domain, you also have the chance to add a TLS
certificate. If this setting is enabled by your GitLab administrator, you
should be able to see the option to upload the public certificate and the
private key when adding a new domain.
![Pages upload cert](img/pages_upload_cert.png)
### Custom error codes pages
You can provide your own 403 and 404 error pages by creating the `403.html` and
`404.html` files respectively in the root directory of the `public/` directory
that will be included in the artifacts. Usually this is the root directory of
your project, but that may differ depending on your static generator
configuration.
If the case of `404.html`, there are different scenarios. For example:
- If you use project Pages (served under `/projectname/`) and try to access
`/projectname/non/exsiting_file`, GitLab Pages will try to serve first
`/projectname/404.html`, and then `/404.html`.
- If you use user/group Pages (served under `/`) and try to access
`/non/existing_file` GitLab Pages will try to serve `/404.html`.
- If you use a custom domain and try to access `/non/existing_file`, GitLab
Pages will try to serve only `/404.html`.
### Remove the contents of your pages
If you ever feel the need to purge your Pages content, you can do so by going
to your project's settings through the gear icon in the top right, and then
navigating to **Pages**. Hit the **Remove pages** button and your Pages website
will be deleted. Simple as that.
![Remove pages](img/pages_remove.png)
## GitLab Pages on GitLab.com
If you are using GitLab.com to host your website, then:
- The general domain name for GitLab Pages on GitLab.com is `gitlab.io`.
- Custom domains and TLS support are enabled.
- Shared runners are enabled by default, provided for free and can be used to
build your website. If you want you can still bring your own Runner.
The rest of the guide still applies.
## Limitations
When using Pages under the general domain of a GitLab instance (`*.example.io`),
you _cannot_ use HTTPS with sub-subdomains. That means that if your
username/groupname contains a dot, for example `foo.bar`, the domain
`https://foo.bar.example.io` will _not_ work. This is a limitation of the
[HTTP Over TLS protocol][rfc]. HTTP pages will continue to work provided you
don't redirect HTTP to HTTPS.
[rfc]: https://tools.ietf.org/html/rfc2818#section-3.1 "HTTP Over TLS RFC"
## Redirects in GitLab Pages
Since you cannot use any custom server configuration files, like `.htaccess` or
any `.conf` file for that matter, if you want to redirect a web page to another
location, you can use the [HTTP meta refresh tag][metarefresh].
Some static site generators provide plugins for that functionality so that you
don't have to create and edit HTML files manually. For example, Jekyll has the
[redirect-from plugin](https://github.com/jekyll/jekyll-redirect-from).
## Frequently Asked Questions
### Can I download my generated pages?
Sure. All you need to do is download the artifacts archive from the job page.
### Can I use GitLab Pages if my project is private?
Yes. GitLab Pages don't care whether you set your project's visibility level
to private, internal or public.
### Do I need to create a user/group website before creating a project website?
No, you don't. You can create your project first and it will be accessed under
`http(s)://namespace.example.io/projectname`.
## Known issues
For a list of known issues, visit GitLab's [public issue tracker].
[jekyll]: http://jekyllrb.com/
[ee-80]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/80
[ee-173]: https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/173
[pages-daemon]: https://gitlab.com/gitlab-org/gitlab-pages
[gitlab ci]: https://about.gitlab.com/gitlab-ci
[gitlab runner]: https://docs.gitlab.com/runner/
[pages]: ../../../ci/yaml/README.md#pages
[yaml]: ../../../ci/yaml/README.md
[staticgen]: https://www.staticgen.com/
[pages-jekyll]: https://gitlab.com/pages/jekyll
[metarefresh]: https://en.wikipedia.org/wiki/Meta_refresh
[public issue tracker]: https://gitlab.com/gitlab-org/gitlab-ce/issues?label_name=pages
[ce-14605]: https://gitlab.com/gitlab-org/gitlab-ce/issues/14605
[quick start guide]: ../../../ci/quick_start/README.md
[pages-index-guide]: index.md
[pages-quick]: getting_started_part_one.md
[video-pages-fork]: https://youtu.be/TWqh9MtT4Bg
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment