Rework the Dockerfile
- Have two Dockerfiles doing essentially the same, but optimized for build time (for tests) and image size (for Docker Hub) - Fetch gx dependencies - Expose port 4002 for utp - Specify go version, currently 1.5.3-r0 - Create ephemeral fs-repo if none is mounted - Have t0300-docker-image actually test IPFS, not just an echo - Make everything a bit less hardcoded - Remove dead shacheck License: MIT Signed-off-by: Lars Gierth <larsg@systemli.org>
Lars Gierth committed
Feb 4, 2016 at 04:19 UTC
81c8cffee9c01d2c8dc1efac76441ece9c3bdca2
8 files changed
+146
-52
.dockerignore
+3
-1
@@ -1 +1,3 @@
1
-.git
1
+cmd/ipfs/ipfs
2
+vendor/gx/
3
+test/
Dockerfile
+62
-23
@@ -1,34 +1,73 @@
1
FROM alpine:3.3
2
-MAINTAINER Brian Tiger Chow <btc@perfmode.com>
2
+MAINTAINER Lars Gierth <lgierth@ipfs.io>
3
+
4
+# There is a copy of this Dockerfile in test/sharness,
5
+# which is optimized for build time, instead of image size.
6
+#
7
+# Please keep these two Dockerfiles in sync.
8
4
-ENV IPFS_PATH /data/ipfs
5
-ENV GOPATH /go:/go/src/github.com/ipfs/go-ipfs/Godeps/_workspace
9
7
-EXPOSE 4001 5001 8080
8
-# 4001 = Swarm, 5001 = API, 8080 = HTTP transport
10
+# Ports for Swarm TCP, Swarm uTP, API, Gateway
11
+EXPOSE 4001
12
+EXPOSE 4002/udp
13
+EXPOSE 5001
14
+EXPOSE 8080
15
10
-ADD bin/container_daemon /usr/local/bin/start_ipfs
11
-ADD bin/container_shacheck /usr/local/bin/shacheck
16
+# Volume for mounting an IPFS fs-repo
17
+# This is moved to the bottom for technical reasons.
18
+#VOLUME $IPFS_PATH
19
13
-ADD . /go/src/github.com/ipfs/go-ipfs
14
-WORKDIR /go/src/github.com/ipfs/go-ipfs/cmd/ipfs
20
+# IPFS API to use for fetching gx packages.
21
+# This can be a gateway too, since its read-only API provides all gx needs.
22
+# - e.g. /ip4/172.17.0.1/tcp/8080 if the Docker host
23
+# has the IPFS gateway listening on the bridge interface
24
+# provided by Docker's default networking.
25
+# - if empty, the public gateway at ipfs.io is used.
26
+ENV GX_IPFS ""
27
+# The IPFS fs-repo within the container
28
+ENV IPFS_PATH /data/ipfs
29
+# Golang stuff
30
+ENV GO_VERSION 1.5.3-r0
31
+ENV GOPATH /go
32
+ENV PATH /go/bin:$PATH
33
+ENV SRC_PATH /go/src/github.com/ipfs/go-ipfs
34
16
-RUN adduser -D -h /data -u 1000 ipfs \
17
- && mkdir -p /data/ipfs && chown ipfs:ipfs /data/ipfs \
18
- && apk add --update bash ca-certificates git go \
19
- && go install -ldflags "-X github.com/ipfs/go-ipfs/repo/config.CurrentCommit=$(git rev-parse --short HEAD 2> /dev/null || echo unknown)" \
20
- && mv /go/bin/ipfs /usr/local/bin/ipfs \
21
- && chmod 755 /usr/local/bin/start_ipfs \
22
- && apk del --purge go git
35
+# Get the go-ipfs sourcecode
36
+COPY . $SRC_PATH
37
24
-WORKDIR /
25
-RUN rm -rf /go/src/github.com/ipfs/go-ipfs
38
+RUN apk add --update musl go=$GO_VERSION git bash wget ca-certificates \
39
+ # Setup user and fs-repo directory
40
+ && mkdir -p $IPFS_PATH \
41
+ && adduser -D -h $IPFS_PATH -u 1000 ipfs \
42
+ && chown ipfs:ipfs $IPFS_PATH && chmod 755 $IPFS_PATH \
43
+ # Install gx
44
+ && go get -u github.com/whyrusleeping/gx \
45
+ && go get -u github.com/whyrusleeping/gx-go \
46
+ # Point gx to a specific IPFS API
47
+ && ([ -z "$GX_IPFS" ] || echo $GX_IPFS > $IPFS_PATH/api) \
48
+ # Invoke gx
49
+ && cd $SRC_PATH \
50
+ && gx --verbose install --global \
51
+ # Build and install IPFS and entrypoint script
52
+ && cd $SRC_PATH/cmd/ipfs \
53
+ && go build -ldflags "-X github.com/ipfs/go-ipfs/repo/config.CurrentCommit=$(git rev-parse --short HEAD 2> /dev/null)" \
54
+ && cp ipfs /usr/local/bin/ipfs \
55
+ && cp $SRC_PATH/bin/container_daemon /usr/local/bin/start_ipfs \
56
+ && chmod 755 /usr/local/bin/start_ipfs \
57
+ # Remove all build-time dependencies
58
+ && apk del --purge musl go git && rm -rf $GOPATH && rm -vf $IPFS_PATH/api
59
60
+# Call uid 1000 "ipfs"
61
USER ipfs
28
-VOLUME /data/ipfs
62
30
-ENTRYPOINT ["/usr/local/bin/start_ipfs"]
63
+# Expose the fs-repo as a volume.
64
+# We're doing this down here (and not at the top),
65
+# so that the overlay directory is owned by the ipfs user.
66
+# start_ipfs initializes an ephemeral fs-repo if none is mounted,
67
+# which is why uid=1000 needs write permissions there.
68
+VOLUME $IPFS_PATH
69
32
-# build: docker build -t go-ipfs .
33
-# run: docker run -p 4001:4001 -p 5001:5001 go-ipfs:latest
34
-# run: docker run -p 8080:8080 -p 4001:4001 -p 5001:5001 go-ipfs:latest
70
+# This just makes sure that:
71
+# 1. There's an fs-repo, and initializes one if there isn't.
72
+# 2. The API and Gateway are accessible from outside the container.
73
+ENTRYPOINT ["/usr/local/bin/start_ipfs"]
bin/container_daemon
+9
-8
@@ -1,17 +1,18 @@
1
-#!/bin/bash
1
+#!/bin/sh
2
+
3
+user=$(whoami)
4
+repo="$IPFS_PATH"
5
6
# Test whether the mounted directory is writable for us
4
-if ( touch /data/ipfs/write_test 2>/dev/null ); then
5
- rm /data/ipfs/write_test
6
-else
7
- echo "ERR: /data/ipfs is not writable for user 'ipfs' (UID 1000)"
7
+if [ ! -w "$repo" 2>/dev/null ]; then
8
+ echo "error: $repo is not writable for user $user (uid=$(id -u $user))"
9
exit 1
10
fi
11
11
-echo "Running $(ipfs version)..."
12
+ipfs version
13
13
-if [ -e /data/ipfs/config ]; then
14
- echo "Found ipfs repository. Not initializing."
14
+if [ -e "$repo/config" ]; then
15
+ echo "Found IPFS fs-repo at $repo"
16
else
17
ipfs init
18
ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001
bin/container_shacheck
deleted
-10
@@ -1,10 +0,0 @@
1
-#!/bin/bash -xe
2
-
3
-VERSION=$1
4
-FILENAME=$2
5
-
6
-ONLINE_SHA=$( curl "https://gobuilder.me/api/v1/github.com/ipfs/go-ipfs/cmd/ipfs/signed-hashes/${VERSION}" 2>/dev/null | grep -A 4 ${FILENAME} | grep sha1 | awk '{ print $3 }' )
7
-
8
-echo "Checking SHA1: ${ONLINE_SHA} == $(sha1sum ${FILENAME} | awk '{print $1}')"
9
-
10
-echo "${ONLINE_SHA} ${FILENAME}" | sha1sum -cw
test/3nodetest/Makefile
+1
-1
@@ -25,7 +25,7 @@ bin/random: $(RANDOMSRC)/**/*.go
25
# just build it every time... this part isn't
26
# even the lengthy part, and it decreases pain.
27
docker_ipfs_image:
28
- cd $(IPFS_ROOT) && docker build -t $(IMAGE_NAME) .
28
+ docker build -t $(IMAGE_NAME) -f test/Dockerfile .
29
docker images | grep $(IMAGE_NAME)
30
31
clean:
test/Dockerfile
new
+54
@@ -0,0 +1,54 @@
1
+FROM alpine:3.3
2
+MAINTAINER Lars Gierth <lgierth@ipfs.io>
3
+
4
+# This is a copy of the root Dockerfile,
5
+# except that we optimize for build time, instead of image size.
6
+#
7
+# Please keep these two Dockerfiles in sync.
8
+#
9
+# Only sections different from the root Dockerfile are commented.
10
+
11
+
12
+EXPOSE 4001
13
+EXPOSE 4002/udp
14
+EXPOSE 5001
15
+EXPOSE 8080
16
+
17
+ENV GX_IPFS ""
18
+ENV IPFS_PATH /data/ipfs
19
+ENV GO_VERSION 1.5.3-r0
20
+ENV GOPATH /go
21
+ENV PATH /go/bin:$PATH
22
+ENV SRC_PATH /go/src/github.com/ipfs/go-ipfs
23
+
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 --update musl go=$GO_VERSION git bash wget ca-certificates \
34
+ && mkdir -p $IPFS_PATH \
35
+ && adduser -D -h $IPFS_PATH -u 1000 ipfs \
36
+ && chown ipfs:ipfs $IPFS_PATH && chmod 755 $IPFS_PATH \
37
+ && go get -u github.com/whyrusleeping/gx \
38
+ && go get -u github.com/whyrusleeping/gx-go \
39
+ && ([ -z "$GX_IPFS" ] || echo $GX_IPFS > $IPFS_PATH/api) \
40
+ && cd $SRC_PATH \
41
+ && gx --verbose install --global
42
+
43
+COPY . $SRC_PATH
44
+
45
+RUN cd $SRC_PATH/cmd/ipfs \
46
+ && go build -ldflags "-X github.com/ipfs/go-ipfs/repo/config.CurrentCommit=$(git rev-parse --short HEAD 2> /dev/null)" \
47
+ && cp ipfs /usr/local/bin/ipfs \
48
+ && cp $SRC_PATH/bin/container_daemon /usr/local/bin/start_ipfs \
49
+ && chmod 755 /usr/local/bin/start_ipfs \
50
+ && apk del --purge musl go git && rm -rf $GOPATH && rm -vf $IPFS_PATH/api
51
+
52
+USER ipfs
53
+VOLUME $IPFS_PATH
54
+ENTRYPOINT ["/usr/local/bin/start_ipfs"]
test/ipfs-test-lib.sh
+4
-4
@@ -38,14 +38,14 @@ shellquote() {
38
39
# Docker
40
41
-# This takes a directory, that should contain a Dockerfile, as argument
41
+# This takes a Dockerfile, and a build context directory
42
docker_build() {
43
- docker build --rm "$1"
43
+ docker build --rm -f "$1" "$2"
44
}
45
46
# This takes an image as argument and writes a docker ID on stdout
47
docker_run() {
48
- docker run -it -d -p 8080:8080 -p 4001:4001 -p 5001:5001 "$1"
48
+ docker run -d "$1"
49
}
50
51
# This takes a docker ID and a command as arguments
@@ -54,7 +54,7 @@ docker_exec() {
54
then
55
sudo lxc-attach -n "$(docker inspect --format '{{.Id}}' $1)" -- /bin/bash -c "$2"
56
else
57
- docker exec -i "$1" /bin/bash -c "$2"
57
+ docker exec -t "$1" /bin/bash -c "$2"
58
fi
59
}
60
test/sharness/t0300-docker-image.sh
+13
-5
@@ -33,7 +33,7 @@ TEST_TESTS_DIR=$(dirname "$TEST_SCRIPTS_DIR")
33
APP_ROOT_DIR=$(dirname "$TEST_TESTS_DIR")
34
35
test_expect_success "docker image build succeeds" '
36
- docker_build "$APP_ROOT_DIR" >actual
36
+ docker_build "$TEST_TESTS_DIR/Dockerfile" "$APP_ROOT_DIR" >actual
37
'
38
39
test_expect_success "docker image build output looks good" '
@@ -46,12 +46,20 @@ test_expect_success "docker image runs" '
46
DOC_ID=$(docker_run "$IMAGE_ID")
47
'
48
49
-test_expect_success "simple command can be run in docker container" '
50
- docker_exec "$DOC_ID" "echo Hello Worlds" >actual
49
+test_expect_success "docker image gateway is up" '
50
+ docker_exec "$DOC_ID" "wget --retry-connrefused --waitretry=1 --timeout=30 -t 30 \
51
+ -q -O - http://localhost:8080/version >/dev/null"
52
'
53
53
-test_expect_success "simple command output looks good" '
54
- echo "Hello Worlds" >expected &&
54
+test_expect_success "docker image API is up" '
55
+ docker_exec "$DOC_ID" "wget --retry-connrefused --waitretry=1 --timeout=30 -t 30 \
56
+ -q -O - http://localhost:5001/api/v0/version >/dev/null"
57
+'
58
+
59
+test_expect_success "simple ipfs add/cat can be run in docker container" '
60
+ expected="Hello Worlds" &&
61
+ HASH=$(docker_exec "$DOC_ID" "echo $(cat expected) | ipfs add | cut -d' ' -f2") &&
62
+ docker_exec "$DOC_ID" "ipfs cat $HASH" >actual &&
63
test_cmp expected actual
64
'
65