Skip to content

Commit b61723f

Browse files
committed
[BUILD] Minimize docker container sizes
We use two techniques: 1) the use of a minimal docker base (FROM scratch + busybox) 2) the use of a static binary ... to create a minimally sized image for 'peer' and 'orderer' Before this patch, these containers are approximately 1.4GB. After this patch, they are about 20MB-24MB. It isn't strictly necessary to include busybox. The main benefit is achieved simply by eliminating external dependencies in the golang binary using -static and then getting rid of all the bloat in the baseimage via "FROM scratch". However, in this mode the image is pathologically bare-boned. For instance, the image has to be launched using the exec-form '["peer", "node", "start"]' since there is no shell interpreter available to do the more natural "CMD peer node start". Further, any "docker exec" style debugging would be impossible. It is often helpful to jump into a container and poke around with tools like ifconfig, ping, netstat, etc. Enter busybox: We can create a basic unix environment with only a 5MB payload. This is impressive and is easily worth its weight in the image. However, the challenge isn't really justifying the utility of having busybox over saving 5MB as much as it is about how we will get it into the image. If the world were a monochrome x86_64, we could simply s/FROM scratch/FROM busybox and be done. However, we have to consider other multi $arch. To support this, we forgo the temptation to use FROM busybox and build busybox from source. On my 2011 Macbook Pro, this adds about 5 minutes to the build, at least on the first build. Subsequent builds utilize the cache in ./build and thus are no-ops. This is _just_ fast enough that I am not embarrassed to propose it for consideration. However, if this is perceived as a problem we do have alternatives. For instance, we could start distributing a multi-$arch busybox base (hyperledger/fabric-busybox:$arch), TBD. Change-Id: I4ed20a429c2cc2e72fd602b45c5c8dd5548bc995 Signed-off-by: Greg Haskins <[email protected]>
1 parent 9bd4e85 commit b61723f

File tree

5 files changed

+51
-7
lines changed

5 files changed

+51
-7
lines changed

Makefile

