-
-
Notifications
You must be signed in to change notification settings - Fork 122
/
Dockerfile.debian
340 lines (282 loc) Β· 15.9 KB
/
Dockerfile.debian
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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
# https://www.debian.org/releases/
# https://hub.docker.com/_/debian
# We use codename (bookworm) instead of version number (12) because we want to select
# the matching Python Docker image, which is named after the codename only.
# bookworm-20241016 corresponds to Debian 12.7
ARG DEBIAN_CODENAME=bookworm
# Debian codenamed images are tagged with date codes rather than minor version numbers.
ARG DEBAIN_DATECODE=20241016
# Find the current version of Python at https://www.python.org/downloads/source/
ARG PYTHON_VERSION=3.12.7
# https://github.com/ahmetb/kubectx/releases
ARG KUBECTX_COMPLETION_VERSION=0.9.5
# https://github.com/jonmosco/kube-ps1/releases
ARG KUBE_PS1_VERSION=0.9.0
# https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-working-with-install-plugin.html#plugin-version-history
ARG SESSION_MANAGER_PLUGIN_VERSION=latest
# Helm plugins:
# https://github.com/databus23/helm-diff/releases
ARG HELM_DIFF_VERSION=3.9.11
# https://github.com/aslafy-z/helm-git/releases
ARG HELM_GIT_VERSION=1.3.0
FROM python:${PYTHON_VERSION}-slim-${DEBIAN_CODENAME} AS python
# Debian comes with minimal Locale support. See https://github.com/docker-library/docs/pull/703/files
# Recommended: LC_ALL=C.UTF-8
ENV LC_ALL=C.UTF-8
# Once again, Debian is weird. Package-installed Python is system-only, and does not
# play well with pip. See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765022#30
# and https://wiki.debian.org/Python#Deviations_from_upstream
#
# So we copy python from the Docker "Official Image" for python, (not to be confused with
# any official python image provided by python upstream). See https://hub.docker.com/_/python/ for details.
#
# Bad is the fact that python, being an interpreted language, installs a lot of shell scripts
# that specifically reference the location of the python interpreter or other things, those
# locations being baked in at install time. So it does not work to install python in `/dist`
# and then later copy `/dist` to `/usr/local`: The installed scripts would have `!#/dist/bin/python`
# baked in and fail. So the official image starts with a basically empty /usr/local/,
# installs python into /usr/local, and then we copy /usr/local over.
#
# Build the Python packages, configured to use /usr/local/bin/python3, and install them under /usr/local
COPY requirements.txt /requirements.txt
RUN python3 -m pip install --upgrade --progress-bar off pip setuptools wheel && \
pip install --progress-bar off -r /requirements.txt --prefix=/usr/local --no-build-isolation
# Remove Python cache files
RUN find / -xdev -name __pycache__ -exec rm -rf {} \; -prune
#
# Geodesic base image
#
FROM debian:${DEBIAN_CODENAME}-${DEBAIN_DATECODE}-slim
ARG VERSION
ENV GEODESIC_VERSION=$VERSION
ENV GEODESIC_OS=debian
# TARGETARCH and TARGETOS are defined by buildkit, but not available with other builders
ARG TARGETARCH
ARG TARGETOS
RUN [ -n "$TARGETARCH" ] && [ -n "$TARGETOS" ] || (echo "Geodesic must be built with buildkit."; echo "See: https://docs.docker.com/build/buildkit/"; false)
RUN [ "$TARGETARCH" = "amd64" ] || [ "$TARGETARCH" = "arm64" ] || (echo "Unsupported TARGETARCH: \"$TARGETARCH\"" && false)
RUN [ "$TARGETOS" = "linux" ] || (echo "Unsupported TARGETOS: \"$TARGETOS\"" && false)
# Set a default terminal to "dumb" (headless) to make `tput` happy when running scripts.
# When we launch Geodesic for interactive use, we forward the host value of `TERM`
ENV TERM=dumb
# Debian comes with minimal Locale support. See https://github.com/docker-library/docs/pull/703/files
# Recommended: LC_ALL=C.UTF-8
ENV LC_ALL=C.UTF-8
# Set XDG environment variables per https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html
# This is not a "multi-user" system, so we'll use special directories under
# - /etc as the global configuration dir instead of default $HOME/.config
# - /usr/share as the global data dir instead of default $HOME/.local/share
# - /tmp as the global cache dir instead of default $HOME/.cache
# This allows daemon/server users like Atlantis to use the same
# configuration as the root user, which is usually what we want.
# If the daemon wants isolation, it can unset the variables
# or set them to something else.
# We leave the runtime dir unset/default since that is specifically
# required to be owned by the current user.
# Read more: <https://wiki.archlinux.org/index.php/XDG_Base_Directory>
ENV XDG_DATA_HOME=/usr/share/xdg_data_home
ENV XDG_CONFIG_HOME=/etc/xdg_config_home
ENV XDG_CACHE_HOME=/var/cache/xdg_cache_home
RUN for dir in $XDG_DATA_HOME $XDG_CONFIG_HOME $XDG_CACHE_HOME; do \
mkdir -p $dir; chmod 777 $dir; done
ENV BANNER "geodesic"
ENV MOTD_URL=http://geodesic.sh/motd
ENV HOME=/conf
# Install all packages as root
USER root
# Keep dpkg quiet about running non-interactively
RUN echo 'debconf debconf/frontend select Noninteractive' | debconf-set-selections
# Make Cloud Posse repo the preference for `kubectl` because
# the Google Cloud SDK repo uses a different versioning scheme
COPY os/debian/rootfs/etc/apt/preferences.d/kubectl-preferences /etc/apt/preferences.d/kubectl-preferences
COPY packages.txt packages-amd64-only.txt os/debian/packages-debian.txt /etc/apt/
## Here is where we would copy in the repo checksum in an attempt to ensure updates bust the Docker build cache
# Add CloudPosse package repo
RUN apt-get update && apt-get install -y apt-utils curl
RUN curl -1sLf 'https://dl.cloudsmith.io/public/cloudposse/packages/cfg/setup/bash.deb.sh' | bash
# Add OpenTofu package repo
RUN curl -fsSL https://get.opentofu.org/opentofu.gpg > /etc/apt/keyrings/opentofu.gpg && \
curl -fsSL https://packages.opentofu.org/opentofu/tofu/gpgkey | \
gpg --no-tty --batch --dearmor -o /etc/apt/keyrings/opentofu-repo.gpg >/dev/null && \
chmod a+r /etc/apt/keyrings/opentofu.gpg /etc/apt/keyrings/opentofu-repo.gpg && \
printf "%s [signed-by=/etc/apt/keyrings/opentofu.gpg,/etc/apt/keyrings/opentofu-repo.gpg] https://packages.opentofu.org/opentofu/tofu/any/ any main\n" \
"deb" "deb-src" > /etc/apt/sources.list.d/opentofu.list && \
chmod a+r /etc/apt/sources.list.d/opentofu.list
# Install Google package repo
RUN echo "deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main" \
> /etc/apt/sources.list.d/google-cloud-sdk.list && \
curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | gpg --dearmor -o /usr/share/keyrings/cloud.google.gpg
# Install packages (but only explicitly listed ones)
RUN apt-get update && apt-get install -y --no-install-recommends \
$(grep -h -v '^#' /etc/apt/packages.txt /etc/apt/packages-debian.txt | sed -E 's/@(cloudposse|community|testing)//g' ) && \
mkdir -p /etc/bash_completion.d/ /etc/profile.d/ /conf && \
touch /conf/.gitconfig
# Install `tofu` as an alternative to `terraform`, if it is available.
# Set priority to 5, which is lower than any other Cloud Posse Terraform package,
# so that it is available, if Terraform is not installed, but does not interfere with Terraform installations.
RUN command -v tofu >/dev/null && update-alternatives --install /usr/bin/terraform terraform $(command -v tofu) 5
# Here is where we would confirm that the package repo checksum is what we expect (not mismatched due to Docker layer cache)
# Using the en_US.UTF-8 local breaks our login setup because it changes the sort order,
# and therefore the order of execution, of our profile files. We use locale C.UTF-8 instead,
# which is widely supported (more widely than en_US.UTF-8). However, if
# we had a compelling reason to need en_US.UTF-8, we could install the
# "locales" package and run the following command:
# RUN localedef -i en_US -c -f UTF-8 -A /usr/share/locale/locale.alias en_US.UTF-8
# Not sure why we were disabling IPv6, but we should not do that anymore, as IPv6 is stable and useful
# RUN echo "net.ipv6.conf.all.disable_ipv6=0" > /etc/sysctl.d/00-ipv6.conf
# Disable vim from reading a swapfile (incompatible with goofys)
RUN echo 'set noswapfile' >> /etc/vim/vimrc
WORKDIR /tmp
# Copy python dependencies
COPY --from=python /usr/local/ /usr/local/
# Explicitly set KUBECONFIG to enable kube_ps1 prompt
ENV KUBECONFIG=/conf/.kube/config
# Install an empty kubeconfig to suppress some warnings
COPY rootfs/conf/.kube/config /conf/.kube/config
# Set mode on kubeconfig to suppress some warnings while installing tools
RUN chmod 600 $KUBECONFIG
#
# Install kubectl
#
# Set KUBERNETES_VERSION and KOPS_BASE_IMAGE in /conf/kops/kops.envrc
#
RUN kubectl completion bash > /etc/bash_completion.d/kubectl.sh
# https://github.com/ahmetb/kubectx/releases
ARG KUBECTX_COMPLETION_VERSION
ADD https://raw.githubusercontent.com/ahmetb/kubectx/v${KUBECTX_COMPLETION_VERSION}/completion/kubens.bash /etc/bash_completion.d/kubens.sh
ADD https://raw.githubusercontent.com/ahmetb/kubectx/v${KUBECTX_COMPLETION_VERSION}/completion/kubectx.bash /etc/bash_completion.d/kubectx.sh
#
# Install fancy Kube PS1 Prompt
# https://github.com/jonmosco/kube-ps1/releases
ARG KUBE_PS1_VERSION
ADD https://raw.githubusercontent.com/jonmosco/kube-ps1/v${KUBE_PS1_VERSION}/kube-ps1.sh /etc/profile.d/prompt:kube-ps1.sh
RUN chmod 755 /etc/bash_completion.d/kubens.sh /etc/bash_completion.d/kubectx.sh /etc/profile.d/prompt:kube-ps1.sh
#
# Install helm
#
############# End of Helm 2 support ################################
# We no longer install helm2. If you want to install it yourself, copy and uncomment the following:
#
# # helm version 2 config
# ENV HELM_HOME /var/lib/helm
# ENV HELM_VALUES_PATH=${SECRETS_PATH}/helm/values
#
# RUN helm2 completion bash > /etc/bash_completion.d/helm2.sh \
# && mkdir -p ${HELM_HOME} \
# && helm2 init --client-only \
# && mkdir -p ${HELM_HOME}/plugins
#
# # Enable Atlantis to use helm 2
# RUN chmod -R a+rwX ${HELM_HOME}
#
# ARG HELM_HELM_2TO3_VERSION=0.10.0
# RUN helm3 plugin install https://github.com/helm/helm-2to3 --version ${HELM_HELM_2TO3_VERSION}
#
############# End of Helm 2 support ################################
#
# Install minimal helm plugins
ARG HELM_DIFF_VERSION
ARG HELM_GIT_VERSION
RUN helm3 plugin install https://github.com/databus23/helm-diff.git --version v${HELM_DIFF_VERSION} \
&& helm3 plugin install https://github.com/aslafy-z/helm-git.git --version ${HELM_GIT_VERSION} \
&& rm -rf $XDG_CACHE_HOME/helm
# helm version 3 uses XDG variables set above.
# XDG directory permissions updated at end of installs.
# See https://helm.sh/docs/faq/#xdg-base-directory-support
#
# Configure host AWS configuration to be available from inside Docker image
#
# AWS_DATA_PATH is a PATH-like variable for configuring the AWS botocore library to
# load additional modules. Do not set it. ENV AWS_DATA_PATH=/localhost/.aws
ARG GEODESIC_AWS_HOME=/localhost/.aws
ENV AWS_CONFIG_FILE=${GEODESIC_AWS_HOME}/config
ENV AWS_SHARED_CREDENTIALS_FILE=${GEODESIC_AWS_HOME}/credentials
# Region abbreviation types are "fixed" (always 3 chars), "short" (4-5 chars), or "long" (the full AWS string)
# See https://github.com/cloudposse/terraform-aws-utils#introduction
ENV AWS_REGION_ABBREVIATION_TYPE=short
# Shell customization
# options for `less`. `R` allows ANSI color codes to be displayed while stripping out
# other control codes that can cause `less` to mess up the screen formatting
ENV LESS=R
# MANOPT=--no-hyphenation disables hyphenation for man pages, which is generally preferable
# for the man pages in Geodesic to preserve the ability to copy and paste code.
ENV MANOPT=--no-hyphenation
# Support for using an SSH key file on the host. No longer favored now that
# Docker supports forwarding SSH_AUTH_SOCK, but retained for backward compatibility.
# See rootfs/etc/profile.d/ssh-agent.sh
ENV SSH_AGENT_CONFIG=/var/tmp/.ssh-agent
# Install "root" filesystem
# Debian, starting with v12 (bookworm), has symbolic links for /bin, /sbin, and /lib
# so we cannot have those directories under rootfs and copy the whole directory.
COPY rootfs/ /
COPY os/debian/rootfs/ /
# For certain pagkage we like to have but are not available on arm64,
# install them on amd64, and link to a stub script on arm64.
RUN if [ "$TARGETARCH" = "amd64" ]; then \
apt-get update && apt-get install -y \
$(grep -h -v '^#' /etc/apt/packages-amd64-only.txt | sed -E 's/@(cloudposse|community|testing)//g' ); \
else \
for pkg in $(grep -h -v '^#' /etc/apt/packages-amd64-only.txt | sed -E 's/@(cloudposse|community|testing)//g' ); do \
ln -s /usr/local/bin/no-arm64-support /usr/local/bin/$pkg; \
done; \
fi
# Move AWS CLI v1 aside (if installed) and install AWS CLI v2 as default, leaving both available as alternatives.
# We do this at the end because we need cache busting from above to get us the latest AWS CLI v2
RUN if [[ -x /usr/local/bin/aws ]]; then mv /usr/local/bin/aws /usr/local/bin/aws1 && \
mv /usr/local/bin/aws_completer /usr/local/bin/aws1_completer && \
update-alternatives --install /usr/local/bin/aws aws /usr/local/bin/aws1 1 \
--slave /usr/local/bin/aws_completer aws_completer /usr/local/bin/aws1_completer; \
fi
# Install AWS CLI 2
# Get AWS CLI V2 version from https://github.com/aws/aws-cli/blob/v2/CHANGELOG.rst if you want
# but it is updated several times a week, so we choose to just get the latest.
# It is available in a Debain package `awscli`, but that can be very out of date.
# ARG AWS_CLI_VERSION=2.15.48
RUN AWSTMPDIR=$(mktemp -d -t aws-inst-XXXXXXXXXX) && \
if [ "$TARGETARCH" = "amd64" ]; then \
AWS_ARCH=x86_64; else AWS_ARCH=aarch64; fi && \
curl -sSL "https://awscli.amazonaws.com/awscli-exe-linux-${AWS_ARCH}${AWS_CLI_VERSION:+-${AWS_CLI_VERSION}}.zip" -o "$AWSTMPDIR/awscliv2.zip" && \
savedir="$PWD" && cd $AWSTMPDIR && \
unzip -qq awscliv2.zip && \
./aws/install -i /usr/share/aws/v2 -b /usr/share/aws/v2/bin && \
update-alternatives --install /usr/local/bin/aws aws /usr/share/aws/v2/bin/aws 2 \
--slave /usr/local/bin/aws_completer aws_completer /usr/share/aws/v2/bin/aws_completer && \
update-alternatives --set aws /usr/share/aws/v2/bin/aws && \
ln -s /usr/share/aws/v2/bin/aws /usr/local/bin/aws2 && \
ln -s /usr/share/aws/v2/bin/aws_completer /usr/local/bin/aws2_completer && \
cd "$savedir" && rm -rf $AWSTMPDIR
# We recommend AWS_PAGER="less -FRX" but you can override it in your Dockerfile
# or in your Geodesic preferences (see `man customization`).
# FRX acts like it does not invoke the pager unless the output would be
# more than can fit on one scree, while preserving text color/bold.
# FRX is actually the AWS default, except we overrode the default above by setting ENV LESS.
# options to `less`:
# F = Quit if output fits on one screen, so short output remains visible after the command finishes
# R = Output "raw" control characters, so that text treatment like "bold" text is retained as "bold" text rather than quoted escapes
# X = Disable termcap init/de-init sequences, keeps the pager from clearing the screen when it finishes
ENV AWS_PAGER="less -FRX"
# Install AWS Session Manager Plugin
ARG SESSION_MANAGER_PLUGIN_VERSION
RUN if [ "$TARGETARCH" = "amd64" ]; then \
AWS_ARCH=64bit; else AWS_ARCH="$TARGETARCH"; fi && \
curl -sSL "https://s3.amazonaws.com/session-manager-downloads/plugin/${SESSION_MANAGER_PLUGIN_VERSION}/ubuntu_${AWS_ARCH}/session-manager-plugin.deb" \
-o "/tmp/session-manager-plugin.deb" && \
sudo dpkg -i /tmp/session-manager-plugin.deb && \
rm -f /tmp/session-manager-plugin.deb
# Install documentation
COPY docs/ /usr/share/docs/
# Build man pages
# `pandoc` is huge, so we only install it temporarily
RUN apt-get update && apt-get install -y --no-install-recommends pandoc && \
/usr/local/bin/docs update; \
apt-get remove -y pandoc && apt-get autoremove -y
# Make sure that "user specific" directories we are sharing
# are in fact available to all users
RUN for dir in $XDG_DATA_HOME $XDG_CONFIG_HOME $XDG_CACHE_HOME; do \
chmod -R a+rwX $dir; done
WORKDIR /conf
ENTRYPOINT ["/bin/bash"]
CMD ["-c", "boot"]
ARG DEV_VERSION
ENV GEODESIC_DEV_VERSION=$DEV_VERSION
ENV GEODESIC_VERSION="${GEODESIC_VERSION}${GEODESIC_DEV_VERSION:+ (${GEODESIC_DEV_VERSION})}"