-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDockerfile
More file actions
118 lines (104 loc) · 5.7 KB
/
Dockerfile
File metadata and controls
118 lines (104 loc) · 5.7 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
# NetCopy container image.
#
# We deliberately do NOT rebuild the jar inside the image: the release.yml
# workflow stages the shaded jar with a versioned filename and passes its
# path as a build-arg. Rebuilding here would either duplicate the maven run
# or split the image away from the published jar.
#
# Local "docker build .": pass --build-arg JAR_FILE=target/netcopy.jar
# CI: passes release/netcopy-<version>.jar.
ARG JAR_FILE=target/netcopy.jar
ARG VERSION=dev
# ---- Stage 1: pull a static gosu binary --------------------------------
# UBI 10 minimal doesn't ship curl/wget by default and getting gosu from
# microdnf is awkward; alpine + apk add curl is the smallest path. We just
# COPY --from this layer; the alpine layer doesn't ship in the final image.
#
# Base image SHA-pinned: locking the digest decouples our build from any
# upstream re-tag of `alpine:3.20`. Bump deliberately on each NetCopy
# release; the version comment after `@sha256:...` is what gets searched.
FROM alpine:3.20@sha256:d9e853e87e55526f6b2917df91a2115c36dd7c696a35be12163d44e6e2a4b6bc AS gosu-stage
ARG GOSU_VERSION=1.17
# Per-arch SHA-256 of the gosu binary, pulled from
# https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/SHA256SUMS .
# Pinning the binary itself (not just the version tag) closes the
# "compromised GitHub release / MITM" supply-chain hole.
ARG GOSU_SHA256_AMD64=bbc4136d03ab138b1ad66fa4fc051bafc6cc7ffae632b069a53657279a450de3
ARG GOSU_SHA256_ARM64=c3805a85d17f4454c23d7059bcb97e1ec1af272b90126e79ed002342de08389b
RUN set -eux; \
apk add --no-cache curl; \
case "$(uname -m)" in \
x86_64) gosuArch=amd64; gosuSha="${GOSU_SHA256_AMD64}" ;; \
aarch64) gosuArch=arm64; gosuSha="${GOSU_SHA256_ARM64}" ;; \
*) echo "unsupported arch $(uname -m)"; exit 1 ;; \
esac; \
curl -fsSL "https://github.com/tianon/gosu/releases/download/${GOSU_VERSION}/gosu-${gosuArch}" \
-o /tmp/gosu; \
echo "${gosuSha} /tmp/gosu" | sha256sum -c -; \
chmod +x /tmp/gosu; \
/tmp/gosu --version
# ---- Stage 2: runtime --------------------------------------------------
FROM eclipse-temurin:25-jre-ubi10-minimal@sha256:c897ce903faf6736e4b5cbb2dd5e05e6b74909d71105f3cfe33840b3ce7b8b21 AS runtime
# OCI labels filled in further by the workflow's --label flags.
LABEL org.opencontainers.image.title="NetCopy"
LABEL org.opencontainers.image.description="Fast multi-stream file transfer between two trusted hosts in a LAN."
LABEL org.opencontainers.image.source="https://github.com/VirusAlex/NetCopy"
LABEL org.opencontainers.image.licenses="Apache-2.0"
# curl is needed for the HEALTHCHECK (UBI 10 minimal doesn't ship it). Cheap
# install — adds ~6 MiB to the final image. Combined into the gosu COPY block
# below so we keep the layer count down.
RUN microdnf install -y --setopt=install_weak_deps=0 --nodocs curl-minimal \
&& microdnf clean all \
&& rm -rf /var/cache/yum
# gosu lets the entrypoint chown the state dir as root and then drop privileges
# to PUID:PGID before running java. See entrypoint.sh for the rationale.
COPY --from=gosu-stage /tmp/gosu /usr/local/bin/gosu
# Conventional mount points. We DO NOT bake any non-root ownership into them
# any more: the entrypoint chowns /var/lib/netcopy at start-up to whatever
# PUID:PGID the user picks (default 10001:10001 for backward compat with
# pre-v0.2.7 images). /share and /incoming aren't touched — they're user
# data and recursive chown there would be wrong + slow on large datasets.
RUN mkdir -p /var/lib/netcopy /share /incoming /opt/netcopy
# Re-declare ARGs after FROM so the COPY below sees them.
ARG JAR_FILE
ARG VERSION
# Jar lands at a stable in-image path so the ENTRYPOINT does not depend on
# the version string.
COPY ${JAR_FILE} /opt/netcopy/netcopy.jar
COPY entrypoint.sh /usr/local/bin/entrypoint.sh
RUN chmod +x /usr/local/bin/entrypoint.sh
ENV NETCOPY_VERSION=${VERSION}
ENV JAVA_TOOL_OPTIONS=""
# Default uid/gid the entrypoint drops to. Override at runtime:
# docker run -e PUID=$(id -u) -e PGID=$(id -g) ...
# Bare numeric ids — no /etc/passwd entry needed (UBI minimal lacks shadow-utils).
ENV PUID=10001
ENV PGID=10001
# No USER directive — entrypoint starts as root, chowns the state dir, then
# drops privileges to PUID:PGID via gosu. To skip that and run as a specific
# uid/gid throughout, pass `docker run --user <uid>:<gid> ...`; the entrypoint
# detects "I'm not root" and just execs java directly.
WORKDIR /var/lib/netcopy
# 7777 control plane (HTTP + WS), 7778 binary TCP data plane.
EXPOSE 7777 7778
# Healthcheck against the unauthenticated /api/health endpoint. Defaults are
# conservative — JVM cold-start on a slow VM can take ~10 s, so allow 30 s
# start-period before the first failed probe counts. After that, probe every
# 30 s; mark unhealthy after 3 consecutive failures.
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
CMD curl -fsS http://127.0.0.1:7777/api/health > /dev/null || exit 1
# Conventional volume mount points; override with -v on `docker run`.
# -v /host/share:/share:ro -> mounted as a --shared-root
# -v /host/incoming:/incoming -> mounted as a --receive-root
# -v /host/state:/var/lib/netcopy -> persists jobs/<id>.json across restarts
VOLUME ["/share", "/incoming", "/var/lib/netcopy"]
# Sensible defaults so `docker run -p 7777:7777 -p 7778:7778 ghcr.io/.../netcopy`
# Just Works. Override / extend on the command line:
# docker run ... ghcr.io/.../netcopy --token mySecret --shared-root /share
ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
CMD ["--bind", "0.0.0.0", \
"--port", "7777", \
"--tcp-port", "7778", \
"--shared-root", "/share", \
"--receive-root", "/incoming", \
"--state-dir", "/var/lib/netcopy"]