声明:文章首发个人博客

总有一些项目不太想开源,为了便利布置 期望改完代码之后通过 docker 主动布置到不同的服务器上。本文简略叙述一下整个流程,期望对你有协助

一、先来创立一个项目

首先在 github 上面创立一个私有项目

私有项目如何使用 github action 打包 docker 镜像并部署到服务器

此处主要以一个前端项目为例(运用 umi 创立的项目)

mkdir myapp && cd myapp
pnpm dlx create-umi@latest

二、聊聊 Docker 的基础指令

1. 镜像常见相关指令

# 去下载镜像,先从本地找,没有去镜像,最后没有去 hub,标签不写默以为 lastest
docker pull [镜像名]:[标签Tag]
# 列出本机的一切 image 文件,-a 显现本地一切镜像(包含中心镜像),-q 只显现镜像ID,--digests 显现镜像的摘要信息
docker image ls
docker images
# 删去 image 文件, -f 强制删去镜像
docker rmi [镜像名][:标签Tag]
docker rmi [镜像名1][:标签Tag] [镜像名2][:标签Tag]    # 删多个
docker rmi $(docker ps -a -q)    # 删全部,后边是子指令
# 查询镜像称号,--no-trunc 显现完整的镜像描述,--filter=stars=30 列出star不少于指定值的镜像,--filter=is-automated=true 列出主动构建类型的镜像
docker search [关键字]
# 下载镜像,标签 tag 不写默以为 lastest,也能够自己加比如 :3.2.0
docker pull [镜像名][:标签Tag]

2. 容器常见相关指令

# 列出本机正在运转的容器,-a 列出本机一切容器包含中止运转的容器,-q 静默形式只显现容器编号,-l 显现最近创立的容器
docker container ls     # 等价于下面这个指令
docker ps
# 新建并发动容器; 这个一般用的比较多
docker run [option] [容器名]
# 发动容器
docker start [容器ID]/[容器Names]
# 重启容器
docker restart [容器ID]/[容器Names]
docker stop [容器ID]  # 沉着中止,相当于向容器里边的主进程发出 SIGTERM 信号,然后过一段时间再发出 SIGKILL 信号
docker stop $(docker ps -a -q) # 中止一切容器
# 中止运转的容器文件,依然会占据硬盘空间,能够运用 docker container rm 指令删去,-f 强制删去能够删去正在运转的容器
docker rm [容器ID]
docker rm `docker ps -aq`    # 删去一切已经中止的容器,由于没中止的rm删不了需求加-f
# 设置容器在docker发动时主动发动
$ docker container update --restart=always [容器姓名]

这儿要特甭说一下 docker runoption,由于最常用:

  • –name 为容器指定一个称号;
  • -d 容器发动后进入后台,并回来容器 ID,即发动看护式容器;
  • -P 随机端口映射;
  • -p 80:8080 将本地 80 端口映射到容器的 8080 端口;
  • -i 以交互形式运转容器,通常与 -t 一起运用;
  • -t 为容器重新分配一个伪输入终端,容器的 Shell 会映射到当时的 Shell,然后在本机窗口输入的指令,就会传入容器,通常与 -i 一起运用;
  • –rm 在容器中止运转后主动删去容器文件;
  • –restart=always 设置容器自发动;
  • -v /xxx:/yyy 映射指令,把本机的 xxx 目录映射到容器中的 yyy 目录,也就是说改动本机的 xxx 目录下的内容, 容器 yyy 目录中的内容也会改动;

三、编写 Dockerfile

由于 umi 构建之后产品会放在 dist 目录下面,所以咱们能够编写如下的 Dockerfile;

Dockerfile 用于声明镜像履行的过程; 对于如下指令不熟悉的同学能够点击检查此文章

FROM nginx:latest # 运用nginx 作为基础镜像
LABEL maintainer "你的github邮箱"
ADD ./dist /usr/share/nginx/html # 将产品放在  nginx 的 /usr/share/nginx/html 目录下
EXPOSE 80 # 暴露出80 端口

四、编写 github action

由于 hub.docker.io 现在只支撑一个 私有镜像,所以咱们暂不考虑运用;引荐大家运用 github 自带的 镜像源 ghcr.io

前置准备工作

  1. 去 github.com/settings/to… 生成一个 token,留意此 token 需求读写 packages 等权限 概况请见这儿
  2. 准备好你的要布置的服务器的 账号 和暗码(当时页能够运用秘钥登录,这儿暂且运用暗码)
  3. 想好你的镜像称号(此处以 web-image 为例)

