forked from devilbox/makefiles
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Makefile.docker
268 lines (241 loc) · 9.87 KB
/
Makefile.docker
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
ifneq (,)
.error This Makefile requires GNU Make.
endif
ifndef VERBOSE
MAKEFLAGS += --no-print-directory
endif
# -------------------------------------------------------------------------------------------------
# Docker required Variables
# -------------------------------------------------------------------------------------------------
NAME =
VERSION =
IMAGE =
# -------------------------------------------------------------------------------------------------
# Docker optional Variables
# -------------------------------------------------------------------------------------------------
NO_CACHE =
ARGS =
DOCKER_TAG = latest
DIR = .
FILE = Dockerfile
# Space separated Docker images (in FROM block) to not to pull
DOCKER_PULL_BASE_IMAGES_IGNORE =
# Auto-detect current platform and use it as default to build for
_PLATFORM = $(shell uname -m)
ifeq ($(strip $(_PLATFORM)),x86_64)
ARCH = linux/amd64
else
ifeq ($(strip $(_PLATFORM)),arm64)
ARCH = linux/arm64
endif
endif
# -------------------------------------------------------------------------------------------------
# Targets
# -------------------------------------------------------------------------------------------------
.PHONY: docker-help
docker-help:
@echo "make docker-arch-build # Build Docker image"
@echo " NAME= # (req) Set label name"
@echo " VERSION= # (req) Set label version"
@echo " IMAGE= # (req) Set Docker image name"
@echo " DOCKER_TAG= # (opt) Set Docker image tag"
@echo " ARCH= # (opt) Specify Docker platform to build against"
@echo " DIR= # (opt) Specify directory of Docker file"
@echo " FILE= # (opt) Specify filename of Docker file"
@echo " ARGS= # (opt) Add additional docker build arguments"
# -------------------------------------------------------------------------------------------------
# Docker Architecture targets
# -------------------------------------------------------------------------------------------------
.PHONY: docker-arch-build
docker-arch-build:
@if [ "$(NAME)" = "" ]; then \
echo "This make target requires the NAME variable to be set."; \
echo "make docker-arch-build NAME="; \
echo "Exiting."; \
false; \
fi
@if [ "$(VERSION)" = "" ]; then \
echo "This make target requires the VERSION variable to be set."; \
echo "make docker-arch-build VERSION="; \
echo "Exiting."; \
false; \
fi
@if [ "$(IMAGE)" = "" ]; then \
echo "This make target requires the IMAGE variable to be set."; \
echo "make docker-arch-build IMAGE="; \
echo "Exiting."; \
false; \
fi
@echo "################################################################################"
@echo "# Building $(IMAGE):$(DOCKER_TAG) (platform: $(ARCH))"
@echo "################################################################################"
docker build \
$(NO_CACHE) \
$(ARGS) \
$$( if [ -n "$(DOCKER_TARGET)" ]; then echo "--target $(DOCKER_TARGET)"; fi; ) \
--network host \
--platform $(ARCH) \
--label "org.opencontainers.image.created"="$$(date --rfc-3339=s)" \
--label "org.opencontainers.image.revision"="$$(git rev-parse HEAD)" \
--label "org.opencontainers.image.name"="$(NAME)" \
--label "org.opencontainers.image.version"="$(VERSION)" \
--tag $(IMAGE):$(DOCKER_TAG) \
--file $(DIR)/$(FILE) $(DIR)
.PHONY: docker-arch-rebuild
docker-arch-rebuild: NO_CACHE=--no-cache
docker-arch-rebuild: docker-pull-base-image
docker-arch-rebuild: docker-arch-build
.PHONY: docker-arch-push
docker-arch-push:
@if [ "$(IMAGE)" = "" ]; then \
echo "This make target requires the IMAGE variable to be set."; \
echo "make docker-arch-push IMAGE="; \
echo "Exiting."; \
false; \
fi
@echo "################################################################################"
@echo "# Pushing Docker Image $(IMAGE):$(DOCKER_TAG)-manifest-$(subst /,-,$(ARCH))"
@echo "################################################################################"
docker tag $(IMAGE):$(DOCKER_TAG) $(IMAGE):$(DOCKER_TAG)-manifest-$(subst /,-,$(ARCH))
docker push $(IMAGE):$(DOCKER_TAG)-manifest-$(subst /,-,$(ARCH))
# -------------------------------------------------------------------------------------------------
# Docker Manifest Targets
# -------------------------------------------------------------------------------------------------
.PHONY: docker-manifest-create
docker-manifest-create:
@if [ "$(IMAGE)" = "" ]; then \
echo "This make target requires the IMAGE variable to be set."; \
echo "make docker-manifest-create IMAGE="; \
echo "Exiting."; \
false; \
fi
@if [ "$(ARCHES)" = "" ]; then \
echo "This make target requires the ARCHES variable to be set."; \
echo "make docker-manifest-create ARCHES="; \
echo "Exiting."; \
false; \
fi
@echo "################################################################################"
@echo "# Creating Manifest $(IMAGE):$(DOCKER_TAG) ($(ARCHES))"
@echo "################################################################################"
@echo "docker manifest create \
$(IMAGE):$(DOCKER_TAG) \
$$( echo $(ARCHES) | sed 's/,/ /g' | sed 's|/|-|g' | xargs -n1 sh -c 'printf -- " --amend $(IMAGE):$(DOCKER_TAG)-manifest-$${1}"' -- )" \
| sed 's/\s\s*/ /g' \
| sed 's/--/\\\n --/g'
@echo "docker manifest create \
$(IMAGE):$(DOCKER_TAG) \
$$( echo $(ARCHES) | sed 's/,/ /g' | sed 's|/|-|g' | xargs -n1 sh -c 'printf -- " --amend $(IMAGE):$(DOCKER_TAG)-manifest-$${1}"' -- )" \
| bash
.PHONY: docker-manifest-push
docker-manifest-push:
@if [ "$(IMAGE)" = "" ]; then \
echo "This make target requires the IMAGE variable to be set."; \
echo "make docker-manifest-push IMAGE="; \
echo "Exiting."; \
false; \
fi
@echo "################################################################################"
@echo "# Pushing Manifest $(IMAGE):$(DOCKER_TAG)"
@echo "################################################################################"
docker manifest push $(IMAGE):$(DOCKER_TAG)
# -------------------------------------------------------------------------------------------------
# Export/Import targets
# -------------------------------------------------------------------------------------------------
.PHONY: docker-save
docker-save:
@if [ "$(OUTFILE)" = "" ]; then \
echo "This make target requires the OUTFILE variable to be set."; \
echo "make docker-save OUTFILE="; \
echo "Exiting."; \
false; \
fi
@if [ "$(IMAGE)" = "" ]; then \
echo "This make target requires the IMAGE variable to be set."; \
echo "make docker-arch-build IMAGE="; \
echo "Exiting."; \
false; \
fi
@echo "################################################################################"
@echo "# Saving $(IMAGE):$(DOCKER_TAG) to: $(OUTFILE)"
@echo "################################################################################"
docker save $(IMAGE):$(DOCKER_TAG) | gzip > "$(OUTFILE)"
.PHONY: docker-load
docker-load:
@if [ "$(INFILE)" = "" ]; then \
echo "This make target requires the INFILE variable to be set."; \
echo "make docker-load INFILE="; \
echo "Exiting."; \
false; \
fi
@echo "################################################################################"
@echo "# Loading $(INFILE)"
@echo "################################################################################"
docker load -i "$(INFILE)"
# -------------------------------------------------------------------------------------------------
# Helper Targets
# -------------------------------------------------------------------------------------------------
.PHONY: docker-pull-base-image
_DOCKER_PULL_BASE_IMAGES_FOUND = $(shell \
if [ ! -f "$(DIR)/$(FILE)" ]; then \
echo "Error, Dockerfile not found in: $(DIR)/$(FILE)" >&2; \
exit 1; \
fi; \
grep FROM $(DIR)/$(FILE) | sed 's/^FROM\s*//g' | sed 's/\s.*$$//g' | sort -u \
)
DOCKER_PULL_VARIABLES = "VERSION=$(VERSION)"
docker-pull-base-image:
@echo "################################################################################"
@echo "# Pulling Base Image (platform: $(ARCH))"
@echo "################################################################################"
@echo "Docker File: $(DIR)/$(FILE)"
@echo "Var Exports: $(DOCKER_PULL_VARIABLES)"
@if [ -n $(DOCKER_PULL_VARIABLES) ];then for e in $(DOCKER_PULL_VARIABLES);do export "$${e}";done;fi; echo "Images Found: $(_DOCKER_PULL_BASE_IMAGES_FOUND)"
@if [ -n $(DOCKER_PULL_VARIABLES) ];then for e in $(DOCKER_PULL_VARIABLES);do export "$${e}";done;fi; echo "Images Ignore: $(DOCKER_PULL_BASE_IMAGES_IGNORE)"
@echo
@if [ "$(.SHELLSTATUS)" != "0" ]; then \
exit 1; \
fi
# These variables will be exported to the shell
@if [ -n $(DOCKER_PULL_VARIABLES) ];then for e in $(DOCKER_PULL_VARIABLES);do export "$${e}";done;fi; \
echo $(_DOCKER_PULL_BASE_IMAGES_FOUND) | sed 's/\s/\n/g' | while read -r line; do \
if echo "$(DOCKER_PULL_BASE_IMAGES_IGNORE)" | grep -F "$${line}" >/dev/null; then \
continue; \
fi; \
echo "docker pull --platform $(ARCH) $${line}"; \
SUCC=0; \
for count in $$(seq 10); do \
if docker pull --platform $(ARCH) $${line}; then \
SUCC=1; \
break; \
fi; \
done; \
if [ "$${SUCC}" != "1" ]; then \
echo "Failed."; \
exit 1; \
fi; \
done
.PHONY: docker-enter
docker-enter:
@if [ "$(IMAGE)" = "" ]; then \
echo "This make target requires the IMAGE variable to be set."; \
echo "make docker-enter IMAGE="; \
echo "Exiting."; \
false; \
fi
docker run --rm --platform=$(ARCH) -it --entrypoint=bash $(ARG) $(IMAGE)
.PHONY: docker-login
docker-login:
ifeq ($(strip $(USERNAME)),)
@$(info This make target requires the USERNAME variable to be set.)
@$(info make docker-login USERNAME= PASSWORD=)
@$(info )
@$(error Exiting)
endif
ifeq ($(strip $(PASSWORD)),)
@$(info This make target requires the PASSWORD variable to be set.)
@$(info make docker-login USERNAME= PASSWORD=)
@$(info )
@$(error Exiting)
endif
@yes | docker login --username $(USERNAME) --password $(PASSWORD)