diff --git a/.github/workflows/container_foundationdb_version.yml b/.github/workflows/container_foundationdb_version.yml new file mode 100644 index 000000000..15517b2f1 --- /dev/null +++ b/.github/workflows/container_foundationdb_version.yml @@ -0,0 +1,111 @@ +name: "docker: build foundationdb image by version" + +on: + workflow_dispatch: + inputs: + fdb_version: + description: 'FoundationDB version to build (e.g. 7.3.43)' + required: true + default: '7.3.43' + seaweedfs_ref: + description: 'SeaweedFS git tag, branch, or commit to build' + required: true + default: 'master' + image_tag: + description: 'Optional Docker tag suffix (defaults to foundationdb__seaweedfs_)' + required: false + default: '' + +permissions: + contents: read + +jobs: + build-foundationdb-image: + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v2 + + - name: Prepare Docker tag + id: tag + env: + FDB_VERSION_INPUT: ${{ inputs.fdb_version }} + SEAWEEDFS_REF_INPUT: ${{ inputs.seaweedfs_ref }} + CUSTOM_TAG_INPUT: ${{ inputs.image_tag }} + run: | + set -euo pipefail + sanitize() { + local value="$1" + value="${value,,}" + value="${value// /-}" + value="${value//[^a-z0-9_.-]/-}" + value="${value#-}" + value="${value%-}" + printf '%s' "$value" + } + version="${FDB_VERSION_INPUT}" + seaweed="${SEAWEEDFS_REF_INPUT}" + tag="${CUSTOM_TAG_INPUT}" + if [ -z "$version" ]; then + echo "FoundationDB version input is required." >&2 + exit 1 + fi + if [ -z "$seaweed" ]; then + echo "SeaweedFS ref input is required." >&2 + exit 1 + fi + sanitized_version="$(sanitize "$version")" + if [ -z "$sanitized_version" ]; then + echo "Unable to sanitize FoundationDB version '$version'." >&2 + exit 1 + fi + sanitized_seaweed="$(sanitize "$seaweed")" + if [ -z "$sanitized_seaweed" ]; then + echo "Unable to sanitize SeaweedFS ref '$seaweed'." >&2 + exit 1 + fi + if [ -z "$tag" ]; then + tag="foundationdb_${sanitized_version}_seaweedfs_${sanitized_seaweed}" + fi + tag="${tag,,}" + tag="${tag// /-}" + tag="${tag//[^a-z0-9_.-]/-}" + tag="${tag#-}" + tag="${tag%-}" + if [ -z "$tag" ]; then + echo "Resulting Docker tag is empty." >&2 + exit 1 + fi + echo "docker_tag=$tag" >> "$GITHUB_OUTPUT" + echo "full_image=chrislusf/seaweedfs:$tag" >> "$GITHUB_OUTPUT" + echo "seaweedfs_ref=$seaweed" >> "$GITHUB_OUTPUT" + + - name: Set up QEMU + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v1 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v1 + + - name: Login to Docker Hub + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v1 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and push image + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v2 + with: + context: ./docker + push: true + file: ./docker/Dockerfile.foundationdb_large + build-args: | + FDB_VERSION=${{ inputs.fdb_version }} + BRANCH=${{ inputs.seaweedfs_ref }} + platforms: linux/amd64 + tags: ${{ steps.tag.outputs.full_image }} + labels: | + org.opencontainers.image.title=seaweedfs + org.opencontainers.image.description=SeaweedFS is a distributed storage system for blobs, objects, files, and data lake, to store and serve billions of files fast! + org.opencontainers.image.vendor=Chris Lu + diff --git a/.github/workflows/container_release_foundationdb.yml b/.github/workflows/container_release_foundationdb.yml new file mode 100644 index 000000000..5be990b4c --- /dev/null +++ b/.github/workflows/container_release_foundationdb.yml @@ -0,0 +1,61 @@ +name: "docker: build release containers for foundationdb" + +on: + push: + tags: + - '*' + workflow_dispatch: {} + +permissions: + contents: read + +jobs: + + build-large-release-container_foundationdb: + runs-on: [ubuntu-latest] + + steps: + - + name: Checkout + uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v2 + - + name: Docker meta + id: docker_meta + uses: docker/metadata-action@c1e51972afc2121e065aed6d45c65596fe445f3f # v3 + with: + images: | + chrislusf/seaweedfs + tags: | + type=ref,event=tag,suffix=_large_disk_foundationdb + flavor: | + latest=false + labels: | + org.opencontainers.image.title=seaweedfs + org.opencontainers.image.description=SeaweedFS is a distributed storage system for blobs, objects, files, and data lake, to store and serve billions of files fast! + org.opencontainers.image.vendor=Chris Lu + - + name: Set up QEMU + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v1 + - + name: Set up Docker Buildx + uses: docker/setup-buildx-action@e468171a9de216ec08956ac3ada2f0791b6bd435 # v1 + - + name: Login to Docker Hub + if: github.event_name != 'pull_request' + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # v1 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + - + name: Build + uses: docker/build-push-action@263435318d21b8e681c14492fe198d362a7d2c83 # v2 + with: + context: ./docker + push: ${{ github.event_name != 'pull_request' }} + file: ./docker/Dockerfile.foundationdb_large + build-args: | + BRANCH=${{ github.sha }} + platforms: linux/amd64 + tags: ${{ steps.docker_meta.outputs.tags }} + labels: ${{ steps.docker_meta.outputs.labels }} + diff --git a/docker/Dockerfile.foundationdb_large b/docker/Dockerfile.foundationdb_large new file mode 100644 index 000000000..daa8a453b --- /dev/null +++ b/docker/Dockerfile.foundationdb_large @@ -0,0 +1,77 @@ +FROM golang:1.24 AS builder + +RUN apt-get update +RUN apt-get install -y build-essential wget + +ARG FDB_VERSION=7.3.43 +ENV FDB_VERSION=${FDB_VERSION} + +# Install FoundationDB client libraries +RUN cd /tmp && \ + wget https://github.com/apple/foundationdb/releases/download/${FDB_VERSION}/foundationdb-clients_${FDB_VERSION}-1_amd64.deb && \ + dpkg -i foundationdb-clients_${FDB_VERSION}-1_amd64.deb && \ + rm foundationdb-clients_${FDB_VERSION}-1_amd64.deb + +# Set up FoundationDB environment variables for CGO +ENV CGO_CFLAGS="-I/usr/include/foundationdb" +ENV CGO_LDFLAGS="-lfdb_c" + +# build SeaweedFS +RUN mkdir -p /go/src/github.com/seaweedfs/ +RUN git clone https://github.com/seaweedfs/seaweedfs /go/src/github.com/seaweedfs/seaweedfs +ARG BRANCH=master +RUN cd /go/src/github.com/seaweedfs/seaweedfs && git checkout $BRANCH +RUN cd /go/src/github.com/seaweedfs/seaweedfs/weed \ + && export LDFLAGS="-X github.com/seaweedfs/seaweedfs/weed/util/version.COMMIT=$(git rev-parse --short HEAD)" \ + && go install -tags "5BytesOffset foundationdb" -ldflags "${LDFLAGS}" + + +FROM alpine AS final +LABEL author="Chris Lu" +COPY --from=builder /go/bin/weed /usr/bin/ +RUN mkdir -p /etc/seaweedfs +COPY --from=builder /go/src/github.com/seaweedfs/seaweedfs/docker/filer_foundationdb.toml /etc/seaweedfs/filer.toml +COPY --from=builder /go/src/github.com/seaweedfs/seaweedfs/docker/entrypoint.sh /entrypoint.sh + +# Install dependencies and create non-root user +# Note: FoundationDB client library needs to be installed in the runtime image +RUN apk add --no-cache fuse ca-certificates wget && \ + addgroup -g 1000 seaweed && \ + adduser -D -u 1000 -G seaweed seaweed + +# Install FoundationDB client library in Alpine +# We need to extract the .so files from the deb package +COPY --from=builder /usr/lib/libfdb_c.so /usr/lib/libfdb_c.so + +# volume server gprc port +EXPOSE 18080 +# volume server http port +EXPOSE 8080 +# filer server gprc port +EXPOSE 18888 +# filer server http port +EXPOSE 8888 +# master server shared gprc port +EXPOSE 19333 +# master server shared http port +EXPOSE 9333 +# s3 server http port +EXPOSE 8333 +# webdav server http port +EXPOSE 7333 + +# Create data directory and set proper ownership for seaweed user +RUN mkdir -p /data && \ + chown -R seaweed:seaweed /data && \ + chown -R seaweed:seaweed /etc/seaweedfs && \ + chmod 755 /entrypoint.sh + +VOLUME /data + +WORKDIR /data + +# Switch to non-root user +USER seaweed + +ENTRYPOINT ["/entrypoint.sh"] + diff --git a/docker/filer_foundationdb.toml b/docker/filer_foundationdb.toml new file mode 100644 index 000000000..c7a7e3d28 --- /dev/null +++ b/docker/filer_foundationdb.toml @@ -0,0 +1,19 @@ +[filer.options] +# with http DELETE, by default the filer would check whether a folder is empty. +# recursive_delete will delete all sub folders and files, similar to "rm -Rf" +recursive_delete = false + +#################################################### +# FoundationDB store +#################################################### +[foundationdb] +enabled = true +cluster_file = "/etc/foundationdb/fdb.cluster" +api_version = 730 +# Optional: timeout for FDB operations (default: 10s) +# timeout = "10s" +# Optional: max retry delay for retryable errors (default: 1s) +# max_retry_delay = "1s" +# Optional: directory prefix for storing SeaweedFS data (default: "seaweedfs") +# directory_prefix = "seaweedfs" +