发布 npm 包

如何使用 buddy 的流水线自动发布私有npm包呢?

这里使用的是 buddy 的自主托管版本和 gitlab ce 。 npm 注册表使用的是 gitlab 的软件仓库。

在 buddy 里创建项目,将需要发布的项目代码 clone 下来。

如果是从 gitlab ce 上 clone ,使用 oAuth 方式可能会遇到问题。

本文使用的是个人令牌的方式。

为项目创建流水线,并在 操作 于运行 栏目下,选择添加按钮。然后选中 node.js 项。

之后,在运行栏目下,输入本次的命令

# yarn install
# 安装依赖
npm ci
# 配置注册表和令牌
npm config --location=project set @zhangtx:registry=https://$GITLAB_HOST/api/v4/projects/$GITLAB_PROJECT_ID/packages/npm/
npm config --location=project set //$GITLAB_HOST/api/v4/projects/$GITLAB_PROJECT_ID/packages/npm/:_authToken=$GITLAB_NPM_PUBLISH_PACKAGE_TOKEN
# 编译
npm run build
# 发布
npm publish

注意其中的 $ 开头的名称,它们是自定义变量。

–location=project 表示修改的是本项目的 .npmrc

@zhangtx 表示范围包。

GITLAB_HOST 是本次 gitlab ce 的域名,你也可以使用ip

GITLAB_PROJECT_ID 时本次项目在 gitlab ce 中的 项目ID。不是项目名称

GITLAB_NPM_PUBLISH_PACKAGE_TOKEN 是发布包时需要的令牌,可以从 gitlab ce的的 个人令牌中获取,注意范围要勾选api

接下来你可以尝试运行这个流水线。

制作基于 mysql 的镜像

直接通过 commit 提交包含数据的MySQL镜像是无效的.

因为 mysql 的镜像使用了卷,而commit不会提交这些数据。

解决方案:

或许可以通过推荐方法来完成这个这件事情

创建一个 Dockerfile 文件。

# @see https://hub.docker.com/_/mysql
FROM mysql:8.0.28

# 创建数据库后按照此文件里面的配置进行初始化,文件将按字母顺序执行
COPY ./docker-entrypoint-initdb.d /docker-entrypoint-initdb.d

# 初始化一个数据库
ENV MYSQL_DATABASE=myDatabase

# 设置root账户密码
ENV MYSQL_ROOT_PASSWORD=123456

myDatabase 是你的数据库名称

123456 是你的 root 账户密码

紧接着,在 ./docker-entrypoint-initdb.d 目录里,放入你你用来初始化数据库的文件,比如 .sql 文件。

摘抄官网原文:When a container is started for the first time, a new database with the specified name will be created and initialized with the provided configuration variables. Furthermore, it will execute files with extensions .sh, .sql and .sql.gz that are found in /docker-entrypoint-initdb.d. Files will be executed in alphabetical order. You can easily populate your mysql services by mounting a SQL dump into that directory and provide custom images with contributed data. SQL files will be imported by default to the database specified by the MYSQL_DATABASE variable.

译文:当容器第一次启动时,将创建一个具有指定名称的新数据库,并使用提供的配置变量进行初始化。此外,它将执行在/docker-entrypoint-initdb.d中找到的扩展名为.sh、.sql和.sql.gz的文件。文件将按字母顺序执行。您可以通过将SQL转储挂载到该目录中,并使用贡献的数据提供自定义映像来轻松填充mysql服务。默认情况下,SQL文件将被导入到由MYSQL_DATABASE变量指定的数据库中。

参考网站:mysql – Official Image | Docker Hub

drone CICD 后端配置参考

部分说明可以参考 前端配置参考

.drone.yml

kind: pipeline
name: default
volumes:
  - name: .m2 # 缓存
    host:
      path: /tmp/.m2
steps:
- name: maven-build
  image: maven:3.6.3
  volumes:
  - name: .m2
    path: /root/.m2
  commands:
    - mvn clean package -DskipTests
- name: docker-build # 使用 dockerfile 打包成镜像, 并推送到镜像仓库
  image: plugins/docker
  settings:
    registry: xxxxx.xxxxx.aliyuncs.com
    repo: xxxxx.xxxxx.aliyuncs.com/xxxx/xxxxx
    username:
      from_secret: docker_username
    password:
      from_secret: docker_password
    tags: 
      - latest
      - ${DRONE_COMMIT}
      - ${DRONE_TARGET_BRANCH}