.github/workflows目录创立一个 publish-image.yml

name: Publish Image
on:
  push: # push 到主分支主动 发布
    branches: ["main"]
    paths-ignore: # 忽略一些不必要的文件
      - ".gitignore"
      - "README.md"
      - ".vscode/**"
  pull_request:
    branches: ["main"]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: docker/login-action@v1
        with:
          registry: ghcr.io # 声明镜像源
          username: ${{ github.actor }} # 当时github 用户名
          password: ${{ secrets.HUB_GITHUB_TOKEN }} # 需求去 https://github.com/settings/tokens 生成一个 名为 token,留意此token 需求读写 packages 等权限 概况请见
      - uses: actions/setup-node@v2
        with:
          node-version: "16.14"
      - uses: actions/cache@v2
        id: cache
        with:
          path: node_modules
          key: ${{ runner.os }}-node-${{ hashFiles('package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-
        # Runs a single command using the runners shell
      - name: pnpm install
        run: npm install -g pnpm --registry https://registry.npm.taobao.org
      - name: Install
        if: steps.cache.outputs.cache-hit != 'true'
        run: npm config set registry https://registry.npm.taobao.org && pnpm i
      - name: Build
        run: npm run build
      - name: Show Dir
        run: ls
      - name: Build the  Docker image
        run:
          | # 运用 上一步写的 Dockerfile 构建镜像并发布到私有库房; 发布完结能够去 https://github.com/MrGaoGang?tab=packages 检查
          docker build . --file Dockerfile --tag ghcr.io/你的github称号/web-image:latest 
          docker push ghcr.io/你的github称号/web-image:latest
      - name: 更新服务器
        uses: appleboy/ssh-action@v0.1.10
        with:
          host: ${{ secrets.SERVER_HOST }} # 服务器ip地址 ; 需求去库房的 settings/secrets/actions 去创立
          username: ${{ secrets.SERVER_USER }} # 服务器用户称号;需求去库房的 settings/secrets/actions 去创立
          password: ${{ secrets.SERVER_PWD }} # 服务器暗码;需求去库房的 settings/secrets/actions 去创立
          port: ${{ secrets.SERVER_PORT }} # 服务器端口,默许22;需求去库房的 settings/secrets/actions 去创立
          script: | # 重启更新镜像
            docker stop web-image 
            docker rm web-image 
            docker login -u 你的github称号 -p 你的github token https://ghcr.io 
            docker pull ghcr.io/你的github称号/web-image:latest 
            docker run -dp 80:80  --restart=always --name web-image ghcr.io/你的github称号/web-image
        # 上面运用 80端口发动,当然你也能够换成自己想要的端口

五、私有 docker 镜像

上面咱们运用到 github 的私有镜像 ghcr; 当然你也能够自己基于 docker/register 弄一个私有镜像; 能够在自己服务器上运转如下指令

# 1、下载镜像
docker pull registry:2
# 2、运转容器
$ docker run  -d --restart=always  -v /opt/registry:/var/lib/registry -p 5000:5000 --name myregistry registry:2

然后再本地构建镜像并上传镜像:


# 私有化构建
$ docker build . --file Dockerfile --tag 服务器ip地址:5000:web-image:latest
# 私有化发布
$ docker push 服务器ip地址:5000:web-image:latest
# 留意,上传镜像时报错了:http: server gave HTTP response to HTTPS client
# 【在docker push 的客户端履行,而不是私有服务器】解决办法1:
# 1、编辑 /etc/docker/daemon.json,在文件中写入:(假如你的镜像真实linux/centos 上)
{ "insecure-registries":["服务器ip地址:5000"] }
# 【在docker push 的客户端履行,而不是私有服务器】或许快解决办法2 (假如你的镜像真实linux/centos 上)
$ sudo vim /usr/lib/systemd/system/docker.service
# 修正里边的内容 为
ExecStart=/usr/bin/dockerd  --containerd=/run/containerd/containerd.sock --insecure-registry 你的ip:5000
# 2、重启收效:
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
# 再次上传,问题解决:
$ docker push 服务器ip地址:5000:web-image:latest

假如你运用的是 windows/mac 能够直接在 docker 的设置里边增加

{
  "builder": {
    "gc": {
      "defaultKeepStorage": "20GB",
      "enabled": true
    }
  },
  "experimental": false,
  "features": {
    "buildkit": true
  },
  "insecure-registries": ["你的服务器ip地址:5000"]
}