前提
- 一个项目,我这里以vitepress为例
- 一台linux服务器
- 一个github账号,并且开通Actions workflow的功能
1. 项目搭建
- 进入vitePress的官网根据指引创建一个项目,这里我就不多述说了😏
- 项目创建完成后,在项目的根目录创建一个 DockerFile 文件,DockerFile是一个用来构建镜像的文本文件熟悉docker的同学应该经常用到。
打开编辑DockerFile文件
DockerFile
FROM node:20-alpine AS build
WORKDIR /code
COPY package*.json pnpm-lock.yaml ./
RUN npm config set registry https://registry.npmmirror.com
RUN npm install pnpm -g
RUN pnpm install
COPY . .
ENV NODE_OPTIONS="--max-old-space-size=8192"
RUN pnpm run docs:build
FROM nginx:latest AS final
RUN rm -rf /usr/share/nginx/html
RUN rm /etc/nginx/conf.d/default.conf
# RUN yum install git
WORKDIR /usr/share/nginx/html
COPY --from=build /code/docs/.vitepress/dist .
该 Dockerfile 用于构建一个基于 Node.js 的文档,并将其部署到 Nginx 服务器上。
2. 配置linux服务器
2.1 安装 Docker
确保在服务器上已经安装了 Docker。
sql
bash
Copy code
# Ubuntu 示例
sudo apt-get update
sudo apt-get install -y docker.io
2.2 拉取 Registry 镜像
Docker Registry 是 Docker 官方提供的镜像仓库服务。
css
bash
Copy code
docker pull registry:2
2.3 启动 Docker Registry
通过以下命令启动 Docker Registry:
css
bash
Copy code
docker run -d -p 5000:5000 --name registry registry:2
这将在 5000
端口运行一个私有镜像仓库。需要在服务器中和运营商中放开这端口的访问或者通过反代的形式访问。
2.4. 配置 Docker 客户端
默认情况下,Docker 客户端不允许通过 HTTP 推送镜像到不安全的仓库。需要修改 Docker 配置文件以允许不安全的 HTTP 连接。
2.4.1 修改配置文件
编辑 /etc/docker/daemon.json
文件(如果文件不存在,可以创建)。
添加以下内容:
css
json
Copy code
{
"insecure-registries": ["<your-registry-host>:5000"]
}
将 <your-registry-host>
替换为私有仓库的 IP 或主机名。后续如果无法正常推送镜像可以尝试增加反代的域名信息
2.4.2 重启 Docker
css
bash
Copy code
sudo systemctl restart docker
2.5 为了保证私服的安全通常增加认证
arduino
mkdir -p /home/auth
docker run --rm --entrypoint htpasswd httpd:2 -Bbn <username> <password> > /home/auth/htpasswd
这里创建了一个密码文件,你可以在任何目录下创建, 换成你的账号密码,在下个命令中使用并重新运行服务 /home/auth
就是你创建账号的文件路径
bash
docker run -d -p 5000:5000 --name registry \
-v $(pwd)/home/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
registry:2
3. GitHub Actions workflow 配置
3.1 创建Actions secrets and variables
在编写部署脚本的时候会用到一些密钥等敏感信息、也会用到一些经常需要修改的信息。所以需要将这些信息保存到github中方便管理。登录 github 打开项目厂库依次点击 Setting > Actions secrets and variables
创建以下secrets、variables
3.2 重新打开项目,在项目根目中创建 .github/workflows/ci.yml
文件
其中 DOCKER_IMAGE: ${{ vars.DOCKER_REGISTER }}/${{ vars.DOCKER_IMAGE_NAME }}:publish
yml
name: Build and Push Docker Image
on:
push:
branches:
- publish # 或你希望触发构建的其他分支
jobs:
build:
runs-on: ubuntu-latest
env:
DOCKER_IMAGE: ${{ vars.DOCKER_REGISTER }}/${{ vars.DOCKER_IMAGE_NAME }}:publish
steps:
# Step 1: Checkout the repository
- name: Checkout repository
uses: actions/checkout@v3
# Step 2: Set up Docker Buildx
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
# Step 3: Log in to Docker registry using secrets
- name: Log in to DockerHub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_NAME }}
password: ${{ secrets.DOCKER_PAW }}
registry: ${{ vars.DOCKER_REGISTER }}
# Step 4: Build Docker image
- name: Build Docker image
run: |
docker build -t ${{ env.DOCKER_IMAGE }} .
# Step 5: Push Docker image
- name: Push Docker image
run: |
docker push ${{ env.DOCKER_IMAGE }}
docker tag ${{ env.DOCKER_IMAGE }} ${{ env.DOCKER_IMAGE }}
docker push ${{ env.DOCKER_IMAGE }}
deploy:
runs-on: ubuntu-latest
needs: build # 确保在构建完成后部署
env:
LINUX_IP: ${{ vars.LINUX_IP }}
LINUX_SSH: ${{ secrets.LINUX_SSH }}
LINUX_USER: ${{ secrets.LINUX_USER }}
LINUX_PATH: ${{ vars.LINUX_PATH }}
steps:
# Step 1: Checkout the repository
- name: Checkout repository
uses: actions/checkout@v3
# Step 2: Set up SSH and deploy Docker Compose
- name: Set up SSH and deploy Docker Compose
run: |
# Set up SSH key for authentication
mkdir -p ~/.ssh
echo "$LINUX_SSH" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
# Add the server to known_hosts to prevent SSH prompt
ssh-keyscan -H $LINUX_IP >> ~/.ssh/known_hosts
# SSH into the server and run Docker Compose commands
ssh -o StrictHostKeyChecking=no $LINUX_USER@$LINUX_IP <<EOF
cd $LINUX_PATH
sudo docker compose pull
sudo docker compose up -d --force-recreate
EOF
4.创建 docker-compose.yml
,创建的路径要与$LINUX_PATH
一致,volumes的nginx配置要与dockerfile中的配置对应
docker-compose.yml
version: '3.8'
services:
blog:
image: docker.luckymiaow.com/luckymiaow-blog:publish
container_name: luckymiaow-blog
ports:
- "8000:80"
volumes:
- ./nginx.sites.conf:/etc/nginx/conf.d/nginx.sites.conf
networks:
- webnet
networks:
webnet:
nginx.sites.conf
的是vitePress
的部署示例,
nginx.sites.conf
server {
listen 80;
server_name _; # 默认匹配所有域名
index index.html;
# 启用 gzip 压缩
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
# 根目录指向 /usr/share/nginx/html
root /usr/share/nginx/html;
# 根目录下的请求
location / {
# 尝试文件,先匹配文件,再匹配 .html 文件,最后匹配文件夹
try_files $uri $uri.html $uri/ =404;
# 404 错误页面
error_page 404 /404.html;
# 非法访问文件夹返回 403 错误
error_page 403 /404.html;
}
# 针对 /assets/ 目录的缓存策略
location ~* ^/assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
}