-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
129 lines (113 loc) · 6.11 KB
/
Copy pathDockerfile
File metadata and controls
129 lines (113 loc) · 6.11 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
# syntax=docker/dockerfile:1.7
#
# OpenProxy — single-binary Docker image
#
# Three-stage build:
# 1. web — pnpm install + astro build → web/dist/
# 2. rust — cargo build --release with embedded web/dist via rust-embed
# 3. runtime — debian:bookworm-slim + the binary + ca-certificates
#
# Final image is ~80 MB (debian-slim base + the openproxy binary, which
# already contains the dashboard via rust-embed).
#
# Build: docker build -t openproxy .
# Run: docker run -d --name openproxy -p 4623:4623 \
# -v openproxy-data:/app/data \
# -e TRUST_PROXY=false \
# openproxy
#
# ──────────────────────────────────────────────────────────────────────────
# Reverse-proxy deployment notes
# ──────────────────────────────────────────────────────────────────────────
#
# When deploying OpenProxy behind nginx, Caddy, Traefik, or another
# reverse proxy, set TRUST_PROXY=true so that upstream forwarding headers
# (X-Forwarded-For, X-Real-IP, etc.) are read from the proxy rather than
# stripped. Without TRUST_PROXY=true, reverse-proxy clients connecting
# from 127.0.0.1 (localhost) also bypass auth — set requireLogin=on in the
# dashboard settings or configure auth at the reverse-proxy layer.
#
# Examples:
#
# nginx (location /):
# proxy_pass http://127.0.0.1:4623;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Forwarded-Proto $scheme;
# proxy_set_header Host $host;
#
# Caddy (reverse_proxy):
# reverse_proxy 127.0.0.1:4623
#
# Traefik:
# - "traefik.http.services.openproxy.loadbalancer.server.port=4623"
#
# CORS: the embedded Axum server already sets permissive
# Access-Control-Allow-Origin:* headers on all API responses. When the
# dashboard and API live behind the same reverse-proxy origin, no
# additional CORS configuration is needed. If they are served from
# different origins, adjust CORS headers in the reverse proxy.
#
# ──────────────────────────────────────────────────────────────────────────
# Stage 1: build the dashboard
# ──────────────────────────────────────────────────────────────────────────
FROM node:20-bookworm-slim AS web
WORKDIR /web
# pnpm via corepack — version pinned to match web/package.json packageManager
RUN corepack enable && corepack prepare pnpm@10.33.2 --activate
# Copy the lockfile + manifest first so the install layer caches when the
# rest of web/ changes but dependencies don't.
COPY web/package.json web/pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
# Copy the rest and build.
COPY web/ ./
RUN pnpm run build
# → /web/dist/
# ──────────────────────────────────────────────────────────────────────────
# Stage 2: build the binary with the embedded dashboard
# ──────────────────────────────────────────────────────────────────────────
FROM rust:1-bookworm AS rust
WORKDIR /src
# Install build deps for crates that need them at compile time.
# rusqlite/bundled handles its own SQLite. reqwest/rustls handles its own TLS.
# We only need pkg-config and a working linker, both already in rust:bookworm.
# (apt update kept minimal.)
RUN apt-get update \
&& apt-get install -y --no-install-recommends pkg-config \
&& rm -rf /var/lib/apt/lists/*
# Copy the workspace. Cargo.lock + manifests first for layer caching, then
# the source tree, then the embedded dashboard from stage 1.
COPY Cargo.toml Cargo.lock build.rs ./
COPY src/ ./src/
# rust-embed reads web/dist/ at compile time; src/server/api/mod.rs also
# include_str!s web/package.json. Both must exist before `cargo build`.
COPY --from=web /web/dist/ ./web/dist/
COPY --from=web /web/package.json ./web/package.json
# Build with the default `embed-web` feature on. build.rs verifies
# web/dist/index.html exists before invoking rust-embed.
RUN cargo build --release --locked --bin openproxy
RUN strip /src/target/release/openproxy
# ──────────────────────────────────────────────────────────────────────────
# Stage 3: minimal runtime
# ──────────────────────────────────────────────────────────────────────────
FROM debian:bookworm-slim AS runtime
# ca-certificates: required for outbound HTTPS to provider APIs.
# tini: clean signal handling for ctrl+c / SIGTERM in the container.
# curl: required for HEALTHCHECK probe.
RUN apt-get update \
&& apt-get install -y --no-install-recommends ca-certificates tini curl \
&& rm -rf /var/lib/apt/lists/*
COPY --from=rust /src/target/release/openproxy /usr/local/bin/openproxy
# Container-friendly defaults: bind 0.0.0.0 (so port-forward works) and
# keep state under /app/data which is mounted as a volume.
ENV HOSTNAME=0.0.0.0 \
PORT=4623 \
DATA_DIR=/app/data
WORKDIR /app
VOLUME ["/app/data"]
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD curl -f http://localhost:4623/health || exit 1
EXPOSE 4623
# tini reaps zombies and forwards signals; --no-open avoids any browser
# launch attempt inside the container.
ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/bin/openproxy"]
CMD ["--no-open"]