【发布时间】:2019-07-26 00:50:24
【问题描述】:
我的开发团队维护两个通过 REST 交互的独立 Web 应用程序。
一个应用程序是用 Go 构建的,另一个是用 Python 构建的。
为了在 Prod 发布之前确认这两个应用程序正确交互,我们旨在创建一个自动化的 CircleCI 集成测试作业,该作业执行以下操作:
集成测试要求:
- 查看 Go 和 Python 应用程序
- 在 localhost 上构建并启动这两个应用程序
- 在 Go 应用调用 Python 应用的地方运行实时集成测试
问题: CircleCi (https://circleci.com/docs/2.0/circleci-images/) 中的预构建 Docker 映像仅支持一种主要语言。
解决方案: 为了在同一个 CircleCI 作业中同时运行 Go 和 Python 服务器,我们创建了一个自定义 Docker 映像,该映像结合了公共 circleCI Golang 和 Python 映像。
为了帮助可能遇到类似情况的其他团队(即需要 Java + Python CircleCi docker 容器的团队),分享我们为解决此问题而采取的步骤。
创建自定义 Go + Python docker 映像并在 CircleCi 中使用的步骤
- 在 Docker Hub 中创建一个公共存储库并将其链接到现有的 Github 帐户。
- 这是我们用于本示例的 Docker Hub 存储库:https://hub.docker.com/r/ejparz/circleci-images/dockerfile
- 我们基于此处提供的公共 CircleCi Go 和 Python docker 映像创建了 DockerFile:
去: https://github.com/CircleCI-Public/circleci-dockerfiles/blob/master/golang/images/1.11.0/Dockerfile
在此处公开 go docker 基础镜像: https://github.com/docker-library/golang/blob/master/1.11/stretch/Dockerfile
我们的自定义 DockerFile:
FROM circleci/golang:1.11-stretch
FROM circleci/python:3.7.2-stretch
#Create regular go directory
COPY --from=0 /go /go
#Copy go binaries
COPY --from=0 /usr/local/go /usr/local/go
ENV GOPATH /go
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
#Use Root to set path permissions
USER root
RUN chmod -R 777 "$GOPATH"
#Add circleci user
USER circleci
#Add Shell
CMD ["/bin/sh"]
-
将我们的 Github Dockerfile 链接到 Docker Hub 并自动构建后,我们能够在 CircleCi 文件中引用该图像
run-system-integration-tests: docker: - image: ejparz/circleci-images:latest
从那里,我们能够在一个端口上启动我们的 Python 应用程序。
- run:
name: Start Python Django Server in background
command: |
cd ~/app
pipenv run python manage.py runserver
background: true
- run:
name: Waiting for python server to be ready
command: |
for i in `seq 1 10`;
do
nc -z localhost 8000 && echo Success && exit 0
echo -n .
sleep 1
done
echo Failed waiting for server && exit 1
然后从我们的 golang 应用程序调用该端口。 (或 curl 用于基本测试目的)
- run:
name: Test Port connectivity
command: |
curl http://localhost:8000
就是这样。
通过对上述 DockerFile 模板进行一些小调整,其他团队/用户应该能够轻松组合不同的 CircleCi 主要语言容器。
【问题讨论】: