Skip to content

Commit

Permalink
CNS-150: dockerize lavad build
Browse files Browse the repository at this point in the history
Update the Makefile and intorduce Dockerfile to improve lavad build.

Notable make targets (for all targets - see Makefile):

  make build			- local build (output in ./build/)
  make test			- run unit-tests
  make lint			- run the linter

  make docker-build		- local build with docker image (host arch)

  make build-images		- build and produce docker images (all archs)
  make build-image-amd64	- build and produce docker image (linux/amd64)
  make build-image-amd64	- build and produce docker image (linux/arm64)

Other notable changes:

- See Makefile for options to turn on/off via LAVA_BUILD_OPTIONS variable
- Specifically, use LAVA_BUILD_OPTIONS="static" to build static binary

Also updated .dockerignore (notably, added .git/ to avoid the cost). Anyway,
the copy only affects the builder stage in docker - nothing is copied to the
final image.

Also updates .gitignote (primarily some cleanup).
  • Loading branch information
orenl-lava committed Jan 17, 2023
1 parent b2fd20c commit 41ca04b
Show file tree
Hide file tree
Showing 5 changed files with 254 additions and 66 deletions.
31 changes: 9 additions & 22 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,25 +1,12 @@
vue/node_modules
vue/dist
release/
.idea/
.vscode/
.DS_Store
notes.txt
vue/src/store/generated/*
vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/index.js
vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/index.ts
vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/module/index.d.ts
vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/module/index.js
vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/module/index.ts
vue/src/store/generated/lavanet/lava/lavanet.lava.user/index.js
vue/src/store/generated/lavanet/lava/lavanet.lava.user/index.ts
vue/src/store/generated/lavanet/lava/lavanet.lava.user/module/index.d.ts
vue/src/store/generated/lavanet/lava/lavanet.lava.user/module/index.js
vue/src/store/generated/lavanet/lava/lavanet.lava.user/module/index.ts
relayer/cmd/relayer/__debug_bin
relayer/.env
testutil/e2e/logs/
ptnet/
build/
vue/src/store/generated/
vue/node_modules/
vue/dist/
scripts/vars/
testutil/e2e/logs/
testutil/debugging/
ts-client/
.github/
.git/
.idea/
.vscode/
43 changes: 22 additions & 21 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
vue/node_modules
vue/dist
build/
release/

# Intellij
.idea/
.vscode/

# macOS
.DS_Store
notes.txt
vue/src/store/generated/*
vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/index.js
vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/index.ts
vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/module/index.d.ts
vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/module/index.js
vue/src/store/generated/lavanet/lava/lavanet.lava.servicer/module/index.ts
vue/src/store/generated/lavanet/lava/lavanet.lava.user/index.js
vue/src/store/generated/lavanet/lava/lavanet.lava.user/index.ts
vue/src/store/generated/lavanet/lava/lavanet.lava.user/module/index.d.ts
vue/src/store/generated/lavanet/lava/lavanet.lava.user/module/index.js
vue/src/store/generated/lavanet/lava/lavanet.lava.user/module/index.ts
relayer/cmd/relayer/__debug_bin
relayer/.env

# vscode
.vscode/

# vim
.*.sw?

# Vue
vue/src/store/generated/
vue/node_modules
vue/dist

# Logs and debug
scripts/automation_scripts/automation_results*
testutil/e2e/logs/
ptnet/
scripts/vars/
testutil/debugging/
ts-client/
scripts/automation_scripts/automation_results*

# Misc
scripts/vars/
108 changes: 108 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# syntax = docker/dockerfile:1.2
# WARNING! Use with `docker buildx ...` or `DOCKER_BUILDKIT=1 docker build ...`
# to enable --mount feature used below.

########################################################################
# Dockerfile for reproducible build of lavad binary and docker image
########################################################################

ARG GO_VERSION="1.18.2"
ARG RUNNER_IMAGE="debian:11-slim"

# --------------------------------------------------------
# Base
# --------------------------------------------------------

FROM --platform=$BUILDPLATFORM golang:${GO_VERSION} as base

ARG GIT_VERSION
ARG GIT_COMMIT

# Download debian packages for building
RUN --mount=type=cache,target=/var/cache/apt \
rm -f /etc/apt/apt.conf.d/docker-clean && \
apt-get update && \
apt-get install -yqq --no-install-recommends \
build-essential \
ca-certificates \
curl

# --------------------------------------------------------
# Builder
# --------------------------------------------------------

FROM --platform=$BUILDPLATFORM base as builder

ARG TARGETOS
ARG TARGETARCH

# set GIT_CLONE=true to force 'git clone' of sources from repository
# (useful to compile a specific version, combined with GIT_VERSION).
ARG GIT_CLONE=false

# Download go dependencies
WORKDIR /lava
COPY go.mod go.sum ./
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
go mod download

# Copy the remaining files
COPY . .

# Git clone the sources if requested
# NOTE TODO: after reset of chain (lava-testnet-1) prefix 'v' to ${GIT_VERISON}
RUN if [ "${GIT_CLONE}" = true ]; then \
find . -mindepth 1 -delete && \
git clone --depth 1 --branch ${GIT_VERSION} https://github.com/lavanet/lava . \
; fi

# Remove tag v0.4.0 (same v0.4.0-rc2, which was used in the upgrade proposal
# and must always be reported) to not eclipse the v0.4.0-rc2 tag.
# NOTE TODO: after reset of chain (lava-testnet-1) remove this
RUN git tag -d v0.4.0 || true

# Fix glitch in Makefile for versions < 0.4.3
# NOTE TODO: after reset of chain (lava-testnet-1) remove this
RUN sed -i 's/whitespace += $(whitespace)/whitespace := $(whitespace) $(whitespace)/g' Makefile

# Export our version/commit for the Makefile to know (the .git directory
# is not here, so the Makefile cannot infer them).
ENV BUILD_VERSION=${GIT_VERSION}
ENV BUILD_COMMIT=${GIT_COMMIT}

ENV GOOS=${TARGETOS}
ENV GOARCH=${TARGETARCH}

# Build lavad binary
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
LAVA_BUILD_OPTIONS="static" make build

# --------------------------------------------------------
# Cosmovisor
# --------------------------------------------------------

FROM --platform=$BUILDPLATFORM builder as cosmovisor

# Download Cosmovisor
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
go get github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor@v1.0.0 \
&& go install github.com/cosmos/cosmos-sdk/cosmovisor/cmd/cosmovisor@v1.0.0


# --------------------------------------------------------
# Runner-base
# --------------------------------------------------------

# Download debian packages for runner

FROM ${RUNNER_IMAGE}

COPY --from=builder /lava/build/lavad /bin/lavad

ENV HOME /lava
WORKDIR $HOME

ENTRYPOINT ["/bin/lavad"]
4 changes: 0 additions & 4 deletions Dockerfile-base

This file was deleted.

134 changes: 115 additions & 19 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,50 @@
#!/usr/bin/make -f

VERSION ?= $(shell echo $(shell git describe --tags) | sed 's/^v//')
COMMIT ?= $(shell git log -1 --format='%H')
# Environment variable LAVA_BUILD_OPTIONS may embed compile options;
# Misc options: static, release, nostrip, cleveldb, rocksdb
# Lava options: mask_consumer_logs, debug_mutex

ifeq ($(shell test -d .git || echo false),false)
have_dot_git := false
# Without .git/ we expect VERSION and COMMIT explicitly provided.
# (For example, when called from our Dockerfile)
BUILD_VERSION ?= unknown
BUILD_COMMIT ?= unknown
VERSION := $(BUILD_VERSION)
COMMIT := $(BUILD_COMMIT)
else
have_dot_git := true
# Otherwise, grab the VERSION and COMMIT from git.
# Remove commit count (if current commit no tagged) to simplify output.
VERSION := $(shell git describe --tags --abbrev=7 --dirty | sed 's/-[0-9]*-g/-/')
COMMIT := $(shell git log -1 --format='%H')
endif

ifeq (true,$(have_dot_git))
ifeq (release,$(findstring release,$(LAVA_BUILD_OPTIONS)))
# For release, verify that the currently checked-out code is:
# - clean (no local uncommitted changes, no untracked files)
# - matching in version to the desired tag (no extra commit)
version_real := $(shell git describe --tags --exact-match 2> /dev/null || echo "none")
ifneq '$(VERSION)' '$(version_real)'
$(error Current checked-out code does not match requested release version)
endif
ifeq (-dirty,$(findstring -dirty,$(VERSION)))
$(error Current checked-out code has uncommitted changes or untracked files)
endif
endif

endif

# strip the leading 'v'
VERSION := $(subst v,,$(VERSION))

LEDGER_ENABLED ?= true
SDK_PACK := $(shell go list -m github.com/cosmos/cosmos-sdk | sed 's/ /\@/g')
GO_VERSION := $(shell cat go.mod | grep -E 'go [0-9].[0-9]+' | cut -d ' ' -f 2)
DOCKER := $(shell which docker)
BUILDDIR ?= $(CURDIR)/build
DEBUG_MUTEX ?= false
MASK_CONSUMER_LOGS ?= false

export GO111MODULE = on

# process build tags
Expand Down Expand Up @@ -44,19 +81,31 @@ endif
build_tags += $(BUILD_TAGS)
build_tags := $(strip $(build_tags))

whitespace :=
whitespace := $(whitespace) $(whitespace)
null :=
whitespace += $(null) $(null)
comma := ,
build_tags_comma_sep := $(subst $(whitespace),$(comma),$(build_tags))

# process linker flags

ldflags = -X github.com/cosmos/cosmos-sdk/version.Name=lava \
-X github.com/cosmos/cosmos-sdk/version.AppName=lavad \
-X github.com/cosmos/cosmos-sdk/version.Version=$(VERSION) \
-X github.com/cosmos/cosmos-sdk/version.Commit=$(COMMIT) \
-X github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep) \
-X github.com/lavanet/lava/relayer/chainproxy.ReturnMaskedErrors=$(MASK_CONSUMER_LOGS) \
-X github.com/lavanet/lava/utils.TimeoutMutex=$(DEBUG_MUTEX) \
-X "github.com/cosmos/cosmos-sdk/version.BuildTags=$(build_tags_comma_sep)"

# For static binaries just set CGO_ENABLED=0.
# (Using only '-link-mode=external -extldflags ...' does not work).
ifeq (static,$(findstring static,$(LAVA_BUILD_OPTIONS)))
export CGO_ENABLED = 0
endif

ifeq (mask_consumer_logs,$(findstring mask_consumer_logs,$(LAVA_BUILD_OPTIONS)))
ldflags += -X github.com/lavanet/lava/relayer/chainproxy.ReturnMaskedErrors=true
endif
ifeq (debug_mutex,$(findstring debug_mutex,$(LAVA_BUILD_OPTIONS)))
ldflags += -X github.com/lavanet/lava/utils.TimeoutMutex=true
endif

ifeq (cleveldb,$(findstring cleveldb,$(LAVA_BUILD_OPTIONS)))
ldflags += -X github.com/cosmos/cosmos-sdk/types.DBBackend=cleveldb
Expand All @@ -66,9 +115,7 @@ endif
ifeq (,$(findstring nostrip,$(LAVA_BUILD_OPTIONS)))
ldflags += -w -s
endif
ifeq ($(LINK_STATICALLY),true)
ldflags += -linkmode=external -extldflags "-Wl,-z,muldefs -static"
endif

ldflags += $(LDFLAGS)
ldflags := $(strip $(ldflags))

Expand All @@ -82,23 +129,54 @@ endif
### Build ###
###############################################################################

all: lint test

BUILD_TARGETS := build install

build: BUILD_ARGS=-o $(BUILDDIR)/

.PHONY: lint
lint:
golangci-lint run --config .golangci.yml

.PHONY: $(BUILD_TARGETS)
$(BUILD_TARGETS): go.sum $(BUILDDIR)/
go $@ -mod=readonly $(BUILD_FLAGS) $(BUILD_ARGS) ./...

$(BUILDDIR)/:
mkdir -p $(BUILDDIR)/

build-linux: go.sum
LEDGER_ENABLED=false GOOS=linux GOARCH=amd64 $(MAKE) build
# build lavad within docker (reproducible)
docker-build: TARGETARCH=$(shell GOARCH= go env GOARCH)
docker-build: build-docker-helper

# build lavad (reproducible) and produce docker image(s)
build-images: build-image-amd64 build-image-arm64

build-image-amd64: TARGETARCH=amd64
build-image-amd64: build-docker-helper build-docker-copier

build-image-arm64: TARGETARCH=arm64
build-image-arm64: build-docker-helper build-docker-copier

RUNNER_IMAGE_DEBIAN := debian:11-slim

# Note: this target expects TARGETARCH to be defined
build-docker-helper: $(BUILDDIR)/
$(DOCKER) buildx create --name lavabuilder || true
$(DOCKER) buildx use lavabuilder
$(DOCKER) buildx build \
--build-arg GO_VERSION=$(GO_VERSION) \
--build-arg GIT_VERSION=$(VERSION) \
--build-arg GIT_COMMIT=$(COMMIT) \
--build-arg RUNNER_IMAGE=$(RUNNER_IMAGE_DEBIAN) \
--platform linux/$(TARGETARCH) \
-t lava:$(VERSION) \
--load \
-f Dockerfile .
$(DOCKER) image tag lava:$(VERSION) lava:latest

# Note: this target expects TARGETARCH to be defined
build-docker-copier: $(BUILDDIR)/
$(DOCKER) rm -f lavabinary 2> /dev/null || true
$(DOCKER) create -ti --name lavabinary lava:local-$(TARGETARCH)
$(DOCKER) cp lavabinary:/bin/lavad $(BUILDDIR)/lavad-linux-$(TARGETARCH)
$(DOCKER) rm -f lavabinary

go-mod-cache: go.sum
@echo "--> Download go modules to local cache"
Expand All @@ -108,4 +186,22 @@ go.sum: go.mod
@echo "--> Ensure dependencies have not been modified"
@go mod verify

draw-deps:
@# requires brew install graphviz or apt-get install graphviz
go get github.com/RobotsAndPencils/goviz
@goviz -i ./cmd/lavad -d 2 | dot -Tpng -o dependency-graph.png

test:
@echo "--> Running tests"
@go test -v ./x/...

lint:
@echo "--> Running linter"
golangci-lint run --config .golangci.yml


.PHONY: all build docker-build install lint test \
go-mod-cache go.sum draw-deps \
build-docker-helper build-docker-copier \
build-images build-image-amd64 build-image-arm64 \

0 comments on commit 41ca04b

Please sign in to comment.