Deploy docsify.js using Gitlab Pages with a Preview Environment
One of the biggest challenges our engineering team faces is our knowledge management and documentation.
We searched for the right platform that would give us a standard and simple platform for writing documentation while improving the speed of creating and changing documentation used by our team.
We ended up choosing docsify.js as our knowledge management platform of choice for three main reasons:
- Single standard: Documentation is written in Markdown which is all complied in a similar manner giving a similar look across all of our documentation.
- Reviewable: We want to treat our documentation in the same way that we treat our code. Documentation is added through merge requests and reviewed by other team members in order to keep a high standard when writing documentation.
- Costs: Usage of GitLab Pages allows us to deploy a secure website for our documentation without any additional costs (other than running Gitlab CI jobs for deployments which has a free monthly quota as well).
The structure of our knowledge base is quite straightforward and an example repo exists on GitLab: example project.
First: Create a documentation project repo
You may use our setup:
.
└── documentation/ # Project Repo
├── docs/ # Actual Documentation
│ ├── services/
│ │ ├── example-service.md
│ │ └── another-service.md
│ └── services.md
│ ├── tutorial/
| │ └── _media/ # Images and such
| │ | └── example-tutorial/
│ | | └── example-image.jpg
│ │ └── example-tutorial.md
│ └── tutorial.md
│ ├── _coverpage.md # Landing page
│ ├── _homepage.md # Content of homepage
│ ├── _sidebar.md # Content of sidebar
├── index.html # The sites page
├── README.md # Repo README
└── gitlab-ci.yml # GitLab CI configurations
Second: Configure docsify.js settings
- Edit the
index.html
file in order to use docsify.js correctly:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta charset="UTF-8">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify/lib/themes/buble.css" />
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.css" />
<title>Example Docs</title>
</head>
<body>
<div id="app"></div>
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
<script>
window.$docsify = {
el: "#app",
basePath: "$DOCSIFY_BASE_PATH",
loadSidebar: true,
coverpage: true
}
</script>
</body>
</html>
Notice that we use the token
$DOCSIFY_BASE_PATH
.
We are going to tokenize the value through the GitLab CI pipeline definition.
- Bonus: add mermaid.js 🧜♀️ (Check out their documentation — they use docsify as well! 🚀) support:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta charset="UTF-8">
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/docsify/lib/themes/buble.css" />
<link rel="stylesheet" href="//cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.css" />
<title>Example Docs</title>
</head>
<body>
<div id="app"></div>
<script src="//cdn.jsdelivr.net/npm/docsify@4"></script>
<script src="//cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
<script>
var num = 0;
mermaid.initialize({ startOnLoad: false });
window.$docsify = {
el: "#app",
basePath: "$DOCSIFY_BASE_PATH",
loadSidebar: true,
coverpage: true,
markdown: {
renderer: {
code: function(code, lang) {
if (lang === "mermaid") {
return (
'<div class="mermaid">' + mermaid.render('mermaid-svg-' + num++, code) + "</div>"
);
}
return this.origin.code.apply(this, arguments);
}
}
}
}
</script>
</body>
</html>
Third: Configure GitLab CI for GitLab Pages deployments and a Preview environment
- Deployment to GitLab Pages:
stages:
- test
- deploy
pages:
image:
name: cirocosta/alpine-envsubst:latest
entrypoint: [""]
variables:
DOCSIFY_BASE_PATH: https://GROUP_NAME.gitlab.io/-/PROJECT_PATH/docs
docsify: $docsify
stage: deploy
script:
- mkdir .public
- mv index.html .index.html
- envsubst < ".index.html" > "index.html"
- rm -f .index.html
- cp -r * .public
- mv .public public
- ls
artifacts:
paths:
- public
only:
- master
- Creation of a Preview Environment:
"Create Preview Environment":
extends: pages
variables:
DOCSIFY_BASE_PATH: https://GROUP_NAME.gitlab.io/-/PROJECT_PATH/-/jobs/$CI_JOB_ID/artifacts/public/docs
script:
- mkdir .public
- envsubst < "index.html" > ".index.html"
- envsubst < ".index.html" > "index.html"
- rm -f .index.html
- cp -r * .public
- mv .public public
stage: test
only:
- merge_requests
With everything together, your gitlab-ci.yml
file should look something like this:
stages:
- test
- deploy
pages:
image:
name: cirocosta/alpine-envsubst:latest
entrypoint: [""]
variables:
DOCSIFY_BASE_PATH: https://GROUP_NAME.gitlab.io/-/PROJECT_PATH/docs
docsify: $docsify
stage: deploy
script:
- mkdir .public
- mv index.html .index.html
- envsubst < ".index.html" > "index.html"
- rm -f .index.html
- cp -r * .public
- mv .public public
- ls
artifacts:
paths:
- public
only:
- master
"Create Preview Environment":
extends: pages
variables:
DOCSIFY_BASE_PATH: https://GROUP_NAME.gitlab.io/-/PROJECT_PATH/-/jobs/$CI_JOB_ID/artifacts/public/docs
script:
- mkdir .public
- envsubst < "index.html" > ".index.html"
- envsubst < ".index.html" > "index.html"
- rm -f .index.html
- cp -r * .public
- mv .public public
stage: test
only:
- merge_requests
Fourth: Use Preview environment for a better developer experience:
As done in the previous step, we configured the job: “Create Preview Environment” which uses GitLab’s artifacts feature in order to load the static files that are needed to run our live preview site.
Once a merge request with new changes is created, an automatic job runs. Once the job completes successfully, the preview environment will be available at:
https://GROUP_NAME.gitlab.io/-/PATH_TO_PROJECT/-/jobs/CI_JOB_ID/artifacts/public/index.html
You can find the CI_JOB_ID by:
Click on the pipeline from within the merge request:
Click on the job:
Copy the Job ID:
Now we can review our changes on the preview environment before merging our changes into the production branch that deploys to our documentation website.