我正在进行多阶段Docker构建:
# Dockerfile
########## Build stage ##########
FROM golang:1.10 as build
ENV TEMP /go/src/github.com/my-id/my-go-project
WORKDIR $TEMP
COPY . .
RUN make build
########## Final stage ##########
FROM alpine:3.4
# ...
ENV HOME /home/$USER
ENV TEMP /go/src/github.com/my-id/my-go-project
COPY --from=build $TEMP/bin/my-daemon $HOME/bin/
RUN chown -R $USER:$GROUP $HOME
USER $USER
ENTRYPOINT ["my-daemon"]
并且Makefile
部分包含:
build: bin
go build -v -o bin/my-daemon cmd/my-daemon/main.go
bin:
mkdir $@
这一切都适用于docker build
。
现在我想使用Codeship,所以我有:
# codeship-services.yml
cachemanager:
build:
image: my-daemon
dockerfile: Dockerfile
和
# codeship-steps.yml
- name: my-daemon build
tag: master
service: my-service
command: true
问题是,如果我jet steps --master
,它构建一切正常,但运行容器就像我做了docker run
一样。为什么?我不希望希望它这样做。
好像我必须有两个单独的 Dockerfile
:一个仅用于构建阶段而一个仅用于 用于运行阶段,并将前者与jet
一起使用。但是这会破坏Docker多阶段构建的重点。
答案 0 :(得分:0)
按照本指南,我可以使用分成两个不同文件的多阶段构建来解决此问题:https://documentation.codeship.com/pro/common-issues/caching-multi-stage-dockerfile/
基本上,您将采用现有的Dockerfile并将其拆分为两个文件,第二个引用第一个:
# Dockerfile.build-stage
FROM golang:1.10 as build-stage
ENV TEMP /go/src/github.com/my-id/my-go-project
WORKDIR $TEMP
COPY . .
RUN make build
# Dockerfile
FROM build-stage as build-stage
FROM alpine:3.4
# ...
ENV HOME /home/$USER
ENV TEMP /go/src/github.com/my-id/my-go-project
COPY --from=build $TEMP/bin/my-daemon $HOME/bin/
RUN chown -R $USER:$GROUP $HOME
USER $USER
ENTRYPOINT ["my-daemon"]
然后,在您的codeship-service.yml文件中:
# codeship-services.yml
cachemanager-build:
build:
dockerfile: Dockerfile.build-stage
cachemanager-app:
build:
image: my-daemon
dockerfile: Dockerfile
在您的codeship-steps.yml文件中:
# codeship-steps.yml
- name: cachemanager build
tag: master
service: cachemanager-build
command: <here you can run tests or linting>
- name: publish to registry
tag: master
service: cachemanager-app
...
我认为您实际上不想运行Dockerfile
,因为它将启动您的应用程序。我们使用第二阶段将较小的构建推送到映像注册表。