From 440bec28d9f31cd4bfaf510e522d7d9e5a8f82ad Mon Sep 17 00:00:00 2001 From: Krishna Srinivas Date: Fri, 6 Nov 2015 16:46:04 -0800 Subject: [PATCH] docker: the docker image will now contain just the static binary --- Docker.md | 16 ++++++++++++++++ Dockerfile | 44 +++++++------------------------------------- Makefile | 12 +++++++++++- main.go | 13 +++++++++---- pkg/fs/config.go | 29 +++++++++++++++++++++++++---- server-config.go | 5 ++--- utils.go | 24 ++++++++++++++++++++++++ 7 files changed, 94 insertions(+), 49 deletions(-) create mode 100644 Docker.md diff --git a/Docker.md b/Docker.md new file mode 100644 index 000000000..8d521e14d --- /dev/null +++ b/Docker.md @@ -0,0 +1,16 @@ +# docker run + +To run docker image: +```docker run -p 9000:9000 minio/minio:latest``` + +This will start minio server in the docker container, the data however is not persistent. +If you need persistent storage you can use the command: + +```docker run -p 9000:9000 -v /home/krishna/.minio:/.minio -v /home/user/export:/export minio:latest``` + +Here the data uploaded to the minio server will be persisted to /home/user/export directory. + +# docker build + +To build the docker image: +```make dockerimage TAG=""``` diff --git a/Dockerfile b/Dockerfile index 34fb0e9f5..3fade6c49 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,38 +1,8 @@ -FROM ubuntu-debootstrap:14.04 - -MAINTAINER Minio Community - -ENV GOLANG_TARBALL go1.5.1.linux-amd64.tar.gz - -ENV GOROOT /usr/local/go/ -ENV GOPATH /go-workspace -ENV PATH ${GOROOT}/bin:${GOPATH}/bin/:$PATH - -ENV MINIOHOME /home/minio -ENV MINIOUSER minio -RUN useradd -m -d $MINIOHOME $MINIOUSER - -RUN apt-get update -y && apt-get install -y -q \ - curl \ - git \ - build-essential \ - ca-certificates - -RUN curl -O -s https://storage.googleapis.com/golang/${GOLANG_TARBALL} && \ - tar -xzf ${GOLANG_TARBALL} -C ${GOROOT%*go*} && \ - rm ${GOLANG_TARBALL} - -ADD . ${GOPATH}/src/github.com/minio/minio - -RUN cd ${GOPATH}/src/github.com/minio/minio && \ - make - -RUN apt-get remove -y build-essential curl git && \ - apt-get -y autoremove && \ - rm -rf /var/lib/apt/lists/* - -USER minio - +# use "make dockerimage" to build +FROM scratch +ENV DOCKERIMAGE 1 +ADD minio.dockerimage /minio +ADD export /export EXPOSE 9000 - -CMD ["sh", "-c", "${GOPATH}/bin/minio server"] +ENTRYPOINT ["/minio"] +CMD ["server", "/export"] diff --git a/Makefile b/Makefile index eb15ab3e4..d6f644f98 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,6 @@ LDFLAGS = $(shell go run buildscripts/gen-ldflags.go) +DOCKER_LDFLAGS = '-extldflags "-static"' +TAG = latest all: install @@ -53,7 +55,7 @@ test: build @GO15VENDOREXPERIMENT=1 go test $(GOFLAGS) github.com/minio/minio/pkg... gomake-all: build - @GO15VENDOREXPERIMENT=1 go build -ldflags $(LDFLAGS) -o $(GOPATH)/bin/minio + @GO15VENDOREXPERIMENT=1 go build --ldflags $(LDFLAGS) -o $(GOPATH)/bin/minio pkg-add: @GO15VENDOREXPERIMENT=1 govendor add $(PKG) @@ -66,6 +68,14 @@ pkg-remove: install: gomake-all +dockerimage: install + @echo "Building docker image:" minio:$(TAG) + @GO15VENDOREXPERIMENT=1 go build --ldflags $(LDFLAGS) --ldflags $(DOCKER_LDFLAGS) -o minio.dockerimage + @mkdir -p export + @docker build --rm --tag=minio:$(TAG) . + @rmdir export + @rm minio.dockerimage + clean: @echo "Cleaning up all the generated files:" @rm -fv cover.out diff --git a/main.go b/main.go index 79a348758..cdd01eea5 100644 --- a/main.go +++ b/main.go @@ -19,7 +19,6 @@ package main import ( "fmt" "os" - "os/user" "runtime" "strconv" @@ -29,18 +28,24 @@ import ( ) func init() { + // Check if minio was compiled using a supported version of Golang. + checkGolangRuntimeVersion() + // Check for the environment early on and gracefuly report. - _, err := user.Current() + _, err := userCurrent() if err != nil { Fatalf("Unable to obtain user's home directory. \nError: %s\n", err) } + if os.Getenv("DOCKERIMAGE") == "1" { + // the further checks are ignored for docker image + return + } + if os.Geteuid() == 0 { Fatalln("Please run ‘minio’ as a non-root user.") } - // Check if minio was compiled using a supported version of Golang. - checkGolangRuntimeVersion() } func migrate() { diff --git a/pkg/fs/config.go b/pkg/fs/config.go index c85decec4..bd6022d3e 100644 --- a/pkg/fs/config.go +++ b/pkg/fs/config.go @@ -17,6 +17,7 @@ package fs import ( + "os" "os/user" "path/filepath" @@ -24,13 +25,33 @@ import ( "github.com/minio/minio-xl/pkg/quick" ) +// workaround for docker images with fully static binary. +// for static binaries NSS library will not be a part of the static binary +// hence user.Current() fails +// more here : http://gnu.ist.utl.pt/software/libc/FAQ.html +// FAQ says : NSS (for details just type `info libc "Name Service Switch"') won't work properly without shared libraries +func userCurrent() (*user.User, *probe.Error) { + if os.Getenv("DOCKERIMAGE") == "1" { + wd, err := os.Getwd() + if err != nil { + return nil, probe.NewError(err) + } + return &user.User{Uid: "0", Gid: "0", Username: "root", Name: "root", HomeDir: wd}, nil + } + user, err := user.Current() + if err != nil { + return nil, probe.NewError(err) + } + return user, nil +} + func getFSBucketsConfigPath() (string, *probe.Error) { if customBucketsConfigPath != "" { return customBucketsConfigPath, nil } - u, err := user.Current() + u, err := userCurrent() if err != nil { - return "", probe.NewError(err) + return "", err.Trace() } fsBucketsConfigPath := filepath.Join(u.HomeDir, ".minio", "buckets.json") return fsBucketsConfigPath, nil @@ -40,9 +61,9 @@ func getFSMultipartsSessionConfigPath() (string, *probe.Error) { if customMultipartsConfigPath != "" { return customMultipartsConfigPath, nil } - u, err := user.Current() + u, err := userCurrent() if err != nil { - return "", probe.NewError(err) + return "", err.Trace() } fsMultipartsConfigPath := filepath.Join(u.HomeDir, ".minio", "multiparts-session.json") return fsMultipartsConfigPath, nil diff --git a/server-config.go b/server-config.go index 17049fc9c..62cfeef77 100644 --- a/server-config.go +++ b/server-config.go @@ -21,7 +21,6 @@ import ( "errors" "fmt" "os" - "os/user" "path/filepath" "github.com/fatih/color" @@ -124,9 +123,9 @@ func getConfigPath() (string, *probe.Error) { if customConfigPath != "" { return customConfigPath, nil } - u, err := user.Current() + u, err := userCurrent() if err != nil { - return "", probe.NewError(err) + return "", err.Trace() } configPath := filepath.Join(u.HomeDir, ".minio") return configPath, nil diff --git a/utils.go b/utils.go index 467692bff..888693d0f 100644 --- a/utils.go +++ b/utils.go @@ -18,8 +18,12 @@ package main import ( "encoding/base64" + "os" + "os/user" "strconv" "strings" + + "github.com/minio/minio-xl/pkg/probe" ) // isValidMD5 - verify if valid md5 @@ -51,3 +55,23 @@ func isMaxObjectSize(size string) bool { } return false } + +// workaround for docker images with fully static binary. +// for static binaries NSS library will not be a part of the static binary +// hence user.Current() fails +// more here : http://gnu.ist.utl.pt/software/libc/FAQ.html +// FAQ says : NSS (for details just type `info libc "Name Service Switch"') won't work properly without shared libraries +func userCurrent() (*user.User, *probe.Error) { + if os.Getenv("DOCKERIMAGE") == "1" { + wd, err := os.Getwd() + if err != nil { + return nil, probe.NewError(err) + } + return &user.User{Uid: "0", Gid: "0", Username: "root", Name: "root", HomeDir: wd}, nil + } + user, err := user.Current() + if err != nil { + return nil, probe.NewError(err) + } + return user, nil +}