Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ on:

env:
CARGO_TERM_COLOR: always
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
TAG_NAME: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}

jobs:
Expand Down Expand Up @@ -421,3 +423,47 @@ jobs:
artifacts/*.deb
artifacts/*.rpm
gst-pop-*-source.tar.gz

docker:
name: Docker multi-arch image
needs: [release]
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
steps:
- uses: actions/checkout@v4
with:
ref: ${{ env.TAG_NAME }}

- name: Set up QEMU
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}

- name: Extract version from tag
id: version
run: echo "version=${TAG_NAME#v}" >> "$GITHUB_OUTPUT"

- name: Build and push
uses: docker/build-push-action@v6
with:
context: docker/
file: docker/Dockerfile
platforms: linux/amd64,linux/arm64
push: true
build-args: |
GST_POP_VERSION=${{ steps.version.outputs.version }}
tags: |
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}
${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
cache-from: type=gha
cache-to: type=gha,mode=max
38 changes: 38 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,44 @@ git push origin v0.2.0

This triggers the Release workflow which builds binaries for Linux, Windows, and macOS, creates `.deb` and `.rpm` packages, and publishes a GitHub Release with all artifacts.

### Docker

A multi-arch Docker image (amd64 + arm64) based on Fedora with all GStreamer plugins is published to GitHub Container Registry on each release.

#### Pull and run

```bash
docker pull ghcr.io/dabrain34/gstpop:latest

docker run -d -p 9000:9000 --name gst-pop ghcr.io/dabrain34/gstpop:latest
```

The daemon listens on port 9000 (WebSocket).

#### With docker compose

```bash
cd docker
docker compose up -d
```

#### Configuration

Pass environment variables to configure the daemon:

```bash
docker run -d -p 9000:9000 \
-e GSTPOP_API_KEY=mysecretkey \
-e RUST_LOG=gst_pop=debug \
--name gst-pop ghcr.io/dabrain34/gstpop:latest
```

#### Verify

```bash
docker exec gst-pop gst-pop-inspect | wc -l
```

### Security Considerations

#### Pipeline Descriptions
Expand Down
108 changes: 108 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Multi-arch Dockerfile for gst-pop
# Supports linux/amd64 (prebuilt binary) and linux/arm64 (built from source)
#
# Build:
# docker buildx build --platform linux/amd64,linux/arm64 -t gst-pop .
#
# Run:
# docker run -d -p 9000:9000 --name gst-pop gst-pop

# ============================================================
# Stage 1: Builder - fetch or compile gst-pop binaries
# ============================================================
FROM fedora:42 AS builder

ARG TARGETARCH
ARG GST_POP_VERSION=0.4.2

RUN dnf install -y curl && dnf clean all

# --- amd64: download prebuilt binaries from GitHub release ---
RUN if [ "$TARGETARCH" = "amd64" ]; then \
dnf install -y unzip && dnf clean all \
&& curl -fsSL \
"https://github.com/dabrain34/gstpop/releases/download/v${GST_POP_VERSION}/gst-pop-v${GST_POP_VERSION}-linux-x86_64.zip" \
-o /tmp/gst-pop.zip \
&& mkdir -p /tmp/staging \
&& unzip /tmp/gst-pop.zip -d /tmp/staging \
&& rm /tmp/gst-pop.zip; \
fi

# --- arm64: build from source tarball ---
RUN if [ "$TARGETARCH" = "arm64" ]; then \
dnf install -y \
gcc \
gstreamer1-devel \
gstreamer1-plugins-base-devel \
rust \
cargo \
tar \
gzip \
&& dnf clean all \
&& curl -fsSL \
"https://github.com/dabrain34/gstpop/releases/download/v${GST_POP_VERSION}/gst-pop-v${GST_POP_VERSION}-source.tar.gz" \
-o /tmp/source.tar.gz \
&& mkdir -p /tmp/gst-pop-src \
&& tar -xzf /tmp/source.tar.gz -C /tmp/gst-pop-src --strip-components=1 \
&& cd /tmp/gst-pop-src \
&& cargo build --release --workspace \
&& mkdir -p /tmp/staging \
&& cp target/release/gst-pop /tmp/staging/ \
&& cp target/release/gst-popctl /tmp/staging/ \
&& rm -rf /tmp/gst-pop-src /tmp/source.tar.gz; \
fi

# Fail early if the architecture produced no binaries
RUN test -f /tmp/staging/gst-pop || \
(echo "ERROR: Unsupported architecture: ${TARGETARCH}" && exit 1)

# ============================================================
# Stage 2: Runtime image with GStreamer
# ============================================================
FROM fedora:42

ARG GST_POP_VERSION=0.4.2

LABEL maintainer="Stephane Cerveau <scerveau@igalia.com>"
LABEL description="gst-pop v${GST_POP_VERSION} - GStreamer pipeline management daemon"
LABEL version="${GST_POP_VERSION}"

# --- Install GStreamer with maximum plugin coverage ---
RUN dnf -y install \
gstreamer1 \
gstreamer1-plugins-base \
gstreamer1-plugins-base-tools \
gstreamer1-plugins-good \
gstreamer1-plugins-good-extras \
gstreamer1-plugins-bad-free \
gstreamer1-plugins-bad-free-extras \
gstreamer1-plugins-ugly-free \
gstreamer1-plugin-libav \
gstreamer1-plugin-openh264 \
gstreamer1-vaapi \
bash \
&& dnf clean all

# --- Install gst-pop binaries from builder stage ---
COPY --from=builder --chmod=755 /tmp/staging/gst-pop /usr/bin/gst-pop
COPY --from=builder --chmod=755 /tmp/staging/gst-popctl /usr/bin/gst-popctl

# --- Create busybox-style symlinks ---
RUN ln -sf gst-pop /usr/bin/gst-popd && \
ln -sf gst-pop /usr/bin/gst-pop-launch && \
ln -sf gst-pop /usr/bin/gst-pop-inspect && \
ln -sf gst-pop /usr/bin/gst-pop-discover && \
ln -sf gst-pop /usr/bin/gst-pop-play

# --- Create non-root user ---
RUN useradd -r -s /sbin/nologin -d /nonexistent gstpop

USER gstpop

EXPOSE 9000

HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD bash -c '</dev/tcp/localhost/9000' || exit 1

ENTRYPOINT ["/usr/bin/gst-popd"]
CMD ["--bind", "0.0.0.0", "--no-dbus"]
13 changes: 13 additions & 0 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
services:
gst-pop:
image: ghcr.io/dabrain34/gstpop:${GST_POP_VERSION:-latest}
build:
context: .
dockerfile: Dockerfile
container_name: gst-pop
ports:
- "9000:9000"
environment:
- GSTPOP_API_KEY=${GSTPOP_API_KEY:-}
- RUST_LOG=${RUST_LOG:-gst_pop=info}
restart: unless-stopped
Loading