forked from coder/coder
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbuild_docker.sh
executable file
·156 lines (135 loc) · 3.64 KB
/
build_docker.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
#!/usr/bin/env bash
# This script builds a Docker image of Coder containing the given binary, for
# the given architecture. Only linux binaries are supported at this time.
#
# Usage: ./build_docker.sh --arch amd64 [--version 1.2.3] [--target image_tag] [--build-base image_tag] [--push] path/to/coder
#
# The --arch parameter is required and accepts a Golang arch specification. It
# will be automatically mapped to a suitable architecture that Docker accepts
# before being passed to `docker buildx build`.
#
# The --build-base parameter is optional and specifies to build the base image
# in Dockerfile.base instead of pulling a copy from the registry. The string
# value is the tag to use for the built image (not pushed). This also consumes
# $CODER_IMAGE_BUILD_BASE_TAG for easily forcing a fresh build in CI.
#
# The default base image can be controlled via $CODER_BASE_IMAGE_TAG.
#
# The image will be built and tagged against the image tag returned by
# ./image_tag.sh unless a --target parameter is supplied.
#
# If no version is specified, defaults to the version from ./version.sh.
#
# If the --push parameter is supplied, the image will be pushed.
#
# Prints the image tag on success.
set -euo pipefail
# shellcheck source=scripts/lib.sh
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
DEFAULT_BASE="${CODER_BASE_IMAGE_TAG:-ghcr.io/coder/coder-base:latest}"
arch=""
image_tag=""
build_base="${CODER_IMAGE_BUILD_BASE_TAG:-}"
version=""
push=0
args="$(getopt -o "" -l arch:,target:,build-base:,version:,push -- "$@")"
eval set -- "$args"
while true; do
case "$1" in
--arch)
arch="$2"
shift 2
;;
--target)
image_tag="$2"
shift 2
;;
--version)
version="$2"
shift 2
;;
--build-base)
build_base="$2"
shift 2
;;
--push)
push=1
shift
;;
--)
shift
break
;;
*)
error "Unrecognized option: $1"
;;
esac
done
if [[ "$arch" == "" ]]; then
error "The --arch parameter is required"
fi
# Check dependencies
dependencies docker
# Remove the "v" prefix.
version="${version#v}"
if [[ "$version" == "" ]]; then
version="$(execrelative ./version.sh)"
fi
if [[ "$image_tag" == "" ]]; then
image_tag="$(execrelative ./image_tag.sh --arch "$arch" --version="$version")"
fi
if [[ "$#" != 1 ]]; then
error "Exactly one argument must be provided to this script, $# were supplied"
fi
if [[ ! -f "$1" ]]; then
error "File '$1' does not exist or is not a regular file"
fi
input_file="$(realpath "$1")"
# Remap the arch from Golang to Docker.
declare -A arch_map=(
[amd64]="linux/amd64"
[arm64]="linux/arm64"
[arm]="linux/arm/v7"
[armv7]="linux/arm/v7"
)
if [[ "${arch_map[$arch]+exists}" != "" ]]; then
arch="${arch_map[$arch]}"
fi
# Make temporary dir where all source files intended to be in the image will be
# hardlinked from.
cdroot
temp_dir="$(TMPDIR="$(dirname "$input_file")" mktemp -d)"
ln "$input_file" "$temp_dir/coder"
ln ./scripts/Dockerfile.base "$temp_dir/"
ln ./scripts/Dockerfile "$temp_dir/"
cd "$temp_dir"
export DOCKER_BUILDKIT=1
base_image="$DEFAULT_BASE"
if [[ "$build_base" != "" ]]; then
log "--- Building base Docker image for $arch ($build_base)"
docker build \
--platform "$arch" \
--tag "$build_base" \
--no-cache \
-f Dockerfile.base \
. 1>&2
base_image="$build_base"
else
docker pull --platform "$arch" "$base_image" 1>&2
fi
log "--- Building Docker image for $arch ($image_tag)"
docker build \
--platform "$arch" \
--build-arg "BASE_IMAGE=$base_image" \
--build-arg "CODER_VERSION=$version" \
--no-cache \
--tag "$image_tag" \
-f Dockerfile \
. 1>&2
cdroot
rm -rf "$temp_dir"
if [[ "$push" == 1 ]]; then
log "--- Pushing Docker image for $arch ($image_tag)"
docker push "$image_tag" 1>&2
fi
echo "$image_tag"