forked from localstack/localstack
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Dockerfile
224 lines (189 loc) · 9.47 KB
/
Dockerfile
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
# java-builder: Stage to build a custom JRE (with jlink)
FROM eclipse-temurin:11@sha256:8cf7bf0f13cc47e56c7461420e1a80585612afcbb0073602f846748d31cb1aba as java-builder
# create a custom, minimized JRE via jlink
RUN jlink --add-modules \
# include required modules
java.base,java.desktop,java.instrument,java.management,java.naming,java.scripting,java.sql,java.xml,jdk.compiler,\
# jdk.unsupported contains sun.misc.Unsafe which is required by certain dependencies
jdk.unsupported,\
# add additional cipher suites
jdk.crypto.cryptoki,\
# add ability to open ZIP/JAR files
jdk.zipfs,\
# OpenSearch needs some jdk modules
jdk.httpserver,jdk.management,\
# MQ Broker requires management agent
jdk.management.agent,\
# required for Spark/Hadoop
java.security.jgss,jdk.security.auth,\
# Elasticsearch 7+ crashes without Thai Segmentation support
jdk.localedata --include-locales en,th \
--compress 2 --strip-debug --no-header-files --no-man-pages --output /usr/lib/jvm/java-11 && \
cp ${JAVA_HOME}/bin/javac /usr/lib/jvm/java-11/bin/javac && \
cp -r ${JAVA_HOME}/include /usr/lib/jvm/java-11/include && \
mv /usr/lib/jvm/java-11/lib/modules /usr/lib/jvm/java-11/lib/modules.bk; \
cp -r ${JAVA_HOME}/lib/* /usr/lib/jvm/java-11/lib/; \
mv /usr/lib/jvm/java-11/lib/modules.bk /usr/lib/jvm/java-11/lib/modules; \
rm -rf /usr/bin/java ${JAVA_HOME} && ln -s /usr/lib/jvm/java-11/bin/java /usr/bin/java
# base: Stage which installs necessary runtime dependencies (OS packages, java,...)
FROM python:3.11.9-slim-bookworm@sha256:dad770592ab3582ab2dabcf0e18a863df9d86bd9d23efcfa614110ce49ac20e4 as base
ARG TARGETARCH
# Install runtime OS package dependencies
RUN --mount=type=cache,target=/var/cache/apt \
apt-get update && \
# Install dependencies to add additional repos
apt-get install -y --no-install-recommends \
# Runtime packages (groff-base is necessary for AWS CLI help)
ca-certificates curl gnupg git make openssl tar pixz zip unzip groff-base iputils-ping nss-passwords procps iproute2 xz-utils libatomic1
# FIXME Node 18 actually shouldn't be necessary in Community, but we assume its presence in lots of tests
# Install nodejs package from the dist release server. Note: we're installing from dist binaries, and not via
# `apt-get`, to avoid installing `python3.9` into the image (which otherwise comes as a dependency of nodejs).
# See https://github.com/nodejs/docker-node/blob/main/18/bullseye/Dockerfile
RUN ARCH= && dpkgArch="$(dpkg --print-architecture)" \
&& case "${dpkgArch##*-}" in \
amd64) ARCH='x64';; \
arm64) ARCH='arm64';; \
*) echo "unsupported architecture"; exit 1 ;; \
esac \
# gpg keys listed at https://github.com/nodejs/node#release-keys
&& set -ex \
&& for key in \
4ED778F539E3634C779C87C6D7062848A1AB005C \
141F07595B7B3FFE74309A937405533BE57C7D57 \
74F12602B6F1C4E913FAA37AD3A89613643B6201 \
DD792F5973C6DE52C432CBDAC77ABFA00DDBF2B7 \
61FC681DFB92A079F1685E77973F295594EC4689 \
8FCCA13FEF1D0C2E91008E09770F7A9A5AE15600 \
C4F0DFFF4E8C1A8236409D08E73BC641CC11F4C8 \
890C08DB8579162FEE0DF9DB8BEAB4DFCF555EF4 \
C82FA3AE1CBEDC6BE46B9360C43CEC45C17AB93C \
108F52B48DB57BB0CC439B2997B01419BD92F80A \
A363A499291CBBC940DD62E41F10027AF002F8B0 \
; do \
gpg --batch --keyserver hkps://keys.openpgp.org --recv-keys "$key" || \
gpg --batch --keyserver keyserver.ubuntu.com --recv-keys "$key" ; \
done \
&& curl -O https://nodejs.org/dist/latest-v18.x/SHASUMS256.txt \
&& LATEST_VERSION_FILENAME=$(cat SHASUMS256.txt | grep -o "node-v.*-linux-$ARCH" | sort | uniq) \
&& rm SHASUMS256.txt \
&& curl -fsSLO --compressed "https://nodejs.org/dist/latest-v18.x/$LATEST_VERSION_FILENAME.tar.xz" \
&& curl -fsSLO --compressed "https://nodejs.org/dist/latest-v18.x/SHASUMS256.txt.asc" \
&& gpg --batch --decrypt --output SHASUMS256.txt SHASUMS256.txt.asc \
&& grep " $LATEST_VERSION_FILENAME.tar.xz\$" SHASUMS256.txt | sha256sum -c - \
&& tar -xJf "$LATEST_VERSION_FILENAME.tar.xz" -C /usr/local --strip-components=1 --no-same-owner \
&& rm "$LATEST_VERSION_FILENAME.tar.xz" SHASUMS256.txt.asc SHASUMS256.txt \
&& ln -s /usr/local/bin/node /usr/local/bin/nodejs \
# smoke tests
&& node --version \
&& npm --version \
&& test ! $(which python3.9)
SHELL [ "/bin/bash", "-c" ]
# Install Java 11
ENV LANG C.UTF-8
RUN { \
echo '#!/bin/sh'; echo 'set -e'; echo; \
echo 'dirname "$(dirname "$(readlink -f "$(which javac || which java)")")"'; \
} > /usr/local/bin/docker-java-home \
&& chmod +x /usr/local/bin/docker-java-home
ENV JAVA_HOME /usr/lib/jvm/java-11
COPY --from=java-builder /usr/lib/jvm/java-11 $JAVA_HOME
RUN ln -s $JAVA_HOME/bin/java /usr/bin/java
ENV PATH "${PATH}:${JAVA_HOME}/bin"
# set workdir
RUN mkdir -p /opt/code/localstack
WORKDIR /opt/code/localstack/
# create localstack user and filesystem hierarchy, perform some permission fixes
RUN chmod 777 . && \
useradd -ms /bin/bash localstack && \
mkdir -p /var/lib/localstack && \
chmod -R 777 /var/lib/localstack && \
mkdir -p /usr/lib/localstack && \
mkdir /tmp/localstack && \
chmod -R 777 /tmp/localstack && \
touch /tmp/localstack/.marker && \
mkdir -p /.npm && \
chmod 755 /root && \
chmod -R 777 /.npm
# install basic (global) tools to final image
RUN --mount=type=cache,target=/root/.cache \
pip install --no-cache-dir --upgrade virtualenv
# install the entrypoint script
ADD bin/docker-entrypoint.sh /usr/local/bin/
# add the shipped hosts file to prevent performance degredation in windows container mode on windows
# (where hosts file is not mounted) See https://github.com/localstack/localstack/issues/5178
ADD bin/hosts /etc/hosts
# expose default environment
# Set edge bind host so localstack can be reached by other containers
# set library path and default LocalStack hostname
ENV LD_LIBRARY_PATH=$JAVA_HOME/lib:$JAVA_HOME/lib/server
ENV USER=localstack
ENV PYTHONUNBUFFERED=1
# Install the latest version of awslocal globally
RUN --mount=type=cache,target=/root/.cache \
pip3 install --upgrade awscli awscli-local requests
# builder: Stage which installs the dependencies of LocalStack Community
FROM base as builder
ARG TARGETARCH
# Install build dependencies to base
RUN --mount=type=cache,target=/var/cache/apt \
apt-get update && \
# Install dependencies to add additional repos
# g++ is a workaround to fix the JPype1 compile error on ARM Linux "gcc: fatal error: cannot execute ‘cc1plus’"
apt-get install -y gcc g++
# upgrade python build tools
RUN --mount=type=cache,target=/root/.cache \
(virtualenv .venv && . .venv/bin/activate && pip3 install --upgrade pip wheel setuptools)
# add files necessary to install runtime dependencies
ADD Makefile pyproject.toml requirements-runtime.txt ./
# add the VERSION file to invalidate docker layers with version bumps
ADD VERSION ./
# add the localstack start scripts (necessary for the installation of the runtime dependencies, i.e. `pip install -e .`)
ADD bin/localstack bin/localstack.bat bin/localstack-supervisor bin/
# install dependencies to run the LocalStack Pro runtime and save which ones were installed
RUN --mount=type=cache,target=/root/.cache \
make install-runtime
RUN . .venv/bin/activate && pip3 freeze -l > requirements-runtime.txt
# final stage: Builds upon base stage and copies resources from builder stages
FROM base
COPY --from=builder /opt/code/localstack/.venv /opt/code/localstack/.venv
# add project files necessary to install all dependencies
ADD Makefile pyproject.toml VERSION ./
# add the localstack start scripts (necessary for the installation of the runtime dependencies, i.e. `pip install -e .`)
ADD bin/localstack bin/localstack.bat bin/localstack-supervisor bin/
# add the code as late as possible
ADD localstack/ localstack/
# Generate the plugin entrypoints
RUN make entrypoints
# Install packages which should be shipped by default
RUN --mount=type=cache,target=/root/.cache \
--mount=type=cache,target=/var/lib/localstack/cache \
source .venv/bin/activate && \
python -m localstack.cli.lpm install \
lambda-runtime \
dynamodb-local && \
chown -R localstack:localstack /usr/lib/localstack && \
chmod -R 777 /usr/lib/localstack
# link the python package installer virtual environments into the localstack venv
RUN echo /var/lib/localstack/lib/python-packages/lib/python3.11/site-packages > localstack-var-python-packages-venv.pth && \
mv localstack-var-python-packages-venv.pth .venv/lib/python*/site-packages/
RUN echo /usr/lib/localstack/python-packages/lib/python3.11/site-packages > localstack-static-python-packages-venv.pth && \
mv localstack-static-python-packages-venv.pth .venv/lib/python*/site-packages/
# expose edge service, external service ports, and debugpy
EXPOSE 4566 4510-4559 5678
HEALTHCHECK --interval=10s --start-period=15s --retries=5 --timeout=5s CMD ./bin/localstack status services --format=json
# default volume directory
VOLUME /var/lib/localstack
# mark the image version
RUN touch /usr/lib/localstack/.community-version
LABEL authors="LocalStack Contributors"
LABEL maintainer="LocalStack Team (info@localstack.cloud)"
LABEL description="LocalStack Docker image"
# Add the build date and git hash at last (changes everytime)
ARG LOCALSTACK_BUILD_DATE
ARG LOCALSTACK_BUILD_GIT_HASH
ARG LOCALSTACK_BUILD_VERSION
ENV LOCALSTACK_BUILD_DATE=${LOCALSTACK_BUILD_DATE}
ENV LOCALSTACK_BUILD_GIT_HASH=${LOCALSTACK_BUILD_GIT_HASH}
ENV LOCALSTACK_BUILD_VERSION=${LOCALSTACK_BUILD_VERSION}
# define command at startup
ENTRYPOINT ["docker-entrypoint.sh"]