Docker多阶段构建和Codeship运行容器

时间:2018-05-23 17:04:05

标签: docker go dockerfile codeship

我正在进行多阶段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多阶段构建的重点。

1 个答案:

答案 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,因为它将启动您的应用程序。我们使用第二阶段将较小的构建推送到映像注册表。