我有一个要通过GitLab CI进行部署的Dockerized Angular / Node.js应用程序。
我使用GitLab CI,使用带有Runner的专用构建VM /服务器来构建映像并将其推送到GitLab容器注册表,然后应在其他服务器(即生产服务器)中将图像作为容器拉出并启动。
这是我的gitlab-ci.yml
文件现在的样子:
image: docker:latest
#services:
# - docker:dind
stages:
- build
- deploy
build-1:
stage: build
only:
- deploy
script:
- docker login -u $GITLAB_USERNAME -p $CI_ACCESS_TOKEN $CI_REGISTRY
- docker build -t $FRONTEND_IMG .
- echo Pushing Docker image to GitLab
- docker push $FRONTEND_IMG
when: manual
tags:
- my-runner
build-2:
stage: build
only:
- deploy
script:
- docker login -u $GITLAB_USERNAME -p $CI_ACCESS_TOKEN $CI_REGISTRY
- docker build -t $BACKEND_IMG .
- docker push $BACKEND_IMG
when: manual
tags:
- my-runner
deploy-live:
stage: deploy
only:
- deploy
before_script:
## Install ssh-agent if not already installed, it is required by Docker.
## (change apt-get to yum if you use an RPM-based image)
##
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
##
## Run ssh-agent (inside the build environment)
##
- eval $(ssh-agent -s)
##
## Add the SSH key stored in SSH_PRIVATE_KEY variable to the agent store
## We're using tr to fix line endings which makes ed25519 keys work
## without extra base64 encoding.
## https://gitlab.com/gitlab-examples/ssh-private-key/issues/1#note_48526556
##
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' | ssh-add -
##
## Create the SSH directory and give it the right permissions
##
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
# - mkdir -p ~/.ssh && touch ~/.ssh/known_hosts
# - echo "$SSH_KNOWN_HOSTS" >> ~/.ssh/known_hosts
##
## Use ssh-keyscan to scan the keys of your private server. Replace gitlab.com
## with your own domain name. You can copy and repeat that command if you have
## more than one server to connect to.
##
- ssh-keyscan $SERVER_IP_ADDRESS >> ~/.ssh/known_hosts
- chmod 644 ~/.ssh/known_hosts
script:
- echo SSH to prod server
- ssh $SERVER_USERNAME@$SERVER_IP_ADDRESS && ip addr show && docker login -u $GITLAB_USERNAME -p $CI_ACCESS_TOKEN $CI_REGISTRY && docker pull $FRONTEND_IMG && docker pull $BACKEND_IMG && docker-compose -f docker-compose.yml up -d
when: manual
tags:
- my-runner
问题是,docker命令似乎在构建服务器上执行(而不是在我们的ssh
生产服务器上),并且可以从那里访问应用程序,但不能从生产服务器上访问该应用程序。
在部署后在生产服务器上运行docker images
时,该列表显示为空。但是,当我在构建服务器中执行此操作时,已构建的图像就在其中。
Pseudo-terminal will not be allocated because stdin is not a terminal.
Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-66-generic x86_64)
* Documentation: https://help.ubuntu.com
* Management: https://landscape.canonical.com
* Support: https://ubuntu.com/advantage
System information as of Wed Apr 15 00:58:45 UTC 2020
System load: 0.0 Processes: 110
Usage of /: 6.0% of 24.06GB Users logged in: 2
Memory usage: 26% IP address for eth0: x.x.x.x
Swap usage: 0% IP address for docker0: x.x.x.x
121 packages can be updated.
73 updates are security updates.
mesg: ttyname failed: Inappropriate ioctl for device
我想念什么或做错什么了?
答案 0 :(得分:1)
在查看您的 ci 代码后,当您想在生产服务器上运行容器时,您应该使用 ansible。
Ansible 优于
ssh myserver "command1 && command2 &&....."
答案 1 :(得分:0)
我可以与您分享我的 ansible 文件 deploy.yml
# https://stackoverflow.com/questions/59384708/ansible-returns-with-failed-to-import-the-required-python-library-docker-sdk-f/65495769#65495769
---
- name: Build
hosts: local
connection: local
tags:
- build
tasks:
- name: Build Image
community.general.docker_image:
build:
path: .
pull: no
name: registry.digitalocean.com/main/example-com
push: true
source: build
force_source: yes
environment:
DOCKER_BUILDKIT: 1
- name: Deploy
hosts: remote
tags:
- deploy
vars:
path: /root/example.com
tasks:
- name: Creates directory
file:
path: "{{ path }}"
state: directory
- name: Copy Docker Compose
copy:
src: docker-compose.yml
dest: "{{ path }}/docker-compose.yml"
- name: Reload Compose
community.general.docker_compose:
pull: yes
project_src: "{{ path }}"
和 gitlab ci 文件 .gitlab-ci.yml
variables:
DOCKER_REGISTRY_DOMAIN: "registry.digitalocean.com"
DOCKER_HOST: tcp://docker:2375
DOCKER_TLS_CERTDIR: ""
DOCKER_DRIVER: overlay2
image: docker:latest
services:
- docker:dind
.deploy:
image: archlinux:latest
stage: deploy
before_script:
- pacman -Sy make ansible python python-pip openssh docker --noconfirm
- docker login -u ${DOCKER_TOKEN} -p ${DOCKER_TOKEN} ${DOCKER_REGISTRY_DOMAIN}
- pip3 install docker docker-compose
- eval $(ssh-agent -s)
- ssh-add <(echo $SSH_PRIVATE_KEY_BASE64 | base64 -d)
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
script:
- ansible-playbook -i hosts deploy.yml
deploy:
extends: .deploy
environment:
name: production
url: https://example.com
only:
refs:
- prod
终于hosts
[local]
127.0.0.1 env=prod
[remote]
xxx.xxx.xxx ansible_user=root env=prod
像 fei yang
一样,我也建议将 ssh
命令替换为 ansible
。
我认为可能存在这个问题:
ssh $SERVER_USERNAME@$SERVER_IP_ADDRESS && ip addr show
在我的电脑上我可以运行:
curl ipinfo.io
并得到:
{
"ip": "193.118.225.242"
...
然后我输入:
ssh root@104.248.40.145 && curl ipinfo.io
我明白了:
Last login: Thu Jun 17 07:53:38 2021 from 193.118.225.242
我已登录到服务器,但看不到 ipinfo
当我打字时
exit
从远程服务器注销我可以看到:
logout
Connection to 104.248.40.145 closed.
{
"ip": "193.118.225.242",
要通过 ssh 远程执行命令,您不应使用 &&
而应使用 ""
例如。
ssh root@104.248.40.145 "curl ipinfo.io"