Skip to content

Commit 2fa39fb

Browse files
author
Lars Gierth
committed
docker: switch from musl to glibc, and simplify stuff
The Dockerfile now has two stages: build and assembly. This allows for a full-fledged debian build container, while still resulting in a super-thin busybox image. License: MIT Signed-off-by: Lars Gierth <[email protected]>
1 parent f55a7a0 commit 2fa39fb

File tree

4 files changed

+94
-85
lines changed

4 files changed

+94
-85
lines changed

.dockerignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
Dockerfile
2+
Dockerfile.fast
13
.git/
24
!.git/HEAD
35
!.git/refs/

Dockerfile

+43-41
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,46 @@
1-
FROM alpine:edge
1+
FROM golang:1.9-stretch
22
MAINTAINER Lars Gierth <[email protected]>
33

44
# There is a copy of this Dockerfile called Dockerfile.fast,
55
# which is optimized for build time, instead of image size.
66
#
77
# Please keep these two Dockerfiles in sync.
88

9+
ENV GX_IPFS ""
10+
ENV SRC_DIR /go/src/github.com/ipfs/go-ipfs
11+
12+
COPY . $SRC_DIR
13+
14+
# Build the thing.
15+
RUN cd $SRC_DIR \
16+
# Required for getting the HEAD commit hash via git rev-parse.
17+
&& mkdir .git/objects \
18+
# Allows using a custom (i.e. local) IPFS API endpoint.
19+
&& ([ -z "$GX_IPFS" ] || echo $GX_IPFS > /root/.ipfs/api) \
20+
# Build the thing.
21+
&& make build
22+
23+
# Get the TLS CA certificates, they're not provided by busybox.
24+
RUN apt-get install -y ca-certificates
25+
26+
# Now comes the actual target image, which aims to be as small as possible.
27+
FROM busybox:1-glibc
28+
MAINTAINER Lars Gierth <[email protected]>
29+
30+
# Get the ipfs binary, entrypoint script, and TLS CAs from the build container.
31+
ENV SRC_DIR /go/src/github.com/ipfs/go-ipfs
32+
COPY --from=0 $SRC_DIR/cmd/ipfs/ipfs /usr/local/bin/ipfs
33+
COPY --from=0 $SRC_DIR/bin/container_daemon /usr/local/bin/start_ipfs
34+
COPY --from=0 /etc/ssl/certs /etc/ssl/certs
35+
36+
# This shared lib (part of glibc) doesn't seem to be included with busybox.
37+
COPY --from=0 /lib/x86_64-linux-gnu/libdl-2.24.so /lib/libdl.so.2
38+
39+
# This installs a very simple program acting as the init process.
40+
# Makes sure signals are properly passed to the ipfs daemon process.
41+
ENV TINI_VERSION v0.16.1
42+
ADD https://github.com/krallin/tini/releases/download/$TINI_VERSION/tini /sbin/tini
43+
RUN chmod +x /sbin/tini
944

1045
# Ports for Swarm TCP, Swarm uTP, API, Gateway, Swarm Websockets
1146
EXPOSE 4001
@@ -14,51 +49,18 @@ EXPOSE 5001
1449
EXPOSE 8080
1550
EXPOSE 8081
1651

17-
# IPFS API to use for fetching gx packages.
18-
# This can be a gateway too, since its read-only API provides all gx needs.
19-
# - e.g. /ip4/172.17.0.1/tcp/8080 if the Docker host
20-
# has the IPFS gateway listening on the bridge interface
21-
# provided by Docker's default networking.
22-
# - if empty, the public gateway at ipfs.io is used.
23-
ENV GX_IPFS ""
24-
# The IPFS fs-repo within the container
52+
# Create the fs-repo directory and switch to a non-privileged user.
2553
ENV IPFS_PATH /data/ipfs
26-
# The default logging level
27-
ENV IPFS_LOGGING ""
28-
# Golang stuff
29-
ENV GOPATH /go
30-
ENV PATH /go/bin:$PATH
31-
ENV SRC_PATH /go/src/github.com/ipfs/go-ipfs
54+
RUN mkdir -p $IPFS_PATH && adduser -D -h $IPFS_PATH -u 1000 -g 100 ipfs
55+
USER ipfs
3256

