Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding caching to Dockerfiles #5570

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 16 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,16 @@ MAINTAINER Lars Gierth <lgierth@ipfs.io>
ENV GX_IPFS ""
ENV SRC_DIR /go/src/github.com/ipfs/go-ipfs

COPY . $SRC_DIR
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a similar but different approach in making the ipfs-cluster docker build to be faster. Instead of caching the gx dependencies in the docker cache, which still requires you to load the gx dependencies via the docker network stack (hits ipfs.io/ipfs/... for each dependency, even though 99% they are already in your local gopath) at least once but also each time they are updated, I run gx install --local before building the docker container, which brings all the deps into the vendor/ directory and I added docker specific Make install target which uses gx install --local. This way the when docker copies the SRC_DIR into the build context it also brings the gx packages with it and then when building inside the container gx is able to use the already 'local' dependencies.

The advantage of this is that you get the benefit of the docker cache as well as never having to use the docker network stack to go out and retrieve dependencies again.

You can see the Makefile here and the Dockerfile here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @lanzafame , thanks for the info.

Unfortunately that is not a great solution for me, because I use a remote Docker host and I don't want to upload hundreds of megabytes worth of build context.

There are many reasons to use a remote build host. I use one because I'm on macOS.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rob-deutsch Would that maybe be case for a third Dockerfile, i.e. Dockerfile.remote? I have had enough fights with docker daemon networking issues that I would rather not see anymore network reliant requests be added to the Dockerfile.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To start with, I think this PR should be merged, because (I believe) it's a strict improvement over what's currently there.

Longer term, I don't mind whether there's a separate Dockerfile that sends all the dependancies in the build context.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rob-deutsch Have you considered "Docker for Mac" (free as in beer) which is actually just docker running in a headless linux VM on your local machine? It would still copy hundreds of megabytes of build context, but it would do so very quickly since nothing is transmitted over the network. Just a thought, anyway.

COPY ./package.json $SRC_DIR/package.json

# Build the thing.
# Also: fix getting HEAD commit hash via git rev-parse.
# Fetch dependencies.
# Also: allow using a custom IPFS API endpoint.
RUN cd $SRC_DIR \
&& mkdir .git/objects \
RUN set -x \
&& go get github.com/whyrusleeping/gx \
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer if gx and gx-go were copied over from the bin/ directory instead of getting the latest version every time so that way you have one less possible variation between a local build env and the docker daemon build env.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I'm pretty sure we neither want nor need gx in the docker build. We only need to do this here because we haven't run make build yet (which installs gx). Instead of this, I believe we should be running make deps (Dockerfile.fast should be doing the same thing).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make deps just install gx,gx-go if they aren't present which will be the case since the whole directory isn't being copied in. The added issue is that make deps uses dist_get to install gx,gx-go and dist_get also is missing due to the bin/ directory not being copied into the docker build context. Though using make deps solves the which version of gx,gx-go is being grabbed issue. We still need to copy in bin/dist_get at the least though to make it work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. Yes, we should be copying bin (I guess? I haven't read the docker documentation)

&& go get github.com/whyrusleeping/gx-go \
&& ([ -z "$GX_IPFS" ] || echo $GX_IPFS > /root/.ipfs/api) \
&& make build
&& cd $SRC_DIR \
&& gx install

# Get su-exec, a very minimal tool for dropping privileges,
# and tini, a very minimal init daemon for containers
Expand All @@ -33,6 +34,15 @@ RUN set -x \
&& wget -q -O tini https://github.com/krallin/tini/releases/download/$TINI_VERSION/tini \
&& chmod +x tini

COPY . $SRC_DIR

# Build the thing.
# Also: fix getting HEAD commit hash via git rev-parse.
RUN set -x \
&& cd $SRC_DIR \
&& mkdir .git/objects \
&& make build

# Get the TLS CA certificates, they're not provided by busybox.
RUN apt-get update && apt-get install -y ca-certificates

Expand Down
22 changes: 11 additions & 11 deletions Dockerfile.fast
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,6 @@ RUN set -x \
&& cd $SRC_DIR \
&& gx install

COPY . $SRC_DIR

# Build the thing.
# Also: fix getting HEAD commit hash via git rev-parse.
RUN set -x \
&& cd $SRC_DIR \
&& mkdir .git/objects \
&& make build \
&& mv cmd/ipfs/ipfs /usr/local/bin/ipfs \
&& mv bin/container_daemon /usr/local/bin/start_ipfs

# Get su-exec, a very minimal tool for dropping privileges,
# and tini, a very minimal init daemon for containers
ENV SUEXEC_VERSION v0.2
Expand All @@ -46,6 +35,17 @@ RUN set -x \
&& chmod +x tini \
&& mv su-exec/su-exec tini /sbin/ # Install them

COPY . $SRC_DIR

# Build the thing.
# Also: fix getting HEAD commit hash via git rev-parse.
RUN set -x \
&& cd $SRC_DIR \
&& mkdir .git/objects \
&& make build \
&& mv cmd/ipfs/ipfs /usr/local/bin/ipfs \
&& mv bin/container_daemon /usr/local/bin/start_ipfs

# Ports for Swarm TCP, Swarm uTP, API, Gateway, Swarm Websockets
EXPOSE 4001
EXPOSE 4002/udp
Expand Down