我正在使用Gitlab CE进行CI/CD,并且我有一个管道部署到ubuntu服务器,该服务器运行pm2
的应用程序。动作是:
- 删除
/node_modules
,/dist
和/tmp
文件夹 - 提取更新后的代码
- 将代码构建到
/dist
- 从
pm2
中删除应用程序 - 再次使用
pm2
启动应用程序
下面是管道:
image: node:16
before_script:
- apt-get update -qq
- apt-get install -qq git
- 'which ssh-agent || ( apt-get install -qq openssh-client )'
- eval $(ssh-agent -s)
- ssh-add <(echo "$K8S_SECRET_SSH_PRIVATE_KEY" | base64 -d)
- ssh-add <(echo "$K8S_SECRET_SSH_PRIVATE_KEY_AWS" | base64 -d)
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *ntStrictHostKeyChecking nonn" > ~/.ssh/config'
stages:
- deploy_production
deploy_production:
stage: deploy_production
only:
- master
script:
- ssh foo@example.com "cd /var/www/html/example2/example2.com && rm -rf node_modules dist/* tmp"
- ssh foo@example.com "cd /var/www/html/example2/example2.com && git pull origin master"
- ssh foo@example.com "source ~/.bash_profile && export NPM_TOKEN=${NPM_TOKEN} && export SECRET=${SECRET} && cd /var/www/html/example2/example2.com && nvm use --delete-prefix && git checkout master && npm ci --verbose && npm run prod"
- ssh foo@example.com "cd /var/www/html/example2/example2.com && pm2 delete example2.com"
- ssh foo@example.com "cd /var/www/html/example2/example2.com && export SECRET=${SECRET} && NODE_ENV=production pm2 start ./dist/server.js --name example2.com --update-env"
现在,当作业成功时,如果我进入生产服务器并列出pm2
实例,我将看到:
┌─────┬───────────────┬─────────────┬─────────┬─────────┬──────────┬────────┬──────┬───────────┬──────────┬──────────┬──────────┬──────────┐
│ id │ name │ namespace │ version │ mode │ pid │ uptime │ ↺ │ status │ cpu │ mem │ user │ watching │
├─────┼───────────────┼─────────────┼─────────┼─────────┼──────────┼────────┼──────┼───────────┼──────────┼──────────┼──────────┼──────────┤
│ 80 │ example2.com │ default │ 0.0.1 │ fork │ 3258598 │ 0s │ 0 │ online │ 0% │ 13.7mb │ foo │ disabled │
└─────┴───────────────┴─────────────┴─────────┴─────────┴──────────┴────────┴──────┴───────────┴──────────┴──────────┴──────────┴──────────┘
但是当我尝试访问应用程序时,它关闭了。现在,如果我直接通过ssh访问并手动删除并启动它,它将工作:
ssh foo@example.com
$ pm2 delete example2.com
$ export SECRET=my_secret && NODE_ENV=production pm2 start ./dist/server.js --name example2.com --update-env
如果有人知道为什么直接做它是有效的,而通过管道做它不是,请告诉我。
你可以仔细检查的一件事是你的用户权限,你在gitlab运行器内使用SSH -这些凭证不同于你手动使用的凭证吗?
我还建议改变你部署到生产服务器的方式。对我来说,在它上面保存一个git回购的副本听起来不太安全。相反,在您的情况下,我希望只提供已编译的二进制文件或dist文件夹,并且而不是在另一个服务器上远程运行git命令。
你也可以直接在你的生产服务器上安装一个自托管的gitlab运行器,对gitlab-runner用户设置有限的用户权限,然后创建一个构建作业来生成和压缩你的项目的dist文件夹。将这个压缩文件夹作为工件,然后您可以在生产服务器上有另一个作业来"解压缩"。并使用正确的用户权限进行部署。
我的意思是:
- 在你的生产服务器上安装一个自托管的gitlab(基于bash的就可以了)运行器
- 编辑你的ci脚本来构建你的dist文件夹,将其压缩并作为工件存储在gitlab中。
- 有一个将下载工件(在管道中自动发生)并在正确位置解压缩的生产作业阶段
- 使用chmod修改用户权限,以确保你的应用程序的解压缩的dist版本是由正确的用户拥有的-例如,如果你正在运行nginx,那么nginx用户需要拥有你想要服务的目录下的文件。
希望用户权限的事情有所帮助:)