Skip to content

Commit 0ba71d8

Browse files
ci: add Docker images with Datadog profiler (#185)
* ci: add Docker images with Datadog profiler * ci: use `inputs` instead + try to add test job * ci: install node modules + add name to job * ci: try to fix test image step * ci: remove tests on Docker image + small improvements * ci: fix digest error * fix(debian dockerfile): also use a condition to fetch the correct ddprof
1 parent 4d68e1c commit 0ba71d8

File tree

6 files changed

+167
-36
lines changed

6 files changed

+167
-36
lines changed

.github/workflows/_build-and-merge-docker.yml

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@ on:
99
distro:
1010
required: true
1111
type: string
12+
with_datadog_profiling:
13+
required: true
14+
type: boolean
1215

13-
# Taken from https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
16+
# Adapted from https://docs.docker.com/build/ci/github-actions/multi-platform/#distribute-build-across-multiple-runners
1417
jobs:
1518
build-docker:
19+
name: Build Docker image for ${{ inputs.distro }} on ${{ matrix.platform }} (DD ${{ inputs.with_datadog_profiling }})
1620
# We use a custom runner for ARM64 builds.
1721
runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-22.04' || 'ubuntu-22.04-arm' }}
1822
strategy:
@@ -26,6 +30,7 @@ jobs:
2630
packages: write
2731
env:
2832
DATABASE_URL: postgresql://postgres:postgres@localhost/nittei
33+
2934
steps:
3035
- name: Prepare
3136
run: |
@@ -60,12 +65,11 @@ jobs:
6065
id: build
6166
uses: docker/build-push-action@v6
6267
with:
63-
file: "./${{ inputs.distro }}.Dockerfile"
68+
file: "./${{ inputs.distro }}${{ inputs.with_datadog_profiling && 'WithDD' || '' }}.Dockerfile"
6469
platforms: ${{ matrix.platform }}
65-
# This is for the Alpine image
70+
# Handle the correct arch
6671
build-args: |
6772
ARCH=${{ matrix.platform == 'linux/amd64' && 'x86_64' || 'aarch64' }}
68-
labels: ${{ steps.meta.outputs.labels }}
6973
outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
7074

7175
- name: Export digest
@@ -77,7 +81,7 @@ jobs:
7781
- name: Upload digest
7882
uses: actions/upload-artifact@v4
7983
with:
80-
name: digests-${{ inputs.distro }}-${{ env.PLATFORM_PAIR }}
84+
name: digests-${{ inputs.distro }}-${{ inputs.with_datadog_profiling }}-${{ env.PLATFORM_PAIR }}
8185
path: /tmp/digests/*
8286
if-no-files-found: error
8387
retention-days: 1
@@ -91,7 +95,7 @@ jobs:
9195
uses: actions/download-artifact@v4
9296
with:
9397
path: /tmp/digests
94-
pattern: digests-${{ inputs.distro }}-*
98+
pattern: digests-${{ inputs.distro }}-${{ inputs.with_datadog_profiling }}-*
9599
merge-multiple: true
96100

97101
- name: Set up Docker Buildx
@@ -109,14 +113,34 @@ jobs:
109113
VERSION=${GITHUB_REF#refs/*/}
110114
echo "VERSION=${VERSION:1}" >> $GITHUB_ENV
111115
116+
- name: Set Docker tags
117+
id: set-tags
118+
run: |
119+
# For debian: latest, debian, 1.0.0
120+
# For debian with DD: dd-latest, debian-dd, dd-1.0.0
121+
# For alpine: alpine-latest, alpine, alpine-1.0.0
122+
# For alpine with DD: alpine-dd-latest, alpine-dd, alpine-dd-1.0.0
123+
124+
if [[ "${{ inputs.distro }}" == "debian" ]]; then
125+
if [[ "${{ inputs.with_datadog_profiling }}" == "true" ]]; then
126+
echo "TAGS=dd-latest, debian-dd, dd-${{ env.VERSION }}" >> $GITHUB_ENV
127+
else
128+
echo "TAGS=latest, debian, ${{ env.VERSION }}" >> $GITHUB_ENV
129+
fi
130+
elif [[ "${{ inputs.distro }}" == "alpine" ]]; then
131+
if [[ "${{ inputs.with_datadog_profiling }}" == "true" ]]; then
132+
echo "TAGS=alpine-dd-latest, alpine-dd, alpine-dd-${{ env.VERSION }}" >> $GITHUB_ENV
133+
else
134+
echo "TAGS=alpine-latest, alpine, alpine-${{ env.VERSION }}" >> $GITHUB_ENV
135+
fi
136+
fi
137+
112138
- name: Docker meta
113139
id: meta
114140
uses: docker/metadata-action@v5
115141
with:
116142
images: ${{ env.REGISTRY_IMAGE }}
117-
# For debian: latest, debian, 1.0.0
118-
# For alpine: alpine, alpine-1.0.0
119-
tags: ${{ inputs.distro == 'debian' && format('latest, debian, {0}', env.VERSION) || format('alpine, alpine-{0}', env.VERSION) }}
143+
tags: ${{ env.TAGS }}
120144

