Usually, developers use a two-stage build process to build a container image. In the first stage, make the binary for the container image, and in the second stage, build the runtime container image, including that binary. To accomplish this, stacker "build only" container builds the required binary and does not generate the corresponding OCI layer. Then copy this binary into the RFS of the runtime image such that the final container has only the required binary.
Two-stage container image build
cat > "hello_stacker.go" << EOF
package main
import "fmt"
func main() {
fmt.Println("Hello Stacker!")
}
EOF
cat > "hello.stacker.yaml" << EOF
build-hello-stacker:
from:
type: docker
url: docker://zothub.io/c3/ubuntu/go-devel-amd64:1.19.2
import:
- ./hello_stacker.go
build_only: true
run: |
# Source Go toolchain env
. /etc/profile
# Setup Go ENV
mkdir -p /go
export GOPATH=/go
mkdir -p /go/src
cd /go/src
# Copy source code to go path
cp /stacker/hello_stacker.go .
# Build a static go binary
go build -ldflags="-extldflags=-static" -o hello_stacker.static hello_stacker.go
cp hello_stacker.static /
hello:
from:
type: docker
url: docker://zothub.io/tools/busybox:stable
import:
- stacker://build-hello-stacker/hello_stacker.static
run: |
cp /stacker/hello_stacker.static /hello_stacker
chmod +x /hello_stacker
/hello_stacker # test
EOF
stacker build -f hello.stacker.yaml
preparing image build-hello-stacker...
copying /dev/shm/ravi/hello_stacker.go
loading docker://zothub.io/c3/ubuntu/go-devel-amd64:1.19.2
Copying blob b900f44d647a done
Copying config 3ece5b544e done
Writing manifest to image destination
Storing signatures
+ . /etc/profile
+ export 'HOME=/go'
+ export 'GOROOT=/opt/go'
+ export 'PATH=/opt/go/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin'
+ mkdir -p /tmp/go/cache
+ export 'GOCACHE=/tmp/go/cache'
+ mkdir -p /go
+ export 'GOPATH=/go'
+ mkdir -p /go/src
+ cd /go/src
+ cp /stacker/hello_stacker.go .
+ go build '-ldflags=-extldflags=-static' -o hello_stacker.static hello_stacker.go
+ cp hello_stacker.static /
preparing image hello...
loading docker://zothub.io/tools/busybox:stable
Copying blob f5b7ce95afea done
Copying config 74c82eccc6 done
Writing manifest to image destination
Storing signatures
+ cp /stacker/hello_stacker.static /hello_stacker
+ chmod +x /hello_stacker
+ /hello_stacker
Hello Stacker!
filesystem hello built successfully
Info
stacker://build-hello-stacker/hello_stacker.static
import statement imports the specific binary file from the build-hello-stacker
that is present in the build cache
Lets verify that the hello layer has /hello_stacker file:
stacker chroot
stacker chroot -f hello.stacker.yaml hello
This chroot is temporary, any changes will be destroyed when it exits.
/ # ls -al /hello_stacker
-rwxrwxr-x 1 root root 1809694 Oct 26 01:27 /hello_stacker
/ # exit
Last update: October 26, 2022