@cryptotaxi247 / kubo / commits / 81c8cffee

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