GitLab流水线拉取Docker镜像成功,但AWS Lightsail实例中镜像消失
GitLab CI/CD部署Docker镜像到AWS Lightsail后镜像/容器消失问题
问题描述
我通过GitLab CI/CD流水线将Docker镜像从GitLab容器仓库部署至AWS Lightsail实例,流水线日志显示镜像拉取成功、所有Docker命令执行无报错,但登录Lightsail实例后,执行docker images和docker ps -a既看不到对应镜像,也找不到运行的容器。
CD作业代码
ssh -o StrictHostKeyChecking=no user@<Lightsail-IP> << "EOF" echo "$DOCKER_ACCESS_KEY" | docker login -u "$DOCKER_USERNAME" --password-stdin https://registry.gitlab.com/ && docker pull registry.gitlab.com/repo/backend-app:develop && docker tag registry.gitlab.com/repo/backend-app:develop backend-app:develop && docker run --name backend-app -p 80:8080 -d registry.gitlab.com/repo/backend-app:develop EOF
流水线拉取日志片段
a2318d6c47ec: Pull complete 99a31bbbcd61: Pull complete 24da4c394c8b: Pull complete fe7649cc1e2b: Pull complete b16c49eb2a3e: Pull complete f69474871ffa: Pull complete 18447de3a64d: Pull complete c996151d738b: Pull complete Digest: sha256:83d9c29bd5546a099153a81d52f7051b14b0db2792ad7908ed70b8be3971e142 Status: Downloaded newer image for registry.gitlab.com/repo/backend-app:develop registry.gitlab.com/repo/backend-app:develop b93fac7f2b1576d4885debd7bb9d9e779ae4731cd07fe254e32e183436a0a012
可能的原因及解决办法
1. SSH会话与登录用户的Docker环境不一致
- 问题:流水线通过SSH执行命令时使用的
user用户,和你登录实例的用户不是同一主体;或者user没有Docker权限,命令实际以sudo执行,镜像存储在root用户的Docker环境中,普通用户无法查看。 - 解决:
- 在SSH脚本中给所有Docker命令添加
sudo:ssh -o StrictHostKeyChecking=no user@<Lightsail-IP> << "EOF" echo "$DOCKER_ACCESS_KEY" | sudo docker login -u "$DOCKER_USERNAME" --password-stdin https://registry.gitlab.com/ && sudo docker pull registry.gitlab.com/repo/backend-app:develop && sudo docker tag registry.gitlab.com/repo/backend-app:develop backend-app:develop && sudo docker run --name backend-app -p 80:8080 -d registry.gitlab.com/repo/backend-app:develop EOF - 或者将
user加入docker用户组,避免每次用sudo:在实例执行sudo usermod -aG docker user,重新登录该用户后生效。
- 在SSH脚本中给所有Docker命令添加
2. Docker容器启动后立即退出
- 问题:
docker run命令返回成功,但容器因配置错误(端口冲突、环境变量缺失、启动脚本报错等)立即退出,未保留运行状态;若实例开启了Docker自动清理策略,未运行的容器或关联镜像可能被删除。 - 解决:
- 在SSH脚本中添加日志查看命令,定位退出原因:
ssh -o StrictHostKeyChecking=no user@<Lightsail-IP> << "EOF" echo "$DOCKER_ACCESS_KEY" | sudo docker login -u "$DOCKER_USERNAME" --password-stdin https://registry.gitlab.com/ && sudo docker pull registry.gitlab.com/repo/backend-app:develop && sudo docker tag registry.gitlab.com/repo/backend-app:develop backend-app:develop && sudo docker run --name backend-app -p 80:8080 -d registry.gitlab.com/repo/backend-app:develop || echo "容器启动失败" && sudo docker logs backend-app EOF - 检查端口映射是否冲突(实例80端口是否被其他服务占用)、镜像内启动命令是否有效。
- 在SSH脚本中添加日志查看命令,定位退出原因:
3. SSH heredoc的变量替换失效
- 问题:脚本中使用
<< "EOF"(带双引号)会阻止GitLab CI/CD环境变量($DOCKER_ACCESS_KEY、$DOCKER_USERNAME)的替换,导致Docker登录实际失败,后续命令看似执行成功但未产生有效结果。 - 解决:去掉EOF的双引号,让变量正常传递到远程实例:
ssh -o StrictHostKeyChecking=no user@<Lightsail-IP> << EOF echo "$DOCKER_ACCESS_KEY" | sudo docker login -u "$DOCKER_USERNAME" --password-stdin https://registry.gitlab.com/ && sudo docker pull registry.gitlab.com/repo/backend-app:develop && sudo docker tag registry.gitlab.com/repo/backend-app:develop backend-app:develop && sudo docker run --name backend-app -p 80:8080 -d registry.gitlab.com/repo/backend-app:develop EOF
4. 实例磁盘空间不足
- 问题:实例磁盘已满,Docker无法存储拉取的镜像文件,完成拉取后自动清理了临时文件。
- 解决:
- 在SSH脚本中添加磁盘检查命令:
df -h - 清理实例中无用的Docker资源:
sudo docker system prune -af
- 在SSH脚本中添加磁盘检查命令:
内容的提问来源于stack exchange,提问作者Khazar Neverland
相关产品推荐
相关产品推荐

