-
Notifications
You must be signed in to change notification settings - Fork 15
Expand file tree
/
Copy pathDockerfile
More file actions
75 lines (59 loc) · 2.73 KB
/
Copy pathDockerfile
File metadata and controls
75 lines (59 loc) · 2.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# =============================================================================
# Build stage - Compile the Rust binary (Alpine/musl, static binary)
# =============================================================================
FROM rust:1.96-alpine AS builder
WORKDIR /app
# Install build dependencies
RUN apk add --no-cache \
musl-dev \
pkgconfig \
cmake \
perl
# Copy only Cargo files first for better layer caching
COPY Cargo.toml Cargo.lock ./
# Create stub sources (lib + bin) so cargo can compile *only* the dependencies.
# The real source is layered on top afterward; cargo then rebuilds just our crates.
RUN mkdir -p src && \
echo "fn main() {}" > src/main.rs
# Pre-build dependencies. BuildKit cache mounts persist the cargo registry and
# the build target across builds, so un
61AD
changed dependencies are never recached
# or recompiled. Sharing=locked is safe here (single buildx invocation).
RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \
--mount=type=cache,target=/app/target,sharing=locked \
cargo build --release --locked
# Replace stubs with the real source code
RUN rm -rf src
COPY . .
# Final build: only the project crates recompile. Bump source mtimes after
# COPY so cargo's fingerprint (mtime-based) invalidates the project crate --
# the stub build recorded src/*.rs older than what COPY delivered, so without
# this cargo would skip the rebuild and ship the stub binary. Dependencies are
# untouched (they live in the cargo registry, not /app/src). Copy the produced
# binary out of the cache mount into the image layer for the runtime stage.
RUN --mount=type=cache,target=/usr/local/cargo/registry,sharing=locked \
--mount=type=cache,target=/app/target,sharing=locked \
find src -type f -exec touch {} + && \
cargo build --release --locked && \
cp target/release/m4b-merge /usr/local/bin/m4b-merge
# =============================================================================
# Runtime stage - Minimal Alpine image with FFmpeg
# =============================================================================
FROM alpine:3.22 AS runtime
# Install runtime dependencies
RUN apk add --no-cache ffmpeg ca-certificates
# Create non-root user
RUN addgroup -S appgroup && adduser -S -G appgroup appuser
# Create necessary directories
RUN mkdir -p /input /output /config && \
chown -R appuser:appgroup /input /output /config
# Copy the binary from builder (copied out of the cache mount in the builder
# stage so it persists in the image layer)
COPY --from=builder /usr/local/bin/m4b-merge /usr/local/bin/m4b-merge
# Set environment variables
ENV HOME=/home/appuser
# Switch to non-root user
USER appuser
# Set working directory
WORKDIR /home/appuser
# Default command
ENTRYPOINT ["m4b-merge"]