- name: ssh-publish # 使用 ssh 在 服务器上进行发布
  image: appleboy/drone-ssh
  settings:
    host:
      - xxxx.xxxxx.cn # 要发布的服务器域名或IP
    username: root
    password:
      from_secret: ssh_password
    port: 22
    command_timeout: 2m
    script:
      - cd /home/xxx
      - docker-compose pull backend # 拉取上一步推送的镜像
      - docker-compose up -d # 启动

Dockerfile

FROM openjdk:11.0.16-jre
COPY ./main/target/*.jar /app/app.jar
WORKDIR /app
EXPOSE 16666/tcp
ENTRYPOINT  ["java","-jar","./app.jar"]

drone CICD 前端配置参考

Drone by Harness ™ 是一个现代化的持续集成平台,它使忙碌的团队能够使用强大的云原生管道引擎自动化他们的构建、测试和发布工作流程。

Trusted 模式

这个脚本使用了 volumes ,按照 drone 的要求,需要开启项目的 Trusted 功能。 官网说明

管理员身份

普通用户直接进入这个页面是没有这个选项的,需要安装 drone 的时候配置 DRONE_USER_CREATE,用户名为git的账户名。

# environment
DRONE_USER_CREATE=username:用户名,admin:true

更详细的配置,参考 官方文档说明

配置 Secrets

这个样例中,分别使用了 docker_username 、docker_password 、ssh_password,分别表示docker的用户名,docker的密码,和部署服务器的密码。

如果将以上三个配置写在第一个Secrets中,则表示当前项目独享,而第二个Secrets 表示组织共享的。

更详细的说明,参考 Secrets官方说明

相关文件

.drone.yml

kind: pipeline
type: docker
name: default

volumes:
  - name: node_modules # 缓存
    host:
      path: /tmp/node_modules

steps:
- name: node-build
  image: node:16.15.0
  volumes:
  - name: node_modules
    path: /drone/src/node_modules
  commands:
    - npm config set registry https://registry.npm.taobao.org && npm install
    - npm run build
- name: docker-build # 使用 dockerfile 打包成镜像, 并推送到镜像仓库
  image: plugins/docker
  settings:
    registry: xxxxx.xxxxxxxx.aliyuncs.com
    repo: xxxxxx.xxxxxx.aliyuncs.com/xxxxx/xxxxx
    username:
      from_secret: docker_username
    password:
      from_secret: docker_password
    tags: 
      - latest
      - ${DRONE_COMMIT}
      - ${DRONE_TARGET_BRANCH}
- name: ssh-publish # 使用 ssh 在 服务器上进行发布
  image: appleboy/drone-ssh
  settings:
    host:
      - xxxxx.xxxxx.cn
    username: root
    password:
      from_secret: ssh_password
    port: 22
    command_timeout: 2m
    script:
      - cd /home/xxxxxxx # cd 到项目目录
      - docker-compose pull front # 拉取上一步推送的镜像
      - docker-compose up -d # 启动

Dockerfile

FROM nginx
COPY ./dist /app
COPY nginx.conf /etc/nginx/nginx.conf

nginx.conf

参考 VueCli官方配置

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
  worker_connections  1024;
}
http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
  access_log  /var/log/nginx/access.log  main;
  sendfile        on;
  keepalive_timeout  65;
  server {
    listen       80;
    server_name  localhost;
    location / {
      root   /app;
      index  index.html;
      try_files $uri $uri/ /index.html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   /usr/share/nginx/html;
    }
  }
}

dokcerfile 之缓存 node_modules

如果直接拷贝代码到 /app 目录,由于每次编译时,代码都会改变,所以都需要重新下载依赖。

如果将依赖下载提到前面,就可以利用docker编译的缓存机制,达到加速编译的效果。

如果 package.json 改变,则会重新下载依赖。

Dockerfile 文件

FROM node:16.15.0 as build
# 将依赖文件拷贝到 tmp 文件夹
COPY ./package.json /tmp/package.json
# 下载依赖
RUN npm config set registry https://registry.npm.taobao.org && cd /tmp && npm install
# 将依赖拷贝到 /app
RUN mkdir /app && cp -a /tmp/node_modules /app/
WORKDIR /app
COPY ./ /app
RUN npm run build

FROM nginx
RUN mkdir /app
COPY --from=build /app/dist /app
COPY nginx.conf /etc/nginx/nginx.conf

nginx.conf 文件

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
events {
  worker_connections  1024;
}
http {
  include       /etc/nginx/mime.types;
  default_type  application/octet-stream;
  log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
  access_log  /var/log/nginx/access.log  main;
  sendfile        on;
  keepalive_timeout  65;
  server {
    listen       80;
    server_name  localhost;
    location / {
      root   /app;
      index  index.html;
      try_files $uri $uri/ /index.html;
    }
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   /usr/share/nginx/html;
    }
  }
}