build: speed up rust image builds and validate env

This commit is contained in:
a.tolmachev
2026-04-11 10:00:54 +03:00
parent 47b7af784b
commit 70e817b44a
7 changed files with 162 additions and 10 deletions
+7
View File
@@ -6,6 +6,13 @@ dist
coverage
.idea
.vscode
.claude
.codex
.tmp
.DS_Store
*.log
var
apps/ui/node_modules
apps/ui/playwright-report
apps/ui/test-results
apps/ui/.playwright
+23
View File
@@ -138,6 +138,29 @@ jobs:
"
fi
- name: Validate required environment variables
run: |
ssh "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" "
set -e
cd '${{ secrets.DEPLOY_PATH }}'
required_vars='
CRANK_DATABASE_URL
CRANK_MASTER_KEY
CRANK_SESSION_SECRET
CRANK_PASSWORD_PEPPER
CRANK_BOOTSTRAP_ADMIN_EMAIL
CRANK_BOOTSTRAP_ADMIN_PASSWORD
CRANK_PUBLIC_BASE_URL
'
for var in \$required_vars; do
value=\$(grep -E \"^\${var}=\" .env | tail -n1 | cut -d= -f2- || true)
if [ -z \"\$value\" ]; then
echo \"missing required env: \$var\" >&2
exit 1
fi
done
"
- name: Deploy with Docker Compose
run: |
ssh "${{ secrets.DEPLOY_USER }}@${{ secrets.DEPLOY_HOST }}" "
+8 -6
View File
@@ -2,19 +2,21 @@
## Current
### `feat/websocket-test-run-polish`
### `feat/rust-docker-build-cache`
Status: pending
Status: in_progress
DoD:
- WebSocket wizard test-run shows reconnect / bounded-result semantics clearly
- WebSocket test-run flow is covered by local fixtures and Playwright
- `TASKS.md` stays aligned with the actual streaming branch state
- Rust Docker builds use a cache-friendly multi-stage layout
- `admin-api` and `mcp-server` reuse dependency layers across rebuilds
- noisy local artifacts are excluded from Docker build context
- deployment fails early when required secret-store env is missing
## Next
- `feat/live-authenticated-staging-entry`
- `feat/websocket-test-run-polish`
## Backlog
- `feat/websocket-test-run-polish`
- `feat/live-authenticated-staging-entry`
+60 -2
View File
@@ -1,3 +1,57 @@
FROM rust:1.85-bookworm AS deps
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY apps/admin-api/Cargo.toml apps/admin-api/Cargo.toml
COPY apps/mcp-server/Cargo.toml apps/mcp-server/Cargo.toml
COPY crates/crank-core/Cargo.toml crates/crank-core/Cargo.toml
COPY crates/crank-schema/Cargo.toml crates/crank-schema/Cargo.toml
COPY crates/crank-mapping/Cargo.toml crates/crank-mapping/Cargo.toml
COPY crates/crank-proto/Cargo.toml crates/crank-proto/Cargo.toml
COPY crates/crank-registry/Cargo.toml crates/crank-registry/Cargo.toml
COPY crates/crank-runtime/Cargo.toml crates/crank-runtime/Cargo.toml
COPY crates/crank-adapter-rest/Cargo.toml crates/crank-adapter-rest/Cargo.toml
COPY crates/crank-adapter-graphql/Cargo.toml crates/crank-adapter-graphql/Cargo.toml
COPY crates/crank-adapter-grpc/Cargo.toml crates/crank-adapter-grpc/Cargo.toml
COPY crates/crank-adapter-grpc/build.rs crates/crank-adapter-grpc/build.rs
COPY crates/crank-adapter-grpc/proto crates/crank-adapter-grpc/proto
COPY crates/crank-adapter-websocket/Cargo.toml crates/crank-adapter-websocket/Cargo.toml
COPY crates/crank-adapter-soap/Cargo.toml crates/crank-adapter-soap/Cargo.toml
RUN mkdir -p \
apps/admin-api/src \
apps/mcp-server/src \
crates/crank-core/src \
crates/crank-schema/src \
crates/crank-mapping/src \
crates/crank-proto/src \
crates/crank-registry/src \
crates/crank-runtime/src \
crates/crank-adapter-rest/src \
crates/crank-adapter-graphql/src \
crates/crank-adapter-grpc/src \
crates/crank-adapter-websocket/src \
crates/crank-adapter-soap/src \
&& printf 'fn main() {}\n' > apps/admin-api/src/main.rs \
&& printf 'fn main() {}\n' > apps/mcp-server/src/main.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-core/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-schema/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-mapping/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-proto/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-registry/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-runtime/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-adapter-rest/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-adapter-graphql/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-adapter-grpc/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-adapter-websocket/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-adapter-soap/src/lib.rs
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git/db \
--mount=type=cache,target=/app/target \
cargo build --release -p admin-api
FROM rust:1.85-bookworm AS builder
WORKDIR /app
@@ -6,7 +60,11 @@ COPY Cargo.toml Cargo.lock ./
COPY apps ./apps
COPY crates ./crates
RUN cargo build --release -p admin-api
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git/db \
--mount=type=cache,target=/app/target \
cargo build --release -p admin-api \
&& cp /app/target/release/admin-api /tmp/admin-api
FROM debian:bookworm-slim
@@ -16,7 +74,7 @@ RUN apt-get update \
WORKDIR /app
COPY --from=builder /app/target/release/admin-api /usr/local/bin/admin-api
COPY --from=builder /tmp/admin-api /usr/local/bin/admin-api
ENV CRANK_ADMIN_BIND=0.0.0.0:3001
+60 -2
View File
@@ -1,3 +1,57 @@
FROM rust:1.85-bookworm AS deps
WORKDIR /app
COPY Cargo.toml Cargo.lock ./
COPY apps/admin-api/Cargo.toml apps/admin-api/Cargo.toml
COPY apps/mcp-server/Cargo.toml apps/mcp-server/Cargo.toml
COPY crates/crank-core/Cargo.toml crates/crank-core/Cargo.toml
COPY crates/crank-schema/Cargo.toml crates/crank-schema/Cargo.toml
COPY crates/crank-mapping/Cargo.toml crates/crank-mapping/Cargo.toml
COPY crates/crank-proto/Cargo.toml crates/crank-proto/Cargo.toml
COPY crates/crank-registry/Cargo.toml crates/crank-registry/Cargo.toml
COPY crates/crank-runtime/Cargo.toml crates/crank-runtime/Cargo.toml
COPY crates/crank-adapter-rest/Cargo.toml crates/crank-adapter-rest/Cargo.toml
COPY crates/crank-adapter-graphql/Cargo.toml crates/crank-adapter-graphql/Cargo.toml
COPY crates/crank-adapter-grpc/Cargo.toml crates/crank-adapter-grpc/Cargo.toml
COPY crates/crank-adapter-grpc/build.rs crates/crank-adapter-grpc/build.rs
COPY crates/crank-adapter-grpc/proto crates/crank-adapter-grpc/proto
COPY crates/crank-adapter-websocket/Cargo.toml crates/crank-adapter-websocket/Cargo.toml
COPY crates/crank-adapter-soap/Cargo.toml crates/crank-adapter-soap/Cargo.toml
RUN mkdir -p \
apps/admin-api/src \
apps/mcp-server/src \
crates/crank-core/src \
crates/crank-schema/src \
crates/crank-mapping/src \
crates/crank-proto/src \
crates/crank-registry/src \
crates/crank-runtime/src \
crates/crank-adapter-rest/src \
crates/crank-adapter-graphql/src \
crates/crank-adapter-grpc/src \
crates/crank-adapter-websocket/src \
crates/crank-adapter-soap/src \
&& printf 'fn main() {}\n' > apps/admin-api/src/main.rs \
&& printf 'fn main() {}\n' > apps/mcp-server/src/main.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-core/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-schema/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-mapping/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-proto/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-registry/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-runtime/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-adapter-rest/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-adapter-graphql/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-adapter-grpc/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-adapter-websocket/src/lib.rs \
&& printf 'pub fn placeholder() {}\n' > crates/crank-adapter-soap/src/lib.rs
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git/db \
--mount=type=cache,target=/app/target \
cargo build --release -p mcp-server
FROM rust:1.85-bookworm AS builder
WORKDIR /app
@@ -6,7 +60,11 @@ COPY Cargo.toml Cargo.lock ./
COPY apps ./apps
COPY crates ./crates
RUN cargo build --release -p mcp-server
RUN --mount=type=cache,target=/usr/local/cargo/registry \
--mount=type=cache,target=/usr/local/cargo/git/db \
--mount=type=cache,target=/app/target \
cargo build --release -p mcp-server \
&& cp /app/target/release/mcp-server /tmp/mcp-server
FROM debian:bookworm-slim
@@ -16,7 +74,7 @@ RUN apt-get update \
WORKDIR /app
COPY --from=builder /app/target/release/mcp-server /usr/local/bin/mcp-server
COPY --from=builder /tmp/mcp-server /usr/local/bin/mcp-server
ENV CRANK_MCP_BIND=0.0.0.0:3002
+1
View File
@@ -63,6 +63,7 @@ services:
CRANK_MCP_REFRESH_MS: ${CRANK_MCP_REFRESH_MS:-5000}
CRANK_LOG_LEVEL: ${CRANK_LOG_LEVEL:-info}
CRANK_SECRET_PROVIDER: ${CRANK_SECRET_PROVIDER:-env}
CRANK_MASTER_KEY: ${CRANK_MASTER_KEY}
CRANK_PUBLIC_BASE_URL: ${CRANK_PUBLIC_BASE_URL:-http://localhost:3000}
depends_on:
postgres:
+3
View File
@@ -135,6 +135,9 @@ Demo/deployment:
- `CRANK_MASTER_KEY`
`CRANK_MASTER_KEY` обязателен и для `admin-api`, и для `mcp-server`, потому что оба приложения
должны уметь резолвить `secret_id` в runtime.
Для опционального demo-seed:
- `CRANK_DEMO_SEED=true`