Skip to content

Commit 7a79263

Browse files
YusukeShimizucdecker
authored andcommitted
testserver: slim testserver image
Introduce multi-stage build to separate build from runtime. Reduce final image size Keep minimal Python env for test usage. Also enable multi-architecture support to ensure proper downloads based on the build environment. This fixes issues on ARM64 where the x86_64 binary was previously being downloaded.
1 parent 659bddc commit 7a79263

File tree

1 file changed

+177
-74
lines changed

1 file changed

+177
-74
lines changed

docker/gl-testserver/Dockerfile

Lines changed: 177 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,84 +1,187 @@
1-
FROM ubuntu:22.04 AS python-builder
2-
1+
############################
2+
# Stage 1: builder
3+
############################
4+
FROM rust:slim-bullseye AS builder
5+
6+
#---------------------------------------------------------------------
7+
# Build-time arguments & environment variables
8+
#---------------------------------------------------------------------
39
ARG BITCOIN_VERSION=24.0
410
ARG GID=0
511
ARG UID=0
612
ARG DOCKER_USER=dev
713
ARG REPO_PATH=/repo
14+
ARG TARGETPLATFORM
15+
ARG TARGETARCH
816

9-
ENV RUST_VERSION=1.74
10-
ENV PATH=$CARGO_HOME/bin:$PATH
1117
ENV PROTOC_VERSION=3.19.3
1218
ENV CFSSL_VERSION=1.6.5
13-
ENV GL_TESTING_IGNORE_HASH=False
14-
ENV PATH=$PATH:/home/$DOCKER_USER/.local/bin/:/opt/bitcoin/bin:/home/$DOCKER_USER/.cargo/bin
15-
ENV REPO=$REPO_PATH
16-
17-
# Force this target dir, so the scripts can find all the binaries.
18-
#ENV CARGO_TARGET_DIR=${REPO}/target
19-
ENV CARGO_TARGET_DIR=/tmp/target/
20-
21-
RUN apt update && apt install -qqy \
22-
curl \
23-
python3 \
24-
python3-pip \
25-
python3-venv \
19+
ENV PATH=/home/${DOCKER_USER}/.local/bin:/opt/bitcoin/bin:/usr/local/bin:$PATH
20+
ENV CARGO_TARGET_DIR=/tmp/target
21+
ENV REPO=${REPO_PATH}
22+
23+
#---------------------------------------------------------------------
24+
# Base packages required for building
25+
#---------------------------------------------------------------------
26+
RUN apt-get update && \
27+
DEBIAN_FRONTEND=noninteractive \
28+
apt-get install -y --no-install-recommends \
29+
python3 python3-venv python3-pip \
30+
python3-dev \
2631
libpq-dev \
27-
unzip \
28-
sudo \
29-
git \
3032
build-essential \
31-
wget
32-
33-
RUN groupadd -g $GID -o $DOCKER_USER &&\
34-
useradd -m -u $UID -g $GID -G sudo -o -s /bin/bash $DOCKER_USER && \
35-
echo '%sudo ALL=(ALL:ALL) ALL' >> /etc/sudoers
36-
37-
RUN wget -q https://github.com/cloudflare/cfssl/releases/download/v${CFSSL_VERSION}/cfssl_${CFSSL_VERSION}_linux_amd64 -O /usr/bin/cfssl && \
38-
chmod a+x /usr/bin/cfssl
39-
RUN wget -q https://github.com/cloudflare/cfssl/releases/download/v${CFSSL_VERSION}/cfssljson_${CFSSL_VERSION}_linux_amd64 -O /usr/bin/cfssljson && \
40-
chmod a+x /usr/bin/cfssljson
41-
42-
RUN mkdir /tmp/protoc && \
43-
cd /tmp/protoc && \
44-
wget --quiet \
45-
-O protoc.zip \
46-
https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-x86_64.zip && \
47-
unzip protoc.zip && \
48-
sudo mv /tmp/protoc/bin/protoc /usr/local/bin && \
49-
chmod a+x /usr/local/bin/protoc && \
50-
rm -rf /tmp/protoc
51-
52-
RUN cd /tmp/ && \
53-
wget "https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_VERSION}/bitcoin-${BITCOIN_VERSION}-x86_64-linux-gnu.tar.gz" -O bitcoin.tar.gz && \
54-
tar -xvzf bitcoin.tar.gz && \
55-
mv /tmp/bitcoin-$BITCOIN_VERSION/ /opt/bitcoin && \
56-
rm -rf bitcoin.tar.gz /tmp/bitcoin-$BITCOIN_VERSION
57-
58-
RUN mkdir -p ${REPO_PATH} && \
59-
chown $DOCKER_USER:users ${REPO_PATH}
60-
61-
ADD ../../libs/ ${REPO_PATH}/libs
62-
ADD ../../pyproject.toml ${REPO_PATH}/
63-
64-
ADD ../../ ${REPO_PATH}/
65-
RUN chown $DOCKER_USER:users -R ${REPO_PATH}
66-
RUN chown $DOCKER_USER:users -R /home/$DOCKER_USER
67-
USER $DOCKER_USER
68-
69-
RUN curl \
70-
--proto '=https' \
71-
--tlsv1.2 \
72-
-sSf https://sh.rustup.rs | sh \
73-
-s -- -y --default-toolchain ${RUST_VERSION}
74-
RUN rustup default stable
75-
76-
WORKDIR ${REPO_PATH}/libs/gl-testserver/
77-
78-
RUN cargo build --bin gl-plugin
79-
RUN cargo build --bin gl-signerproxy
80-
81-
RUN curl -LsSf https://astral.sh/uv/install.sh | sh
82-
83-
RUN uv lock && uv sync --locked -v
84-
CMD uv run gltestserver run --metadata ${REPO}/ --directory ${REPO}/.gltestserver
33+
git \
34+
curl wget unzip sudo ca-certificates \
35+
&& rm -rf /var/lib/apt/lists/*
36+
37+
#---------------------------------------------------------------------
38+
# Additional Rust components
39+
#---------------------------------------------------------------------
40+
RUN rustup component add rustfmt
41+
42+
#---------------------------------------------------------------------
43+
# Create dev user with password-less sudo
44+
#---------------------------------------------------------------------
45+
RUN groupadd -g ${GID} -o ${DOCKER_USER} && \
46+
useradd -m -u ${UID} -g ${GID} -G sudo -o -s /bin/bash ${DOCKER_USER} && \
47+
echo '%sudo ALL=(ALL:ALL) NOPASSWD:ALL' >> /etc/sudoers
48+
49+
USER ${DOCKER_USER}
50+
WORKDIR /home/${DOCKER_USER}
51+
52+
#---------------------------------------------------------------------
53+
# Directories for build tools and staged artifacts
54+
#---------------------------------------------------------------------
55+
RUN sudo mkdir -p /opt/build-tools /opt/bitcoin /opt/stage && \
56+
sudo chown ${DOCKER_USER}:${DOCKER_USER} /opt/build-tools /opt/bitcoin /opt/stage
57+
58+
#---------------------------------------------------------------------
59+
# cfssl & cfssljson
60+
#---------------------------------------------------------------------
61+
RUN wget -q https://github.com/cloudflare/cfssl/releases/download/v${CFSSL_VERSION}/cfssl_${CFSSL_VERSION}_linux_${TARGETARCH} -O /opt/build-tools/cfssl && \
62+
wget -q https://github.com/cloudflare/cfssl/releases/download/v${CFSSL_VERSION}/cfssljson_${CFSSL_VERSION}_linux_${TARGETARCH} -O /opt/build-tools/cfssljson && \
63+
chmod +x /opt/build-tools/cfssl /opt/build-tools/cfssljson
64+
65+
#---------------------------------------------------------------------
66+
# protoc
67+
#---------------------------------------------------------------------
68+
RUN PLATFORM=$(case "${TARGETPLATFORM}" in \
69+
linux/amd64) echo "x86_64";; \
70+
linux/arm64) echo "aarch_64";; \
71+
esac) && \
72+
wget -q https://github.com/protocolbuffers/protobuf/releases/download/v${PROTOC_VERSION}/protoc-${PROTOC_VERSION}-linux-${PLATFORM}.zip -O /tmp/protoc.zip && \
73+
unzip -q /tmp/protoc.zip -d /tmp/protoc && \
74+
mv /tmp/protoc/bin/protoc /opt/build-tools/protoc && \
75+
chmod +x /opt/build-tools/protoc && \
76+
rm -rf /tmp/protoc /tmp/protoc.zip
77+
78+
#---------------------------------------------------------------------
79+
# bitcoind (static binaries)
80+
#---------------------------------------------------------------------
81+
RUN ARCH=$(case "${TARGETPLATFORM}" in \
82+
linux/amd64) echo "x86_64";; \
83+
linux/arm64) echo "aarch64";; \
84+
esac) && \
85+
wget -q https://bitcoincore.org/bin/bitcoin-core-${BITCOIN_VERSION}/bitcoin-${BITCOIN_VERSION}-${ARCH}-linux-gnu.tar.gz -O /tmp/bitcoin.tgz && \
86+
tar -xf /tmp/bitcoin.tgz -C /tmp && \
87+
mv /tmp/bitcoin-${BITCOIN_VERSION}/* /opt/bitcoin && \
88+
rm -rf /tmp/bitcoin.tgz /tmp/bitcoin-${BITCOIN_VERSION}
89+
90+
ENV PATH=/opt/build-tools:$PATH
91+
92+
#---------------------------------------------------------------------
93+
# Copy source code
94+
#---------------------------------------------------------------------
95+
WORKDIR ${REPO_PATH}
96+
COPY --chown=${DOCKER_USER}:users ../../Cargo.toml ${REPO_PATH}/
97+
COPY --chown=${DOCKER_USER}:users ../../pyproject.toml ../../uv.lock ${REPO_PATH}/
98+
COPY --chown=${DOCKER_USER}:users ../../libs ${REPO_PATH}/libs
99+
COPY --chown=${DOCKER_USER}:users ../../examples ${REPO_PATH}/examples
100+
101+
#---------------------------------------------------------------------
102+
# Build Rust binaries (release, stripped)
103+
#---------------------------------------------------------------------
104+
WORKDIR ${REPO_PATH}
105+
RUN cargo build --release \
106+
--manifest-path libs/gl-plugin/Cargo.toml --bin gl-plugin && \
107+
cargo build --release \
108+
--manifest-path libs/gl-signerproxy/Cargo.toml --bin gl-signerproxy && \
109+
strip ${CARGO_TARGET_DIR}/release/gl-plugin ${CARGO_TARGET_DIR}/release/gl-signerproxy
110+
111+
#---------------------------------------------------------------------
112+
# Lock and sync Python dependencies using uv
113+
#---------------------------------------------------------------------
114+
WORKDIR ${REPO_PATH}/libs/gl-testserver
115+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
116+
RUN --mount=type=cache,target=/root/.cache/uv \
117+
uv lock && uv sync --locked -v --no-editable
118+
119+
#---------------------------------------------------------------------
120+
# Collect all artifacts into /opt/stage
121+
#---------------------------------------------------------------------
122+
RUN mkdir -p /opt/stage/bin /opt/stage/bitcoin && \
123+
# Rust binaries
124+
cp ${CARGO_TARGET_DIR}/release/gl-plugin ${CARGO_TARGET_DIR}/release/gl-signerproxy /opt/stage/bin/ && \
125+
# Helper tools
126+
cp /opt/build-tools/* /opt/stage/bin/ && \
127+
# bitcoind
128+
cp -r /opt/bitcoin /opt/stage/ && \
129+
# uv binaries
130+
cp /bin/uv /bin/uvx /opt/stage/bin/ && \
131+
# uv virtual environment
132+
cp -r ${REPO_PATH}/.venv /opt/stage/uv
133+
134+
############################
135+
# Stage 2: runtime
136+
############################
137+
FROM ubuntu:22.04
138+
139+
#---------------------------------------------------------------------
140+
# Minimal runtime packages
141+
#---------------------------------------------------------------------
142+
RUN apt-get update && \
143+
DEBIAN_FRONTEND=noninteractive \
144+
apt-get install -y --no-install-recommends \
145+
python3 \
146+
libpq5 \
147+
curl \
148+
&& apt-get clean && rm -rf /var/lib/apt/lists/*
149+
150+
#---------------------------------------------------------------------
151+
# Arguments & environment variables (kept identical with builder)
152+
#---------------------------------------------------------------------
153+
ARG GID=0
154+
ARG UID=0
155+
ARG DOCKER_USER=dev
156+
ARG REPO_PATH=/repo
157+
158+
ENV PATH=/home/${DOCKER_USER}/.local/bin:/usr/local/bin:/opt/bitcoin/bin:$PATH
159+
ENV REPO=${REPO_PATH}
160+
ENV GL_TESTING_IGNORE_HASH=False
161+
162+
#---------------------------------------------------------------------
163+
# Create runtime user
164+
#---------------------------------------------------------------------
165+
RUN groupadd -g ${GID} -o ${DOCKER_USER} && \
166+
useradd -m -u ${UID} -g ${GID} -s /bin/bash ${DOCKER_USER}
167+
168+
#---------------------------------------------------------------------
169+
# Copy artifacts from the builder stage
170+
#---------------------------------------------------------------------
171+
COPY --from=builder /opt/stage/bin/* /usr/local/bin/
172+
COPY --from=builder /opt/stage/bitcoin /opt/bitcoin
173+
174+
#---------------------------------------------------------------------
175+
# Application code (copy only libs to keep image small)
176+
#---------------------------------------------------------------------
177+
ADD . ${REPO}
178+
COPY --from=builder /opt/stage/uv ${REPO}/.venv
179+
RUN chown -R ${DOCKER_USER}:${DOCKER_USER} ${REPO}
180+
181+
USER ${DOCKER_USER}
182+
WORKDIR ${REPO}/libs/gl-testserver/
183+
184+
#---------------------------------------------------------------------
185+
# ENTRYPOINT
186+
#---------------------------------------------------------------------
187+
CMD . ${REPO}/.venv/bin/activate && python3 gltestserver run --metadata ${REPO}/ --directory ${REPO}/.gltestserver

0 commit comments

Comments
 (0)