3357
# Expose the fs-repo as a volume.
34-
# start_ipfs initializes an fs-repo if none is mounted
58+
# start_ipfs initializes an fs-repo if none is mounted.
59+
# Important this happens after the USER directive so permission are correct.
3560
VOLUME $IPFS_PATH
3661

37-
# Get the go-ipfs sourcecode
38-
COPY . $SRC_PATH
39-
40-
RUN apk add --no-cache --virtual .build-deps-ipfs musl-dev gcc go git \
41-
&& apk add --no-cache tini su-exec bash wget ca-certificates \
42-
# Setup user
43-
&& adduser -D -h $IPFS_PATH -u 1000 ipfs \
44-
# Install gx
45-
&& go get -u github.com/whyrusleeping/gx \
46-
&& go get -u github.com/whyrusleeping/gx-go \
47-
# Point gx to a specific IPFS API
48-
&& ([ -z "$GX_IPFS" ] || echo $GX_IPFS > $IPFS_PATH/api) \
49-
# Invoke gx
50-
&& cd $SRC_PATH \
51-
&& gx --verbose install --global \
52-
&& mkdir .git/objects && commit=$(git rev-parse --short HEAD) \
53-
&& echo "ldflags=-X github.com/ipfs/go-ipfs/repo/config.CurrentCommit=$commit" \
54-
# Build and install IPFS and entrypoint script
55-
&& cd $SRC_PATH/cmd/ipfs \
56-
&& go build -ldflags "-X github.com/ipfs/go-ipfs/repo/config.CurrentCommit=$commit" \
57-
&& cp ipfs /usr/local/bin/ipfs \
58-
&& cp $SRC_PATH/bin/container_daemon /usr/local/bin/start_ipfs \
59-
&& chmod 755 /usr/local/bin/start_ipfs \
60-
# Remove all build-time dependencies
61-
&& apk del --purge .build-deps-ipfs && rm -rf $GOPATH && rm -vf $IPFS_PATH/api
62+
# The default logging level
63+
ENV IPFS_LOGGING ""
6264

6365
# This just makes sure that:
6466
# 1. There's an fs-repo, and initializes one if there isn't.

Dockerfile.fast

+49-35
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,69 @@
1-
FROM alpine:edge
1+
FROM golang:1.9-stretch
22
MAINTAINER Lars Gierth <[email protected]>
33

44
# This is a copy of /Dockerfile,
55
# except that we optimize for build time, instead of image size.
66
#
77
# Please keep these two Dockerfiles in sync.
88

9+
ENV GX_IPFS ""
10+
ENV SRC_DIR /go/src/github.com/ipfs/go-ipfs
911

12+
COPY ./package.json $SRC_DIR/package.json
13+
14+
RUN set -x \
15+
&& go get github.com/whyrusleeping/gx \
16+
&& go get github.com/whyrusleeping/gx-go \
17+
# Allows using a custom (i.e. local) IPFS API endpoint.
18+
&& ([ -z "$GX_IPFS" ] || echo $GX_IPFS > /root/.ipfs/api) \
19+
# Fetch the dependencies so we don't have to do it everytime.
20+
&& cd $SRC_DIR \
21+
&& gx install
22+
23+
COPY . $SRC_DIR
24+
25+
# Build the thing.
26+
RUN set -x \
27+
&& cd $SRC_DIR \
28+
# Required for getting the HEAD commit hash via git rev-parse.
29+
&& mkdir .git/objects \
30+
# Build the thing.
31+
&& make build \
32+
&& mv cmd/ipfs/ipfs /usr/local/bin/ipfs \
33+
&& mv bin/container_daemon /usr/local/bin/start_ipfs
34+
35+
# This installs a very simple program acting as the init process.
36+
# Makes sure signals are properly passed to the ipfs daemon process.
37+
ENV TINI_VERSION v0.16.1
38+
ADD https://github.com/krallin/tini/releases/download/$TINI_VERSION/tini /sbin/tini
39+
RUN chmod +x /sbin/tini
40+
41+
# Ports for Swarm TCP, Swarm uTP, API, Gateway, Swarm Websockets
1042
EXPOSE 4001
1143
EXPOSE 4002/udp
1244
EXPOSE 5001
1345
EXPOSE 8080
46+
EXPOSE 8081
1447

