-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
165 lines (132 loc) · 5.69 KB
/
Copy pathDockerfile
File metadata and controls
165 lines (132 loc) · 5.69 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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
### Multi-stage build for Rust OAuth2 Server (with cargo-chef)
###
### This layout maximizes Docker layer cache reuse:
### - dependencies are compiled in an early cached layer
### - application code changes only rebuild the final binary
###
### Admin CSS is compiled by the Tailwind standalone CLI (no Node/npm required).
### The CSS is pre-built in a dedicated stage and copied into the final image.
# ── Stage 0: Tailwind CSS build ─────────────────────────────────────────────
# Base images are pinned by digest for supply-chain integrity. Refresh digests
# deliberately (e.g. via Dependabot) rather than letting a mutable tag drift.
FROM debian:trixie-slim@sha256:28de0877c2189802884ccd20f15ee41c203573bd87bb6b883f5f46362d24c5c2 AS tailwind-build
ARG TAILWIND_VERSION=v3.4.17
ARG TARGETARCH=amd64
WORKDIR /tw
RUN apt-get update && apt-get install -y curl && rm -rf /var/lib/apt/lists/*
# Download the Tailwind standalone binary (no Node.js needed)
RUN set -eux; \
ARCH="$(dpkg --print-architecture)"; \
case "$ARCH" in \
amd64) TWARCH="linux-x64" ;; \
arm64) TWARCH="linux-arm64" ;; \
*) TWARCH="linux-x64" ;; \
esac; \
curl -fsSL -o tailwindcss \
"https://github.com/tailwindlabs/tailwindcss/releases/download/${TAILWIND_VERSION}/tailwindcss-${TWARCH}"; \
chmod +x tailwindcss
COPY tailwind.config.js ./
COPY static/css/admin.src.css ./
COPY templates/ ./templates/
COPY static/js/ ./static/js/
RUN ./tailwindcss -c tailwind.config.js -i admin.src.css -o admin.min.css --minify
FROM rust:slim@sha256:c37af730be4fd8104cbf9aedbd6ab259e51ca2d5437817a0f8680edf66ac6c28 AS chef
WORKDIR /app
# Build dependencies for popular crates (openssl, etc.)
RUN apt-get update && apt-get install -y \
pkg-config \
libssl-dev \
curl \
unzip \
&& rm -rf /var/lib/apt/lists/*
# Install cargo-chef (cached as a layer). Pin the version so the build tool
# itself can't drift to a newly-published (potentially compromised) release.
RUN cargo install cargo-chef --version 0.1.77 --locked
FROM chef AS planner
# Only copy the manifests first so changes to app source don't bust the dependency cache.
COPY Cargo.toml Cargo.lock ./
COPY crates ./crates
COPY oauth2-ratelimit ./oauth2-ratelimit
COPY oauth2-resilience ./oauth2-resilience
COPY tests ./tests
RUN cargo chef prepare --recipe-path recipe.json
FROM chef AS cacher
# Optional cargo features (e.g., "mongo")
ARG CARGO_FEATURES=""
ARG CARGO_NO_DEFAULT_FEATURES="false"
COPY --from=planner /app/recipe.json recipe.json
RUN if [ -n "$CARGO_FEATURES" ]; then \
if [ "$CARGO_NO_DEFAULT_FEATURES" = "true" ]; then \
cargo chef cook --release --locked --recipe-path recipe.json --no-default-features --features "$CARGO_FEATURES"; \
else \
cargo chef cook --release --locked --recipe-path recipe.json --features "$CARGO_FEATURES"; \
fi; \
else \
if [ "$CARGO_NO_DEFAULT_FEATURES" = "true" ]; then \
cargo chef cook --release --locked --recipe-path recipe.json --no-default-features; \
else \
cargo chef cook --release --locked --recipe-path recipe.json; \
fi; \
fi
FROM chef AS builder
# Optional cargo features (e.g., "mongo")
ARG CARGO_FEATURES=""
ARG CARGO_NO_DEFAULT_FEATURES="false"
# Reuse the dependency build artifacts from the cacher stage
COPY --from=cacher /app/target /app/target
COPY --from=cacher /usr/local/cargo /usr/local/cargo
# Copy full source tree and build the application
COPY . .
RUN if [ -n "$CARGO_FEATURES" ]; then \
if [ "$CARGO_NO_DEFAULT_FEATURES" = "true" ]; then \
cargo build --release --locked --no-default-features --features "$CARGO_FEATURES"; \
else \
cargo build --release --locked --features "$CARGO_FEATURES"; \
fi; \
else \
if [ "$CARGO_NO_DEFAULT_FEATURES" = "true" ]; then \
cargo build --release --locked --no-default-features; \
else \
cargo build --release --locked; \
fi; \
fi
# Stage 2: Runtime
#
# NOTE: We keep the runtime distro aligned with the build environment's glibc.
# CI runners and upstream base images now commonly require GLIBC_2.38+, which
# Debian bookworm does not provide. Debian trixie includes GLIBC_2.38.
# Digest-pinned (see note on the tailwind-build stage above).
FROM debian:trixie-slim@sha256:28de0877c2189802884ccd20f15ee41c203573bd87bb6b883f5f46362d24c5c2
WORKDIR /app
# Install runtime dependencies
RUN apt-get update && apt-get install -y \
ca-certificates \
libssl3 \
adduser \
&& rm -rf /var/lib/apt/lists/*
# Copy the built binary from builder
COPY --from=builder /app/target/release/rust_oauth2_server /app/rust_oauth2_server
# Backwards-compatibility: keep the old path if anything still references it
RUN ln -sf /app/rust_oauth2_server /app/oauth2_server
# Copy templates and static files
COPY templates ./templates
COPY static ./static
# Replace the dev-placeholder admin.css with the compiled Tailwind output
COPY --from=tailwind-build /tw/admin.min.css /app/static/css/admin.css
# Create directory for database
RUN mkdir -p /app/data
# Create a non-root user for security
RUN addgroup --gid 1000 appuser \
&& adduser --disabled-password --gecos '' --uid 1000 --gid 1000 appuser \
&& chown -R appuser:appuser /app
# Expose port
EXPOSE 8080
# Set environment variables
ENV OAUTH2_SERVER_HOST=0.0.0.0
ENV OAUTH2_SERVER_PORT=8080
ENV OAUTH2_DATABASE_URL=sqlite:/app/data/oauth2.db
ENV RUST_LOG=info
# Run as non-root user
USER appuser
# Run the binary
CMD ["/app/rust_oauth2_server"]