121145
- name: Create manifest list and push
122146
working-directory: /tmp/digests

.github/workflows/release.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,28 @@ jobs:
1515
uses: ./.github/workflows/_build-and-merge-docker.yml
1616
with:
1717
distro: debian
18+
with_datadog_profiling: false
1819
secrets: inherit
1920

2021
alpine-build-and-merge-docker:
2122
uses: ./.github/workflows/_build-and-merge-docker.yml
2223
with:
2324
distro: alpine
25+
with_datadog_profiling: false
26+
secrets: inherit
27+
28+
debian-dd-build-and-merge-docker:
29+
uses: ./.github/workflows/_build-and-merge-docker.yml
30+
with:
31+
distro: debian
32+
with_datadog_profiling: true
33+
secrets: inherit
34+
35+
alpine-dd-build-and-merge-docker:
36+
uses: ./.github/workflows/_build-and-merge-docker.yml
37+
with:
38+
distro: alpine
39+
with_datadog_profiling: true
2440
secrets: inherit
2541

2642
# We don't use the Rust client for now

Dockerfile

Lines changed: 0 additions & 26 deletions
This file was deleted.

alpine.Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,4 @@ ENV APP_NAME=${APP_NAME}
3232

3333
COPY --from=builder /${APP_NAME} /${APP_NAME}
3434

35-
CMD /${APP_NAME}
35+
CMD ["/bin/sh", "-c", "exec /${APP_NAME}"]

alpineWithDD.Dockerfile

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# This Dockerfile is based on the alpine.Dockerfile and adds the ddprof tool to the image.
2+
#
3+
# Usage:
4+
# docker buildx build -f alpineWithDD.Dockerfile -t image:tag --build-arg='ARCH=x86_64' --platform linux/amd64 .
5+
# docker buildx build -f alpineWithDD.Dockerfile -t image:tag --build-arg='ARCH=aarch64' --platform linux/arm64 .
6+
7+
ARG ARCH=x86_64
8+
FROM messense/rust-musl-cross:${ARCH}-musl AS builder
9+
10+
ARG ARCH=x86_64
11+
ARG APP_NAME=nittei
12+
ARG RUST_VERSION=1.84.0
13+
14+
# Install and set the specific Rust version
15+
RUN rustup install ${RUST_VERSION} && rustup default ${RUST_VERSION}
16+
17+
# Install the musl target for the correct architecture
18+
RUN rustup target add ${ARCH}-unknown-linux-musl
19+
20+
# Verify the Rust and target setup
21+
RUN rustc --version && rustup show
22+
23+
# Copy source code from previous stage
24+
COPY . .
25+
26+
# Build application
27+
RUN cargo build --release --target ${ARCH}-unknown-linux-musl && \
28+
cp ./target/${ARCH}-unknown-linux-musl/release/${APP_NAME} /${APP_NAME}
29+
30+
# Install ddprof
31+
RUN ARCH_IN_URL=$(case "${ARCH}" in \
32+
x86_64) echo "amd64" ;; \
33+
aarch64) echo "arm64" ;; \
34+
*) echo "unsupported-arch" && exit 1 ;; \
35+
esac) && \
36+
curl -Lo ddprof-linux.tar.xz https://github.com/DataDog/ddprof/releases/latest/download/ddprof-${ARCH_IN_URL}-linux.tar.xz && \
37+
tar xvf ddprof-linux.tar.xz && \
38+
mv ddprof/bin/ddprof /ddprof
39+
40+
#Create a new stage with a minimal image
41+
FROM alpine:3.20.3
42+
43+
ARG APP_NAME=nittei
44+
ENV APP_NAME=${APP_NAME}
45+
46+
COPY --from=builder /${APP_NAME} /${APP_NAME}
47+
COPY --from=builder /ddprof /ddprof
48+
49+
CMD ["/bin/sh", "-c", "exec /ddprof /${APP_NAME}"]

