@cryptotaxi247 / kubo / commits / e2a3cd3b6

docker: switch from musl to glibc

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 <larsg@systemli.org>

Lars Gierth committed Sep 8, 2017 at 03:32 UTC e2a3cd3b66992b0e043b51a0c3dda3fa5cacd2c9
5 files changed +115 -77
.dockerignore
+2
@@ -1,3 +1,5 @@
1 +Dockerfile
2 +Dockerfile.fast
3 .git/
4 !.git/HEAD
5 !.git/refs/
Dockerfile
+54 -41
@@ -1,4 +1,4 @@
1 -FROM alpine:edge
1 +FROM golang:1.9-stretch
2 MAINTAINER Lars Gierth <lgierth@ipfs.io>
3
4 # There is a copy of this Dockerfile called Dockerfile.fast,
@@ -6,6 +6,51 @@ MAINTAINER Lars Gierth <lgierth@ipfs.io>
6 #
7 # Please keep these two Dockerfiles in sync.
8
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 +ENV SUEXEC_VERSION v0.2
24 +ENV TINI_VERSION v0.16.1
25 +RUN set -x \
26 + # Get su-exec, a very minimal tool for dropping privileges
27 + && cd /tmp \
28 + && git clone https://github.com/ncopa/su-exec.git \
29 + && cd su-exec \
30 + && git checkout -q $SUEXEC_VERSION \
31 + && make \
32 + # Get tini, a very minimal init daemon for containers
33 + && cd /tmp \
34 + && wget -q -O tini https://github.com/krallin/tini/releases/download/$TINI_VERSION/tini \
35 + && chmod +x tini
36 +
37 +# Get the TLS CA certificates, they're not provided by busybox.
38 +RUN apt-get install -y ca-certificates
39 +
40 +# Now comes the actual target image, which aims to be as small as possible.
41 +FROM busybox:1-glibc
42 +MAINTAINER Lars Gierth <lgierth@ipfs.io>
43 +
44 +# Get the ipfs binary, entrypoint script, and TLS CAs from the build container.
45 +ENV SRC_DIR /go/src/github.com/ipfs/go-ipfs
46 +COPY --from=0 $SRC_DIR/cmd/ipfs/ipfs /usr/local/bin/ipfs
47 +COPY --from=0 $SRC_DIR/bin/container_daemon /usr/local/bin/start_ipfs
48 +COPY --from=0 /tmp/su-exec/su-exec /sbin/su-exec
49 +COPY --from=0 /tmp/tini /sbin/tini
50 +COPY --from=0 /etc/ssl/certs /etc/ssl/certs
51 +
52 +# This shared lib (part of glibc) doesn't seem to be included with busybox.
53 +COPY --from=0 /lib/x86_64-linux-gnu/libdl-2.24.so /lib/libdl.so.2
54
55 # Ports for Swarm TCP, Swarm uTP, API, Gateway, Swarm Websockets
56 EXPOSE 4001
@@ -14,51 +59,19 @@ EXPOSE 5001
59 EXPOSE 8080
60 EXPOSE 8081
61
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
62 +# Create the fs-repo directory and switch to a non-privileged user.
63 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
64 +RUN mkdir -p $IPFS_PATH \
65 + && adduser -D -h $IPFS_PATH -u 1000 -g 100 ipfs \
66 + && chown 1000:100 $IPFS_PATH
67
68 # Expose the fs-repo as a volume.
34 -# start_ipfs initializes an fs-repo if none is mounted
69 +# start_ipfs initializes an fs-repo if none is mounted.
70 +# Important this happens after the USER directive so permission are correct.
71 VOLUME $IPFS_PATH
72
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
73 +# The default logging level
74 +ENV IPFS_LOGGING ""
75
76 # This just makes sure that:
77 # 1. There's an fs-repo, and initializes one if there isn't.
Dockerfile.fast
+57 -35
@@ -1,4 +1,4 @@
1 -FROM alpine:edge
1 +FROM golang:1.9-stretch
2 MAINTAINER Lars Gierth <lgierth@ipfs.io>
3
4 # This is a copy of /Dockerfile,
@@ -6,50 +6,72 @@ MAINTAINER Lars Gierth <lgierth@ipfs.io>
6 #
7 # Please keep these two Dockerfiles in sync.
8
9 +ENV GX_IPFS ""
10 +ENV SRC_DIR /go/src/github.com/ipfs/go-ipfs
11
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 +ENV SUEXEC_VERSION v0.2
36 +ENV TINI_VERSION v0.16.1
37 +RUN set -x \
38 + # Get su-exec, a very minimal tool for dropping privileges
39 + && cd /tmp \
40 + && git clone https://github.com/ncopa/su-exec.git \
41 + && cd su-exec \
42 + && git checkout -q $SUEXEC_VERSION \
43 + && make \
44 + # Get tini, a very minimal init daemon for containers
45 + && cd /tmp \
46 + && wget -q -O tini https://github.com/krallin/tini/releases/download/$TINI_VERSION/tini \
47 + && chmod +x tini \
48 + # Install them
49 + && mv su-exec/su-exec tini /sbin/
50 +
51 +# Ports for Swarm TCP, Swarm uTP, API, Gateway, Swarm Websockets
52 EXPOSE 4001
53 EXPOSE 4002/udp
54 EXPOSE 5001
55 EXPOSE 8080
56 +EXPOSE 8081
57
15 -ENV GX_IPFS ""
58 +# Create the fs-repo directory and switch to a non-privileged user.
59 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
60 +RUN mkdir -p $IPFS_PATH \
61 + && useradd -s /usr/sbin/nologin -d $IPFS_PATH -u 1000 -g 100 ipfs \
62 + && chown 1000:100 $IPFS_PATH
63
64 +# Expose the fs-repo as a volume.
65 +# start_ipfs initializes an fs-repo if none is mounted.
66 VOLUME $IPFS_PATH
67
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
68 +# The default logging level
69 +ENV IPFS_LOGGING ""
70
71 +# This just makes sure that:
72 +# 1. There's an fs-repo, and initializes one if there isn't.
73 +# 2. The API and Gateway are accessible from outside the container.
74 ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/start_ipfs"]
75 +
76 +# Execute the daemon subcommand by default
77 CMD ["daemon", "--migrate=true"]
bin/container_daemon
+1
@@ -4,6 +4,7 @@ user=ipfs
4 repo="$IPFS_PATH"
5
6 if [ `id -u` -eq 0 ]; then
7 + echo "Changing user to $user"
8 # ensure folder is writable
9 su-exec "$user" test -w "$repo" || chown -R -- "$user" "$repo"
10 # restart script with new privileges
test/sharness/t0301-docker-migrate.sh
+1 -1
@@ -69,7 +69,7 @@ test_expect_success "kill the net cat" '
69 '
70
71 test_expect_success "correct version was requested" '
72 - grep "/fs-repo-migrations/v1.1.1/fs-repo-migrations_v1.1.1_linux-musl-amd64.tar.gz" dist_serv_out > /dev/null
72 + grep "/fs-repo-migrations/v1.1.1/fs-repo-migrations_v1.1.1_linux-amd64.tar.gz" dist_serv_out > /dev/null
73 '
74
75 test_done