diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..5c1d460 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,8 @@ +.git +.github +target +rustpost-data +queue-demo +*.tar.gz +*.zip +*.sha256 diff --git a/.github/workflows/container.yml b/.github/workflows/container.yml new file mode 100644 index 0000000..0c818b2 --- /dev/null +++ b/.github/workflows/container.yml @@ -0,0 +1,61 @@ +name: Container + +on: + workflow_dispatch: + +permissions: + contents: read + packages: write + +jobs: + build: + name: Build ${{ matrix.arch }} + strategy: + fail-fast: false + matrix: + include: + - arch: amd64 + runner: ubuntu-24.04 + - arch: arm64 + runner: ubuntu-24.04-arm + runs-on: ${{ matrix.runner }} + steps: + - uses: actions/checkout@v4 + - name: Verify v1.0.0 application source + run: | + git fetch --depth=1 origin tag v1.0.0 + git diff --quiet v1.0.0 -- Cargo.toml Cargo.lock src + - uses: docker/setup-buildx-action@v3 + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - uses: docker/build-push-action@v6 + with: + context: . + platforms: linux/${{ matrix.arch }} + push: true + tags: ghcr.io/csd113/rustpost:1.0.0-${{ matrix.arch }} + provenance: false + + publish: + name: Publish version and latest + needs: build + runs-on: ubuntu-24.04 + steps: + - uses: docker/setup-buildx-action@v3 + - uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Create multi-platform tags + run: | + docker buildx imagetools create \ + --tag ghcr.io/csd113/rustpost:1.0.0 \ + --tag ghcr.io/csd113/rustpost:latest \ + ghcr.io/csd113/rustpost:1.0.0-amd64 \ + ghcr.io/csd113/rustpost:1.0.0-arm64 + - name: Inspect published image + run: docker buildx imagetools inspect ghcr.io/csd113/rustpost:1.0.0 diff --git a/CHANGELOG.md b/CHANGELOG.md index 63edd7c..d0e0b99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## v1.0.0 - First Release +- Published a Linux amd64/arm64 container image as `ghcr.io/csd113/rustpost:1.0.0` and `ghcr.io/csd113/rustpost:latest`, with persistent state under `/data` and bundled `ffmpeg`. + ### Instance and social controls - Protected accounts: users can require approval before someone follows them. Requests are pending until approved, never count as followers, can be rejected or cancelled, and are cleared by blocks. - Instance announcements: administrators can publish, disable, or clear an announcement rendered next to the site name in the top bar. diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b5852ae --- /dev/null +++ b/Dockerfile @@ -0,0 +1,29 @@ +FROM rust:1.91-bookworm AS build + +WORKDIR /usr/src/rustpost +COPY Cargo.toml Cargo.lock ./ +COPY src ./src +RUN cargo build --release --locked --bin rustpost-cli + +FROM debian:bookworm-slim + +RUN apt-get update \ + && apt-get install -y --no-install-recommends ca-certificates ffmpeg \ + && rm -rf /var/lib/apt/lists/* \ + && groupadd --gid 10001 rustpost \ + && useradd --uid 10001 --gid rustpost --home-dir /data --no-create-home rustpost \ + && mkdir /data \ + && chown rustpost:rustpost /data + +COPY --from=build /usr/src/rustpost/target/release/rustpost-cli /usr/local/bin/rustpost-cli +COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh + +LABEL org.opencontainers.image.source="https://github.com/csd113/RustPost" \ + org.opencontainers.image.title="RustPost" \ + org.opencontainers.image.version="1.0.0" + +USER rustpost +VOLUME /data +EXPOSE 8080 +ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"] +CMD ["serve"] diff --git a/README.md b/README.md index f21bdc2..30993d0 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,21 @@ rustpost-cli --version Use an explicit `--data-dir` for installed deployments. Without it, RustPost places `rustpost-data` beside the executable. +### Run the container + +The multi-platform image is published at `ghcr.io/csd113/rustpost:1.0.0` for Linux amd64 and arm64. `ghcr.io/csd113/rustpost:latest` points to the same release. The image includes `ffmpeg` and runs as UID/GID `10001`. + +```sh +docker volume create rustpost-data +docker run -d --name rustpost \ + -p 127.0.0.1:8080:8080 \ + -v rustpost-data:/data \ + ghcr.io/csd113/rustpost:1.0.0 +docker exec -it rustpost rustpost-cli --data-dir /data create-admin-interactive +``` + +Open `http://127.0.0.1:8080`. The container stores settings, SQLite, uploads, backups, and Tor state in `/data`. On the first boot only, it creates `settings.toml` with `server.host = "0.0.0.0"` so Docker can forward port 8080. Existing settings are preserved; if you mount an existing data directory, set `server.host` to `0.0.0.0` yourself. For a bind mount, make the directory writable by UID/GID `10001`. Keep the published port bound to loopback unless you have configured a reverse proxy and appropriate public access settings. + ### First Run ```sh diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 0000000..29fad58 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/sh +set -eu + +if [ ! -e /data/settings.toml ]; then + rustpost-cli --data-dir /data init >/dev/null + sed -i 's/^host = "127\.0\.0\.1"$/host = "0.0.0.0"/' /data/settings.toml +fi + +exec rustpost-cli --data-dir /data "$@"