+16-5
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ endif
4949
PKGNAME = github.com/$(PROJECT_NAME)
5050
GO_LDFLAGS = -X $(PKGNAME)/metadata.Version=$(PROJECT_VERSION)
5151
CGO_FLAGS = CGO_CFLAGS=" "
52+
GO_DOCKER_FLAGS= -ldflags "$(GO_LDFLAGS) -linkmode external -extldflags '-static -lpthread'"
5253
ARCH=$(shell uname -m)
5354
OS=$(shell uname)
5455
CHAINTOOL_RELEASE=v0.10.0
@@ -100,7 +101,7 @@ GOSHIM_DEPS = $(shell ./scripts/goListFiles.sh $(PKGNAME)/core/chaincode/shim |
100101
JAVASHIM_DEPS = $(shell git ls-files core/chaincode/shim/java)
101102
PROTOS = $(shell git ls-files *.proto | grep -v vendor)
102103
PROJECT_FILES = $(shell git ls-files)
103-
IMAGES = peer orderer ccenv javaenv testenv
104+
IMAGES = peer orderer ccenv javaenv testenv runtime
104105

105106
pkgmap.peer := $(PKGNAME)/peer
106107
pkgmap.orderer := $(PKGNAME)/orderer
@@ -160,12 +161,12 @@ linter: testenv
160161
build/docker/bin/%: $(PROJECT_FILES)
161162
$(eval TARGET = ${patsubst build/docker/bin/%,%,${@}})
162163
@echo "Building $@"
163-
@mkdir -p build/docker/bin build/docker/pkg
164+
@mkdir -p build/docker/bin build/docker/$(TARGET)/pkg
164165
@$(DRUN) \
165166
-v $(abspath build/docker/bin):/opt/gopath/bin \
166-
-v $(abspath build/docker/pkg):/opt/gopath/pkg \
167+
-v $(abspath build/docker/$(TARGET)/pkg):/opt/gopath/pkg \
167168
hyperledger/fabric-baseimage:$(BASE_DOCKER_TAG) \
168-
go install -ldflags "$(GO_LDFLAGS)" $(pkgmap.$(@F))
169+
go install $(GO_DOCKER_FLAGS) $(pkgmap.$(@F))
169170
@touch $@
170171

171172
build/bin:
@@ -181,10 +182,19 @@ build/docker/gotools: gotools/Makefile
181182
hyperledger/fabric-baseimage:$(BASE_DOCKER_TAG) \
182183
make install BINDIR=/opt/gotools/bin OBJDIR=/opt/gotools/obj
183184

184-
# Both peer and peer-docker depend on ccenv and javaenv (all docker env images it supports)
185+
build/docker/busybox:
186+
@$(DRUN) \
187+
hyperledger/fabric-baseimage:$(BASE_DOCKER_TAG) \
188+
make -f busybox/Makefile install BINDIR=$(@D)
189+
190+
# Both peer and peer-docker depend on ccenv and javaenv (all docker env images it supports).
185191
build/bin/peer: build/image/ccenv/.dummy build/image/javaenv/.dummy
186192
build/image/peer/.dummy: build/image/ccenv/.dummy build/image/javaenv/.dummy
187193

194+
# Both peer-docker and orderer-docker depend on the runtime image
195+
build/image/peer/.dummy: build/image/runtime/.dummy
196+
build/image/orderer/.dummy: build/image/runtime/.dummy
197+
188198
build/bin/%: $(PROJECT_FILES)
189199
@mkdir -p $(@D)
190200
@echo "$@"
@@ -205,6 +215,7 @@ build/image/peer/payload: build/docker/bin/peer \
205215
build/image/orderer/payload: build/docker/bin/orderer \
206216
orderer/orderer.yaml
207217
build/image/testenv/payload: build/gotools.tar.bz2
218+
build/image/runtime/payload: build/docker/busybox
208219

209220
build/image/%/payload:
210221
mkdir -p $@

busybox/Makefile

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
BUSYBOX_VER=1.25.1
2+
BUSYBOX_URL=https://www.busybox.net/downloads/busybox-$(BUSYBOX_VER).tar.bz2
3+
4+
OBJDIR=build/busybox-$(BUSYBOX_VER)
5+
6+
all: $(OBJDIR)/busybox
7+
8+
install: $(BINDIR)/busybox
9+
10+
$(BINDIR)/busybox: $(OBJDIR)/busybox
11+
mkdir -p $(@D)
12+
cp $< $@
13+
14+
$(OBJDIR)/.source:
15+
mkdir -p $(@D)
16+
curl -L $(BUSYBOX_URL) | (cd $(@D); tar --strip-components=1 -jx)
17+
touch $@
18+
19+
$(OBJDIR)/.config: $(OBJDIR)/.source
20+
make -C $(@D) defconfig
21+
22+
$(OBJDIR)/busybox: Makefile $(OBJDIR)/.config
23+
make -C $(@D) -l 2.5 -j all LDFLAGS=-static
24+
25+
clean:
26+
-rm -rf $(OBJDIR)
27+

images/orderer/Dockerfile.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM hyperledger/fabric-baseimage:_BASE_TAG_
1+
FROM hyperledger/fabric-runtime:_TAG_
22
ENV ORDERER_CFG_PATH /etc/hyperledger/fabric
33
RUN mkdir -p /var/hyperledger/db /etc/hyperledger/fabric
44
COPY payload/orderer /usr/local/bin

images/peer/Dockerfile.in

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM hyperledger/fabric-baseimage:_BASE_TAG_
1+
FROM hyperledger/fabric-runtime:_TAG_
22
ENV PEER_CFG_PATH /etc/hyperledger/fabric
33
RUN mkdir -p /var/hyperledger/db $PEER_CFG_PATH/msp
44
COPY payload/peer /usr/local/bin

images/runtime/Dockerfile.in

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FROM scratch
2+
COPY payload/busybox /bin/busybox
3+
RUN ["/bin/busybox", "mkdir", "-p", "/usr/bin", "/sbin", "/usr/sbin"]
4+
RUN ["/bin/busybox", "--install"]
5+
RUN mkdir -p /usr/local/bin
6+
ENV PATH=$PATH:/usr/local/bin

0 commit comments

Comments
 (0)