Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 31 additions & 27 deletions .github/workflows/test_build_docker.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,36 +41,40 @@ jobs:
run: |
docker run --rm --entrypoint="" test-image openssl --version

- name: Verify unnecessary packages are removed
- name: Verify build tooling is absent
run: |
docker run --rm --entrypoint="" test-image sh -c '
(command -v npm && echo "FAIL: npm found" && exit 1) || echo "✓ npm removed"
(command -v pnpm && echo "FAIL: pnpm found" && exit 1) || echo "✓ pnpm removed"
(command -v corepack && echo "FAIL: corepack found" && exit 1) || echo "✓ corepack removed"
(command -v python3 && echo "FAIL: python3 found" && exit 1) || echo "✓ python3 removed"
(command -v yum && echo "FAIL: yum found" && exit 1) || echo "✓ yum removed"
(command -v dnf && echo "FAIL: dnf found" && exit 1) || echo "✓ dnf removed"
(command -v npm && echo "FAIL: npm found" && exit 1) || echo "✓ npm absent"
(command -v pnpm && echo "FAIL: pnpm found" && exit 1) || echo "✓ pnpm absent"
(command -v corepack && echo "FAIL: corepack found" && exit 1) || echo "✓ corepack absent"
(command -v python3 && echo "FAIL: python3 found" && exit 1) || echo "✓ python3 absent"
(command -v yum && echo "FAIL: yum found" && exit 1) || echo "✓ yum absent"
(command -v dnf && echo "FAIL: dnf found" && exit 1) || echo "✓ dnf absent"
'

# One run per way the entrypoint starts the server: plain HTTP on 80,
# notebook mode on 9250, and HTTPS on 443, where HOST makes the entrypoint
# generate a self-signed certificate.
- name: Verify server starts and responds
run: |
docker run -d --name test-server \
-p 8080:80 \
-e PROXY_SERVER_HTTPS_CONNECTION=false \
test-image
trap 'docker rm -f test-server 2>/dev/null' EXIT

# Wait for the server to be ready
for i in $(seq 1 30); do
if curl -sf http://localhost:8080/status; then
echo ""
echo "✓ Server responded on /status"
break
fi
if [ "$i" -eq 30 ]; then
echo "FAIL: Server did not respond within 30 seconds"
docker logs test-server
exit 1
fi
sleep 1
done
check() {
name=$1 host_port=$2 container_port=$3 scheme=$4
shift 4
docker run -d --name "$name" -p "$host_port:$container_port" "$@" test-image
for i in $(seq 1 30); do
if curl -sfk "$scheme://localhost:$host_port/status"; then
echo ""
echo "✓ $name responded on /status"
docker rm -f "$name" >/dev/null
return 0
fi
sleep 1
done
echo "FAIL: $name did not respond within 30 seconds"
docker logs "$name"
docker rm -f "$name" >/dev/null
return 1
}
check http 8080 80 http -e PROXY_SERVER_HTTPS_CONNECTION=false
check notebook 9250 9250 http -e NEPTUNE_NOTEBOOK=true
check https 8443 443 https -e HOST=localhost
61 changes: 35 additions & 26 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,48 +2,57 @@
# Pinned to a dated ECR Public snapshot for reproducible builds; bump to move forward.
# The tag also pins dnf repo metadata to that date, so the yum update below resolves
# against that snapshot and cannot reach anything published after it.
FROM public.ecr.aws/amazonlinux/amazonlinux:2023.12.20261013.0 AS base
FROM public.ecr.aws/amazonlinux/amazonlinux:2023.12.20261013.0 AS os
ENV NODE_VERSION=24.21.0

# Install Node.js and openssl, then remove everything not needed at runtime
# (package managers, python3, build tools) to minimize potential issues.
# Node.js and pnpm for the build stages. The runtime copies only the node binary.
FROM os AS toolchain
RUN yum update -y && \
yum install -y tar xz openssl && \
yum install -y tar xz && \
ARCH=$(uname -m) && \
if [ "$ARCH" = "x86_64" ]; then NODE_ARCH="x64"; \
elif [ "$ARCH" = "aarch64" ]; then NODE_ARCH="arm64"; \
else echo "Unsupported architecture: $ARCH" && exit 1; fi && \
curl -fsSL https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.xz | tar -xJ -C /usr/local --strip-components=1 && \
npm install --global corepack@0.36.0 && \
corepack enable && \
yum remove -y tar xz && \
corepack enable
WORKDIR /graph-explorer

FROM toolchain AS build
# The image has no git, so skip installing the Vite+ commit hooks.
ENV VP_GIT_HOOKS=0
COPY . .
RUN pnpm install --frozen-lockfile && \
pnpm build && \
pnpm clean:dep && \
chmod a+x ./process-environment.sh ./setup-ssl.sh ./docker-entrypoint.sh

# Installed from the manifests alone, so the layer is reused until a
# dependency changes and never holds devDependencies.
FROM toolchain AS deps
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./
COPY packages/graph-explorer/package.json packages/graph-explorer/
COPY packages/graph-explorer-proxy-server/package.json packages/graph-explorer-proxy-server/
COPY packages/shared/package.json packages/shared/
RUN pnpm install --prod --frozen-lockfile --ignore-scripts

# openssl is for setup-ssl.sh. yum, dnf, and python3 come with the base image
# and are stripped; npm, pnpm, and corepack never reach this stage.
FROM os AS runtime
RUN yum update -y && \
yum install -y openssl && \
yum clean all && \
rpm -qa 'python3*' | while read pkg; do rpm -e --nodeps "$pkg"; done && \
rpm -qa 'dnf*' 'yum*' 'libdnf*' | while read pkg; do rpm -e --nodeps "$pkg"; done && \
rm -rf /var/cache/yum /var/cache/dnf

FROM base
# LICENSE carries the notices for the third-party code built into node.
COPY --from=toolchain /usr/local/bin/node /usr/local/bin/node
COPY --from=toolchain /usr/local/LICENSE /usr/local/LICENSE

ENV HOME=/graph-explorer
# The image has no git, so skip installing the Vite+ commit hooks.
ENV VP_GIT_HOOKS=0

WORKDIR /
COPY . /graph-explorer/
WORKDIR /graph-explorer

RUN pnpm install --frozen-lockfile && \
pnpm build && \
pnpm clean:dep && \
pnpm install --prod --frozen-lockfile --ignore-scripts && \
npm uninstall -g npm && \
corepack disable && \
rm -rf /usr/local/bin/pnpm* /usr/local/bin/corepack && \
rm -rf $HOME/.local && \
rm -rf $HOME/.cache && \
chmod a+x ./process-environment.sh && \
chmod a+x ./setup-ssl.sh && \
chmod a+x ./docker-entrypoint.sh
COPY --from=deps /graph-explorer ./
COPY --from=build /graph-explorer ./

EXPOSE 443
EXPOSE 80
Expand Down
Loading