15-
ENV GX_IPFS ""
48+
# Create the fs-repo directory and switch to a non-privileged user.
1649
ENV IPFS_PATH /data/ipfs
17-
ENV IPFS_LOGGING ""
18-
ENV GOPATH /go
19-
ENV PATH /go/bin:$PATH
20-
ENV SRC_PATH /go/src/github.com/ipfs/go-ipfs
50+
RUN mkdir -p $IPFS_PATH \
51+
&& useradd -s /usr/sbin/nologin -d $IPFS_PATH -u 1000 -g 100 ipfs \
52+
&& chown 1000:100 $IPFS_PATH
53+
USER ipfs
2154

55+
# Expose the fs-repo as a volume.
56+
# start_ipfs initializes an fs-repo if none is mounted.
57+
# Important this happens after the USER directive so permission are correct.
2258
VOLUME $IPFS_PATH
2359

24-
# This is an optimization which avoids rebuilding
25-
# of the gx dependencies every time anything changes.
26-
# gx will only be invoked if the dependencies have changed.
27-
#
28-
# Put differently: if package.json has changed,
29-
# the image-id after this COPY command will change,
30-
# and trigger a re-run of all following commands.
31-
COPY ./package.json $SRC_PATH/package.json
32-
33-
RUN apk add --no-cache --virtual .build-deps-ipfs musl-dev gcc go git \
34-
&& apk add --no-cache tini su-exec bash wget ca-certificates \
35-
&& adduser -D -h $IPFS_PATH -u 1000 ipfs \
36-
&& go get -u github.com/whyrusleeping/gx \
37-
&& go get -u github.com/whyrusleeping/gx-go \
38-
&& ([ -z "$GX_IPFS" ] || echo $GX_IPFS > $IPFS_PATH/api) \
39-
&& cd $SRC_PATH \
40-
&& gx --verbose install --global
41-
42-
COPY . $SRC_PATH
43-
44-
RUN cd $SRC_PATH \
45-
&& mkdir .git/objects && commit=$(git rev-parse --short HEAD) \
46-
&& echo "ldflags=-X github.com/ipfs/go-ipfs/repo/config.CurrentCommit=$commit" \
47-
&& cd $SRC_PATH/cmd/ipfs \
48-
&& go build -ldflags "-X github.com/ipfs/go-ipfs/repo/config.CurrentCommit=$commit" \
49-
&& cp ipfs /usr/local/bin/ipfs \
50-
&& cp $SRC_PATH/bin/container_daemon /usr/local/bin/start_ipfs \
51-
&& chmod 755 /usr/local/bin/start_ipfs \
52-
&& apk del --purge .build-deps-ipfs && rm -rf $GOPATH && rm -vf $IPFS_PATH/api
60+
# The default logging level
61+
ENV IPFS_LOGGING ""
5362

63+
# This just makes sure that:
64+
# 1. There's an fs-repo, and initializes one if there isn't.
65+
# 2. The API and Gateway are accessible from outside the container.
5466
ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/start_ipfs"]
67+
68+
# Execute the daemon subcommand by default
5569
CMD ["daemon", "--migrate=true"]

bin/container_daemon

100644100755
-9
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,7 @@
11
#!/bin/sh
22
set -e
3-
user=ipfs
43
repo="$IPFS_PATH"
54

6-
if [ `id -u` -eq 0 ]; then
7-
# ensure folder is writable
8-
su-exec "$user" test -w "$repo" || chown -R -- "$user" "$repo"
9-
# restart script with new privileges
10-
exec su-exec "$user" "$0" "$@"
11-
fi
12-
13-
# 2nd invocation with regular user
145
ipfs version
156

167
if [ -e "$repo/config" ]; then

0 commit comments

Comments
 (0)