GitLab CI/CD流水线构建WAR包并部署至Tomcat容器的路径问题求助
解决GitLab CI中Dockerfile无法访问$CI_PROJECT_DIR路径的问题
你遇到的问题其实是Docker构建上下文和CI环境变量作用域的问题,我来一步步帮你梳理解决:
问题根源
- Docker构建时,只有构建上下文目录(也就是你
docker build命令最后指定的目录,这里是.即项目根目录)里的文件能被Docker daemon访问,$CI_PROJECT_DIR是GitLab Runner的环境变量,Dockerfile在构建过程中根本识别不到这个变量。 - 另外,GitLab CI的不同Job之间默认不会共享文件,你在
build阶段生成的WAR包,如果不通过artifacts配置传递,package阶段的Job根本拿不到这个文件。
解决方案步骤
1. 调整.gitlab-ci.yml,传递构建产物
在project-build Job里添加artifacts配置,把生成的target目录传递给后续的package阶段:
stages: - build - package variables: MAVEN_CLI_OPTS: '-s /appdir/.m2/settings.xml' MAVEN_PATH: '/appdir/opt/apache-maven-3.8.4/bin' IMAGE_PATH: 'gitlab-registry.gs.mil/gteam-development/docker' project-build: image: ${IMAGE_PATH}/maven stage: build script: - ${MAVEN_PATH}/mvn ${MAVEN_CLI_OPTS} clean package - ls -als target # 确认WAR包已生成 artifacts: paths: - target/ # 把target目录作为构建产物传递给下一个Job expire_in: 1h # 可选,设置产物过期时间,节省存储空间 build docker image: stage: package image: docker services: - docker:dind script: - echo $CI_REGISTRY_PASSWORD | docker login -u $CI_REGISTRY_USER $CI_REGISTRY --password-stdin - ls -als target # 可选,确认已拿到WAR包 - docker build -t $CI_REGISTRY_IMAGE . - docker push $CI_REGISTRY_IMAGE tags: - dind
2. 修改Dockerfile,使用相对路径复制WAR包
因为target目录现在已经在Docker构建上下文(项目根目录)里了,直接用相对路径就能访问到WAR包,不需要任何环境变量:
FROM tomcat:latest LABEL maintainer="Jacquelyne Wilson" # 直接用构建上下文里的相对路径复制WAR包到Tomcat的webapps目录 COPY target/geoint-rfi-data-api.war /usr/local/tomcat/webapps/ EXPOSE 8080 CMD ["catalina.sh", "run"]
额外优化建议
- 如果你担心构建上下文太大(比如包含很多不需要的文件),可以在项目根目录添加
.dockerignore文件,排除掉不需要的文件,加快构建速度:.git/ .gitignore README.md # 其他你不想包含在构建上下文的文件或目录 - 首次创建CI流水线不用太纠结术语问题,多试几次就熟悉啦😉
内容的提问来源于stack exchange,提问作者jlwilson




