使用 GitHub Actions workflow 自动化将项目以 Docker 部署到服务器

前提

  • 一个项目,我这里以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";
    }
}

提交代码合并到publish将会触发工作流,构建镜像后服务器执行docker-compose.yml更新网站。

相关推荐
迷雾漫步者2 小时前
Flutter组件————FloatingActionButton
前端·flutter·dart
向前看-2 小时前
验证码机制
前端·后端
燃先生._.3 小时前
Day-03 Vue(生命周期、生命周期钩子八个函数、工程化开发和脚手架、组件化开发、根组件、局部注册和全局注册的步骤)
前端·javascript·vue.js
油泼辣子多加3 小时前
2024年12月18日Github流行趋势
github
hunteritself3 小时前
AI Weekly『12月16-22日』:OpenAI公布o3,谷歌发布首个推理模型,GitHub Copilot免费版上线!
人工智能·gpt·chatgpt·github·openai·copilot
高山我梦口香糖4 小时前
[react]searchParams转普通对象
开发语言·前端·javascript
m0_748235244 小时前
前端实现获取后端返回的文件流并下载
前端·状态模式
m0_748240255 小时前
前端如何检测用户登录状态是否过期
前端
black^sugar5 小时前
纯前端实现更新检测
开发语言·前端·javascript