/ Dockerfile
Dockerfile
1 # syntax=docker/dockerfile:1 2 # Enables BuildKit with cache mounts for faster builds 3 FROM --platform=${BUILDPLATFORM:-linux/amd64} golang:1.25 AS builder 4 5 ARG TARGETOS TARGETARCH 6 7 ENV SRC_DIR=/kubo 8 9 # Cache go module downloads between builds for faster rebuilds 10 COPY go.mod go.sum $SRC_DIR/ 11 WORKDIR $SRC_DIR 12 RUN --mount=type=cache,target=/go/pkg/mod \ 13 go mod download 14 15 COPY . $SRC_DIR 16 17 # Preload an in-tree but disabled-by-default plugin by adding it to the IPFS_PLUGINS variable 18 # e.g. docker build --build-arg IPFS_PLUGINS="foo bar baz" 19 ARG IPFS_PLUGINS 20 21 # Allow for other targets to be built, e.g.: docker build --build-arg MAKE_TARGET="nofuse" 22 ARG MAKE_TARGET=build 23 24 # Build ipfs binary with cached go modules and build cache. 25 # mkdir .git/objects allows git rev-parse to read commit hash for version info 26 RUN --mount=type=cache,target=/go/pkg/mod \ 27 --mount=type=cache,target=/root/.cache/go-build \ 28 mkdir -p .git/objects \ 29 && GOOS=$TARGETOS GOARCH=$TARGETARCH GOFLAGS=-buildvcs=false make ${MAKE_TARGET} IPFS_PLUGINS=$IPFS_PLUGINS 30 31 # Extract required runtime tools from Debian. 32 # We use Debian instead of Alpine because we need glibc compatibility 33 # for the busybox base image we're using. 34 FROM debian:bookworm-slim AS utilities 35 RUN set -eux; \ 36 apt-get update; \ 37 apt-get install -y --no-install-recommends \ 38 tini \ 39 # Using gosu (~2MB) instead of su-exec (~20KB) because it's easier to 40 # install on Debian. Useful links: 41 # - https://github.com/ncopa/su-exec#why-reinvent-gosu 42 # - https://github.com/tianon/gosu/issues/52#issuecomment-441946745 43 gosu \ 44 # fusermount enables IPFS mount commands 45 fuse \ 46 ca-certificates \ 47 ; \ 48 apt-get clean; \ 49 rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 50 51 # Final minimal image with shell for debugging (busybox provides sh) 52 FROM busybox:stable-glibc 53 54 # Copy ipfs binary, startup scripts, and runtime dependencies 55 ENV SRC_DIR=/kubo 56 COPY --from=utilities /usr/sbin/gosu /sbin/gosu 57 COPY --from=utilities /usr/bin/tini /sbin/tini 58 COPY --from=utilities /bin/fusermount /usr/local/bin/fusermount 59 COPY --from=utilities /etc/ssl/certs /etc/ssl/certs 60 COPY --from=builder $SRC_DIR/cmd/ipfs/ipfs /usr/local/bin/ipfs 61 COPY --from=builder --chmod=755 $SRC_DIR/bin/container_daemon /usr/local/bin/start_ipfs 62 COPY --from=builder $SRC_DIR/bin/container_init_run /usr/local/bin/container_init_run 63 64 # Set SUID for fusermount to enable FUSE mounting by non-root user 65 RUN chmod 4755 /usr/local/bin/fusermount 66 67 # Swarm P2P port (TCP/UDP) - expose publicly for peer connections 68 EXPOSE 4001 4001/udp 69 # API port - keep private, only for trusted clients 70 EXPOSE 5001 71 # Gateway port - can be exposed publicly via reverse proxy 72 EXPOSE 8080 73 # Swarm WebSockets - expose publicly for browser-based peers 74 EXPOSE 8081 75 76 # Create ipfs user (uid 1000) and required directories with proper ownership 77 ENV IPFS_PATH=/data/ipfs 78 RUN mkdir -p $IPFS_PATH /ipfs /ipns /mfs /container-init.d \ 79 && adduser -D -h $IPFS_PATH -u 1000 -G users ipfs \ 80 && chown ipfs:users $IPFS_PATH /ipfs /ipns /mfs /container-init.d 81 82 # Volume for IPFS repository data persistence 83 VOLUME $IPFS_PATH 84 85 # The default logging level 86 ENV GOLOG_LOG_LEVEL="" 87 88 # Entrypoint initializes IPFS repo if needed and configures networking. 89 # tini ensures proper signal handling and zombie process cleanup 90 ENTRYPOINT ["/sbin/tini", "--", "/usr/local/bin/start_ipfs"] 91 92 # Health check verifies IPFS daemon is responsive. 93 # Uses empty directory CID (QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn) as test 94 HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \ 95 CMD ipfs --api=/ip4/127.0.0.1/tcp/5001 dag stat /ipfs/QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn || exit 1 96 97 # Default: run IPFS daemon with auto-migration enabled 98 CMD ["daemon", "--migrate=true", "--agent-version-suffix=docker"]