-
Notifications
You must be signed in to change notification settings - Fork 1
chore(infra): harden verifier runtime #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
Canvinus
wants to merge
4
commits into
main
Choose a base branch
from
chore/harden-runtime-build
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1,6 @@ | ||
| node_modules | ||
| .git | ||
| **/._* | ||
| coverage | ||
| dist | ||
| node_modules | ||
| npm-debug.log* |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,70 +1,92 @@ | ||
| # Build stage | ||
| FROM node@sha256:2bdb65ed1dab192432bc31c95f94155ca5ad7fc1392fb7eb7526ab682fa5bf14 AS build | ||
| # syntax=docker/dockerfile:1.7 | ||
|
|
||
| WORKDIR /app | ||
| ARG NEAR_CLI_RS_VERSION=0.27.0 | ||
|
|
||
| # Keep exact tags for reviewability and digests for reproducibility. | ||
| FROM node:24.17.0-alpine3.24@sha256:156b55f92e98ccd5ef49578a8cea0df4679826564bad1c9d4ef04462b9f0ded6 AS node-build | ||
|
|
||
| RUN apk add --update python3 make g++\ | ||
| && rm -rf /var/cache/apk/* | ||
| WORKDIR /app | ||
|
|
||
| # Copy configuration files | ||
| COPY eslint.config.mjs ./ | ||
| COPY tsconfig*.json ./ | ||
| COPY package*.json ./ | ||
|
|
||
| # Install dependencies from package-lock.json | ||
| RUN npm ci | ||
| # Install dependencies from package-lock.json. | ||
| RUN --mount=type=cache,target=/root/.npm,sharing=locked npm ci | ||
|
|
||
| # Copy application sources (.ts, .tsx, js) | ||
| COPY src/ src/ | ||
|
|
||
| # Build application (produces dist/ folder) | ||
| RUN npm run build | ||
|
|
||
| # Runtime (production) layer | ||
| FROM docker@sha256:7d85d0eda291f1a7ab6df4a9d1802b5ad4cf9145a088bd11188c78dcb5c7392b AS production | ||
| # Keep only dependencies needed by the production application. | ||
| FROM node-build AS node-production | ||
|
|
||
| RUN npm prune --omit=dev | ||
|
|
||
| # Build near-cli-rs separately so Rust and compiler tooling never reach runtime. | ||
| FROM rust:1.96.1-alpine3.24@sha256:a41f7740f8b45d45795624eec13a8b42263cc700f19f7e4e86e04d3dda08a479 AS near-cli-build | ||
|
|
||
| ARG NEAR_CLI_RS_VERSION | ||
|
|
||
| # Install dependencies for Rust, build tools, and HIDAPI | ||
| RUN apk add --no-cache \ | ||
| python3 \ | ||
| git \ | ||
| curl \ | ||
| perl \ | ||
| protobuf \ | ||
| eudev-dev \ | ||
| build-base \ | ||
| pkgconfig \ | ||
| eudev-dev \ | ||
| linux-headers \ | ||
| bash | ||
| perl \ | ||
| pkgconf \ | ||
| protobuf | ||
|
|
||
| RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \ | ||
| --mount=type=cache,target=/usr/local/cargo/git,sharing=locked \ | ||
| --mount=type=cache,target=/tmp/cargo-target,sharing=locked \ | ||
| CARGO_TARGET_DIR=/tmp/cargo-target \ | ||
| cargo install near-cli-rs --version "${NEAR_CLI_RS_VERSION}" --locked | ||
|
|
||
| # Install Rust | ||
| ENV RUSTUP_HOME=/usr/local/rustup | ||
| ENV CARGO_HOME=/usr/local/cargo | ||
| RUN test "$(near --version)" = "near-cli-rs ${NEAR_CLI_RS_VERSION}" | ||
|
|
||
| # Runtime (production) layer | ||
| FROM docker:29.6.1-dind@sha256:66d292e5c26bd33a6f6f61cacb880de2186339a524ecba1ce098dbbaceed6515 AS production | ||
|
|
||
| RUN mkdir -p $RUSTUP_HOME $CARGO_HOME \ | ||
| && curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain stable -y \ | ||
| && ln -s $RUSTUP_HOME /root/.rustup \ | ||
| && ln -s $CARGO_HOME /root/.cargo | ||
| # Add Rust to the PATH environment variable for all subsequent commands | ||
| ENV PATH="/usr/local/cargo/bin:$PATH" | ||
| ARG NEAR_CLI_RS_VERSION | ||
|
|
||
| # Install near-cli-rs for contract verification | ||
| RUN cargo install near-cli-rs --locked | ||
| LABEL dev.sourcescan.near-cli-rs.version="${NEAR_CLI_RS_VERSION}" | ||
|
|
||
| # Set environment variable for near-cli-rs to run in non-interactive mode | ||
| ENV NEAR_CI=1 | ||
| # Git requires libcurl, while Compose and Buildx are host-side tools here. | ||
| RUN apk upgrade --no-cache libcurl \ | ||
| && rm -f \ | ||
| /usr/local/libexec/docker/cli-plugins/docker-buildx \ | ||
| /usr/local/libexec/docker/cli-plugins/docker-compose | ||
|
|
||
| # Keep near-cli-rs non-interactive and point child processes at the embedded daemon. | ||
| ENV NEAR_CI=1 \ | ||
| DOCKER_HOST=unix:///var/run/docker.sock | ||
|
|
||
| WORKDIR /app | ||
|
|
||
| # Copy node and npm from build stage | ||
| COPY --from=build /usr/local /usr/local | ||
| # Copy Node and the pinned near CLI into the runtime image. | ||
| COPY --from=node-build /usr/lib/libgcc_s.so.1 /usr/lib/ | ||
| COPY --from=node-build /usr/lib/libstdc++.so.6* /usr/lib/ | ||
| COPY --from=node-build /usr/local/bin/node /usr/local/bin/node | ||
| COPY --from=near-cli-build /usr/local/cargo/bin/near /usr/local/bin/near | ||
|
|
||
| # Copy dependencies files | ||
| # Copy package metadata and production dependencies. | ||
| COPY package*.json ./ | ||
|
|
||
| # Install runtime dependencies (without dev/test dependencies) | ||
| RUN npm ci --omit=dev | ||
| COPY --from=node-production /app/node_modules/ ./node_modules/ | ||
| COPY docker-healthcheck.js ./ | ||
|
|
||
| # Copy production build | ||
| COPY --from=build /app/dist/ ./dist/ | ||
| COPY --from=node-build /app/dist/ ./dist/ | ||
|
|
||
| # Fail the image build if any required runtime binary is unusable. | ||
| RUN node --version \ | ||
| && near --version \ | ||
| && docker --version | ||
|
|
||
| HEALTHCHECK --interval=15s --timeout=5s --start-period=10s --retries=3 \ | ||
| CMD ["node", "docker-healthcheck.js"] | ||
|
|
||
| # Start the application when dockerd is ready | ||
| CMD ["sh", "-ec", "rm -f /var/run/docker.pid /var/run/docker.sock /var/run/docker/containerd/containerd.pid /var/run/docker/containerd/containerd.sock /var/run/docker/containerd/containerd.sock.ttrpc /var/run/docker/containerd/containerd-debug.sock; dockerd & until docker info >/dev/null 2>&1; do sleep 1; done; exec node dist/main.js"] | ||
| CMD ["sh", "-ec", "rm -f /var/run/docker.pid /var/run/docker.sock /var/run/docker/containerd/containerd.pid /var/run/docker/containerd/containerd.sock /var/run/docker/containerd/containerd.sock.ttrpc /var/run/docker/containerd/containerd-debug.sock; dockerd & until node docker-healthcheck.js --docker-only >/dev/null 2>&1; do sleep 1; done; exec node dist/main.js"] | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| 'use strict'; | ||
|
|
||
| const http = require('node:http'); | ||
|
|
||
| function request(options, label) { | ||
| return new Promise((resolve, reject) => { | ||
| const req = http.get(options, (response) => { | ||
| response.resume(); | ||
|
|
||
| if (response.statusCode >= 200 && response.statusCode < 300) { | ||
| resolve(); | ||
| return; | ||
| } | ||
|
|
||
| reject(new Error(`${label} returned HTTP ${response.statusCode}`)); | ||
| }); | ||
|
|
||
| req.setTimeout(3000, () => req.destroy(new Error(`${label} timed out`))); | ||
| req.on('error', reject); | ||
| }); | ||
| } | ||
|
|
||
| async function main() { | ||
| await request( | ||
| { socketPath: '/var/run/docker.sock', path: '/_ping' }, | ||
| 'Docker daemon', | ||
| ); | ||
|
|
||
| if (process.argv.includes('--docker-only')) { | ||
| return; | ||
| } | ||
|
|
||
| const port = Number(process.env.NEST_PORT); | ||
| if (!Number.isInteger(port) || port < 1 || port > 65535) { | ||
| throw new Error('NEST_PORT must be a valid TCP port'); | ||
| } | ||
|
|
||
| await request({ host: '127.0.0.1', port, path: '/' }, 'Verifier API'); | ||
| } | ||
|
|
||
| main().catch((error) => { | ||
| console.error(error.message); | ||
| process.exit(1); | ||
| }); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.