GitLab教程(12): GitLab Pages静态网站托管

GitLab Pages可以托管静态网站,支持自定义域名和HTTPS。本文将介绍如何使用GitLab Pages部署文档站点、博客和单页应用。

什么是GitLab Pages

# GitLab Pages功能
- 免费托管静态网站
- 自动HTTPS (Let's Encrypt)
- 支持自定义域名
- 与CI/CD集成
- 支持各种静态站点生成器

# 访问地址格式
# 用户/组页面
https://username.gitlab.io
https://groupname.gitlab.io

# 项目页面
https://username.gitlab.io/projectname
https://groupname.gitlab.io/projectname

# 自托管GitLab
https://username.pages.example.com
https://username.pages.example.com/projectname

简单HTML站点

# 项目结构
my-website/
├── public/
│   ├── index.html
│   ├── about.html
│   ├── css/
│   │   └── style.css
│   └── js/
│       └── main.js
└── .gitlab-ci.yml

# public/index.html



    My Website
    


    

Welcome to My Website

Hosted on GitLab Pages!

# .gitlab-ci.yml pages: stage: deploy script: - echo "Deploying to GitLab Pages..." artifacts: paths: - public # 必须是public目录 rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # 执行结果 Job succeeded Artifacts are stored. Pages deployed! # 访问地址 https://username.gitlab.io/my-website

使用Hugo

# Hugo是一个快速的静态站点生成器

# 创建Hugo站点
hugo new site my-blog
cd my-blog
git init

# 添加主题
git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke themes/ananke
echo "theme = 'ananke'" >> hugo.toml

# 创建文章
hugo new posts/my-first-post.md

# .gitlab-ci.yml
image: registry.gitlab.com/pages/hugo:latest

variables:
  HUGO_ENV: production

pages:
  script:
    - hugo --minify
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# 构建输出
$ hugo --minify
Start building sites…
https://username.gitlab.io/my-blog/

                   | EN
-------------------+------
  Pages            |  12
  Paginator pages  |   0
  Non-page files   |   0
  Static files     |   3
  Processed images |   0
  Aliases          |   1
  Sitemaps         |   1
  Cleaned          |   0

Total in 234 ms

使用VuePress/VitePress

# VitePress - Vue驱动的文档站点

# 创建项目
npm init -y
npm install -D vitepress

# 创建文档
mkdir docs
echo '# Hello VitePress' > docs/index.md

# package.json添加脚本
{
  "scripts": {
    "docs:dev": "vitepress dev docs",
    "docs:build": "vitepress build docs"
  }
}

# .gitlab-ci.yml
image: node:18

pages:
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/
  script:
    - npm ci
    - npm run docs:build
    - mv docs/.vitepress/dist public
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# 如果项目不在根路径,配置base
# docs/.vitepress/config.js
export default {
  base: '/my-docs/',  // 项目名
  title: 'My Documentation',
  description: 'Project documentation'
}

使用MkDocs

# MkDocs - Python文档站点生成器

# 项目结构
my-docs/
├── docs/
│   ├── index.md
│   ├── getting-started.md
│   └── api/
│       └── reference.md
├── mkdocs.yml
└── .gitlab-ci.yml

# mkdocs.yml
site_name: My Project Docs
site_url: https://username.gitlab.io/my-docs
nav:
  - Home: index.md
  - Getting Started: getting-started.md
  - API Reference: api/reference.md
theme:
  name: material
  palette:
    primary: blue

# .gitlab-ci.yml
image: python:3.11

pages:
  script:
    - pip install mkdocs mkdocs-material
    - mkdocs build --site-dir public
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# 构建输出
$ mkdocs build --site-dir public
INFO    -  Cleaning site directory
INFO    -  Building documentation to directory: public
INFO    -  Documentation built in 0.45 seconds

React/Vue SPA

# React应用 (Create React App)

# .gitlab-ci.yml
image: node:18

stages:
  - build
  - deploy

build:
  stage: build
  cache:
    key: ${CI_COMMIT_REF_SLUG}
    paths:
      - node_modules/
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - build/

pages:
  stage: deploy
  script:
    - mv build public
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

# 配置basename (package.json)
{
  "homepage": "/my-react-app"
}

# Vue应用 (Vite)

# vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

export default defineConfig({
  base: '/my-vue-app/',  // 设置base路径
  plugins: [vue()],
  build: {
    outDir: 'dist'
  }
})

# .gitlab-ci.yml
image: node:18

pages:
  script:
    - npm ci
    - npm run build
    - mv dist public
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

自定义域名

# 1. 添加域名
# Project > Deploy > Pages
# 点击 "New Domain"
# 输入: docs.example.com

# 2. 配置DNS记录
# 方式A: CNAME记录
docs.example.com  CNAME  username.gitlab.io

# 方式B: A记录 (gitlab.com)
docs.example.com  A  35.185.44.232

# 3. 验证域名所有权
# 添加TXT记录
_gitlab-pages-verification-code.docs.example.com  TXT  gitlab-pages-verification-code=xxx

# 4. 启用HTTPS
# GitLab Pages会自动通过Let's Encrypt获取证书
# 勾选 "Force HTTPS"

# 使用自有证书
# 上传证书文件 (.crt) 和私钥 (.key)

# DNS验证示例
$ dig docs.example.com CNAME +short
username.gitlab.io.

$ dig _gitlab-pages-verification-code.docs.example.com TXT +short
"gitlab-pages-verification-code=abc123xyz"

访问控制

# Pages访问控制 (需要GitLab 12.4+)

# Project > Deploy > Pages
# Access control:
#   - Everyone (公开)
#   - Everyone with access (需要登录并有项目访问权限)

# 私有项目的Pages默认只有项目成员可访问

# 对于私有Pages,访问时需要GitLab认证
# 用户访问时会重定向到GitLab登录页面

多环境部署

# 正式环境部署到Pages,预览环境使用其他方式

stages:
  - build
  - deploy

build:
  stage: build
  image: node:18
  script:
    - npm ci
    - npm run build
  artifacts:
    paths:
      - dist/

# 预览环境 (使用Surge.sh)
deploy-preview:
  stage: deploy
  image: node:18
  script:
    - npm install -g surge
    - surge ./dist $CI_COMMIT_REF_SLUG.surge.sh
  environment:
    name: preview/$CI_COMMIT_REF_SLUG
    url: https://$CI_COMMIT_REF_SLUG.surge.sh
    on_stop: stop-preview
  rules:
    - if: $CI_MERGE_REQUEST_IID

stop-preview:
  stage: deploy
  script:
    - surge teardown $CI_COMMIT_REF_SLUG.surge.sh
  environment:
    name: preview/$CI_COMMIT_REF_SLUG
    action: stop
  when: manual
  rules:
    - if: $CI_MERGE_REQUEST_IID

# 正式环境 (GitLab Pages)
pages:
  stage: deploy
  script:
    - mv dist public
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == "main"

404和重定向

# 自定义404页面
# 创建 public/404.html




    Page Not Found


    

404 - Page Not Found

The page you're looking for doesn't exist.

Go Home # SPA路由支持(history模式) # 需要将所有请求重定向到index.html # 方式1: 使用_redirects文件 (Cloudflare Pages风格) # public/_redirects /* /index.html 200 # 方式2: 使用404.html作为回退 # public/404.html 内容与 index.html 相同 # 并添加JavaScript处理路由

性能优化

# 配置_headers文件添加缓存头
# public/_headers

/*
  X-Frame-Options: DENY
  X-XSS-Protection: 1; mode=block
  X-Content-Type-Options: nosniff

/assets/*
  Cache-Control: public, max-age=31536000, immutable

/*.js
  Cache-Control: public, max-age=31536000, immutable

/*.css
  Cache-Control: public, max-age=31536000, immutable

/images/*
  Cache-Control: public, max-age=604800

# 压缩资源
# 在构建时启用压缩

# Hugo
hugo --minify

# Vite
npm run build -- --minify

# 使用brotli压缩
pages:
  script:
    - npm run build
    - find public -type f \( -name "*.html" -o -name "*.js" -o -name "*.css" \) -exec gzip -9 -k {} \;
  artifacts:
    paths:
      - public

完整示例

# 完整的文档站点配置 (VitePress)

image: node:18-alpine

stages:
  - test
  - build
  - deploy

variables:
  npm_config_cache: "$CI_PROJECT_DIR/.npm"

cache:
  key: ${CI_COMMIT_REF_SLUG}
  paths:
    - .npm/
    - node_modules/

lint:
  stage: test
  script:
    - npm ci
    - npm run lint
  rules:
    - if: $CI_MERGE_REQUEST_IID

build:
  stage: build
  script:
    - npm ci
    - npm run docs:build
  artifacts:
    paths:
      - docs/.vitepress/dist
    expire_in: 1 hour
  rules:
    - if: $CI_MERGE_REQUEST_IID
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH

pages:
  stage: deploy
  needs: [build]
  script:
    - mv docs/.vitepress/dist public
  artifacts:
    paths:
      - public
  rules:
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
  environment:
    name: production
    url: https://username.gitlab.io/my-docs

总结

本文介绍了GitLab Pages的使用方法,包括各种静态站点生成器的配置、自定义域名设置和性能优化。GitLab Pages是托管文档和静态网站的便捷方式。

下一篇我们将学习GitLab Issue跟踪与项目管理。

发表回复

后才能评论