debianWithDD.Dockerfile

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# This Dockerfile is based on the debian.Dockerfile and adds the ddprof tool to the image.
2+
3+
# Usage:
4+
# docker buildx build -f debianWithDD.Dockerfile -t image:tag --build-arg='ARCH=x86_64' --platform linux/amd64 .
5+
# docker buildx build -f debianWithDD.Dockerfile -t image:tag --build-arg='ARCH=aarch64' --platform linux/arm64 .
6+
7+
ARG RUST_VERSION=1.84.0
8+
ARG APP_NAME=nittei
9+
ARG ARCH=x86_64
10+
11+
FROM rust:${RUST_VERSION}-slim AS builder
12+
13+
ARG ARCH=x86_64
14+
ARG APP_NAME
15+
16+
WORKDIR /app/${APP_NAME}
17+
18+
RUN apt update \
19+
&& apt install -y --no-install-recommends curl openssl ca-certificates pkg-config build-essential libssl-dev \
20+
&& apt clean \
21+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
22+
23+
RUN --mount=type=bind,source=bins,target=/app/${APP_NAME}/bins \
24+
--mount=type=bind,source=crates,target=/app/${APP_NAME}/crates \
25+
--mount=type=bind,source=clients,target=/app/${APP_NAME}/clients \
26+
--mount=type=bind,source=Cargo.toml,target=Cargo.toml \
27+
--mount=type=bind,source=Cargo.lock,target=Cargo.lock \
28+
--mount=type=cache,target=/app/${APP_NAME}/target/ \
29+
--mount=type=cache,target=/usr/local/cargo/git/db \
30+
--mount=type=cache,target=/usr/local/cargo/registry/ \
31+
cargo build --locked --release && \
32+
cp ./target/release/$APP_NAME /bin/server
33+
34+
# Install ddprof
35+
RUN ARCH_IN_URL=$(case "${ARCH}" in \
36+
x86_64) echo "amd64" ;; \
37+
aarch64) echo "arm64" ;; \
38+
*) echo "unsupported-arch" && exit 1 ;; \
39+
esac) && \
40+
curl -Lo ddprof-linux.tar.xz https://github.com/DataDog/ddprof/releases/latest/download/ddprof-${ARCH_IN_URL}-linux.tar.xz && \
41+
tar xvf ddprof-linux.tar.xz && \
42+
mv ddprof/bin/ddprof /ddprof
43+
44+
FROM debian:stable-slim
45+
46+
# Enable backtraces
47+
ENV RUST_BACKTRACE=1
48+
49+
RUN apt update \
50+
&& apt install -y openssl ca-certificates \
51+
&& apt clean \
52+
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
53+
54+
ARG UID=10001
55+
RUN adduser \
56+
--disabled-password \
57+
--gecos "" \
58+
--home "/nonexistent" \
59+
--shell "/sbin/nologin" \
60+
--no-create-home \
61+
--uid "${UID}" \
62+
appuser
63+
USER appuser
64+
65+
COPY --from=builder /bin/server /bin/
66+
COPY --from=builder /ddprof /ddprof
67+
68+
CMD ["/ddprof", "/bin/server"]

0 commit comments

Comments
 (0)