mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-07-25 12:01:04 +02:00
fix: fix ffmpeg download url
This commit is contained in:
parent
e3edc3491d
commit
225f369cba
3 changed files with 103 additions and 48 deletions
|
|
@ -59,56 +59,53 @@ RUN npm ci --omit=dev && npm cache clean --force
|
|||
# Stage 3: Static ffmpeg binary (avoids apt ffmpeg pulling mesa/libllvm for
|
||||
# hardware acceleration we don't use server-side).
|
||||
#
|
||||
# Resilient download: johnvansickle.com is the primary source but it's a single
|
||||
# self-hosted host with no CDN and goes down intermittently. Use bounded-timeout
|
||||
# retries, then fall back to a pinned BtbN/FFmpeg-Builds autobuild. Every archive
|
||||
# is SHA256-verified before extraction. The two sources have different internal
|
||||
# layouts, so locate the binaries with `find` rather than a fixed strip path.
|
||||
# Source: BtbN/FFmpeg-Builds, served from GitHub's release-assets CDN (fast,
|
||||
# highly available, multi-arch). We pin a specific build for reproducibility,
|
||||
# but to a *month-end* autobuild tag — not a daily one. BtbN prunes daily
|
||||
# autobuilds after ~2 weeks (the previous pin was a daily tag and started
|
||||
# 404ing once GC'd), but keeps one month-end snapshot per month long-term
|
||||
# (~2 years back). A dated tag's assets are immutable, so the per-arch sha256
|
||||
# below never rots: builds stay reproducible AND integrity-verified.
|
||||
#
|
||||
# To upgrade ffmpeg: bump BTBN_TAG + BTBN_REV to a newer month-end autobuild
|
||||
# and refresh the two sha256s. No download needed — read tag, revision and
|
||||
# per-asset sha256 straight from the GitHub release-asset metadata:
|
||||
# gh api repos/BtbN/FFmpeg-Builds/releases/tags/<tag> \
|
||||
# --jq '.assets[] | select(.name|test("(linux64|linuxarm64)-gpl\\.tar\\.xz$")) | "\(.name) \(.digest)"'
|
||||
#
|
||||
# `--speed-limit/--speed-time` aborts a *stalled* transfer after 30s of <1KB/s
|
||||
# (the cause of "stuck" builds) without killing a slow-but-progressing
|
||||
# download; `--max-time` is a hard backstop; `--retry` rides out transient CDN
|
||||
# hiccups. The archive nests binaries under bin/, so locate them with `find`.
|
||||
FROM debian:trixie-slim AS ffmpeg-static
|
||||
ARG TARGETARCH
|
||||
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl ca-certificates xz-utils \
|
||||
&& rm -rf /var/lib/apt/lists/* \
|
||||
&& case "${TARGETARCH}" in \
|
||||
amd64) \
|
||||
primary_url="https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz" ; \
|
||||
primary_sha256="abda8d77ce8309141f83ab8edf0596834087c52467f6badf376a6a2a4c87cf67" ; \
|
||||
fallback_url="https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2026-05-30-13-19/ffmpeg-N-124681-gb8c5376eb4-linux64-gpl.tar.xz" ; \
|
||||
fallback_sha256="6cfd689ee95ff128e89080af10c93f16e48760eb2acc124c5c8258dc922cc13b" ; \
|
||||
;; \
|
||||
arm64) \
|
||||
primary_url="https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-arm64-static.tar.xz" ; \
|
||||
primary_sha256="f4149bb2b0784e30e99bdda85471c9b5930d3402014e934a5098b41d0f7201b1" ; \
|
||||
fallback_url="https://github.com/BtbN/FFmpeg-Builds/releases/download/autobuild-2026-05-30-13-19/ffmpeg-N-124681-gb8c5376eb4-linuxarm64-gpl.tar.xz" ; \
|
||||
fallback_sha256="b90a31f1d0b030f5d8a3d11cfec736e369bd5a1371b19bf65421a07f72b1d547" ; \
|
||||
;; \
|
||||
*) echo "unsupported TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;; \
|
||||
esac \
|
||||
&& mkdir -p /tmp/ffmpeg \
|
||||
&& ok= \
|
||||
&& for source in \
|
||||
"primary ${primary_sha256} ${primary_url}" \
|
||||
"fallback ${fallback_sha256} ${fallback_url}" ; do \
|
||||
source_name="${source%% *}" ; \
|
||||
source_data="${source#* }" ; \
|
||||
sha256="${source_data%% *}" ; \
|
||||
url="${source_data#* }" ; \
|
||||
echo "Downloading ffmpeg (${source_name}) from ${url}" ; \
|
||||
if curl -fsSL --connect-timeout 20 --max-time 300 \
|
||||
--retry 3 --retry-delay 5 --retry-all-errors \
|
||||
-o /tmp/ffmpeg.tar.xz "${url}" \
|
||||
&& echo "${sha256} /tmp/ffmpeg.tar.xz" | sha256sum -c - ; then ok=1 ; break ; fi ; \
|
||||
rm -f /tmp/ffmpeg.tar.xz ; \
|
||||
echo "ffmpeg source failed, trying next: ${url}" >&2 ; \
|
||||
done \
|
||||
&& [ -n "${ok}" ] || { echo "all ffmpeg download sources failed" >&2 ; exit 1 ; } \
|
||||
&& tar -xJf /tmp/ffmpeg.tar.xz -C /tmp/ffmpeg \
|
||||
&& ffmpeg_bin="$(find /tmp/ffmpeg -type f -name ffmpeg | head -n1)" \
|
||||
&& ffprobe_bin="$(find /tmp/ffmpeg -type f -name ffprobe | head -n1)" \
|
||||
&& [ -n "${ffmpeg_bin}" ] && [ -n "${ffprobe_bin}" ] \
|
||||
&& mv "${ffmpeg_bin}" "${ffprobe_bin}" /usr/local/bin/ \
|
||||
&& chmod +x /usr/local/bin/ffmpeg /usr/local/bin/ffprobe \
|
||||
&& rm -rf /tmp/ffmpeg /tmp/ffmpeg.tar.xz
|
||||
ARG BTBN_TAG=autobuild-2026-05-31-13-22
|
||||
ARG BTBN_REV=N-124714-g49a77d37be
|
||||
RUN set -eu ; \
|
||||
apt-get update && apt-get install -y --no-install-recommends \
|
||||
curl ca-certificates xz-utils ; \
|
||||
rm -rf /var/lib/apt/lists/* ; \
|
||||
case "${TARGETARCH}" in \
|
||||
amd64) btbn_arch=linux64 ; \
|
||||
sha256=ee052121296e6479325e09c6097d48e72a4af472d18c2b94388b5405dcde6cce ;; \
|
||||
arm64) btbn_arch=linuxarm64 ; \
|
||||
sha256=e97545305043794cdf7b698d713e29291464e0c35bb8e0f3ff1f62e4c56eedd6 ;; \
|
||||
*) echo "unsupported TARGETARCH: ${TARGETARCH}" >&2 ; exit 1 ;; \
|
||||
esac ; \
|
||||
url="https://github.com/BtbN/FFmpeg-Builds/releases/download/${BTBN_TAG}/ffmpeg-${BTBN_REV}-${btbn_arch}-gpl.tar.xz" ; \
|
||||
mkdir -p /tmp/ffmpeg ; cd /tmp/ffmpeg ; \
|
||||
echo "Downloading ffmpeg (${BTBN_TAG}) from ${url}" ; \
|
||||
curl -fsSL --connect-timeout 20 --speed-limit 1024 --speed-time 30 \
|
||||
--max-time 600 --retry 3 --retry-delay 5 --retry-all-errors \
|
||||
-o ffmpeg.tar.xz "${url}" ; \
|
||||
echo "${sha256} ffmpeg.tar.xz" | sha256sum -c - ; \
|
||||
tar -xJf ffmpeg.tar.xz ; \
|
||||
ffmpeg_bin="$(find /tmp/ffmpeg -type f -name ffmpeg | head -n1)" ; \
|
||||
ffprobe_bin="$(find /tmp/ffmpeg -type f -name ffprobe | head -n1)" ; \
|
||||
[ -n "${ffmpeg_bin}" ] && [ -n "${ffprobe_bin}" ] ; \
|
||||
mv "${ffmpeg_bin}" "${ffprobe_bin}" /usr/local/bin/ ; \
|
||||
chmod +x /usr/local/bin/ffmpeg /usr/local/bin/ffprobe ; \
|
||||
rm -rf /tmp/ffmpeg
|
||||
|
||||
# Stage 4: Runtime - Minimal image with only runtime dependencies
|
||||
FROM python:3.13-slim AS runner
|
||||
|
|
|
|||
|
|
@ -65,6 +65,11 @@ else
|
|||
COMPOSE_CMD=(sudo docker compose)
|
||||
fi
|
||||
|
||||
# Reconcile the Postgres role password with .env before starting the API.
|
||||
# POSTGRES_PASSWORD only applies on first volume init, so an existing volume can
|
||||
# hold a stale password the API would fail to authenticate against. Idempotent.
|
||||
dograh_sync_postgres_password "$SCRIPT_DIR" "${COMPOSE_CMD[@]}"
|
||||
|
||||
# When SERVER_IP (sourced from .env above) is a private/reserved address the host
|
||||
# has no public IP, so start the cloudflared service (tunnel profile) to make
|
||||
# webhooks reachable. The backend resolves the tunnel's public URL at runtime using
|
||||
|
|
|
|||
|
|
@ -401,6 +401,59 @@ dograh_preflight_remote_init_render() {
|
|||
rm -rf "$tmp_root"
|
||||
}
|
||||
|
||||
# Reconcile the running Postgres role password with POSTGRES_PASSWORD in .env.
|
||||
#
|
||||
# POSTGRES_PASSWORD only takes effect when the postgres data volume is first
|
||||
# initialized. If the volume was created before .env had a generated password
|
||||
# (e.g. an early start used the compose fallback `:-postgres`), or the password
|
||||
# was later rotated, the role keeps its old password while the API connects with
|
||||
# the .env value over TCP (pg_hba `scram-sha-256`) and dies with "password
|
||||
# authentication failed for user postgres". start_docker.sh handles this for the
|
||||
# OSS quickstart; the remote path (remote_up.sh) needs the same reconciliation.
|
||||
#
|
||||
# Bring postgres up on its own, then ALTER the role over the trusted local
|
||||
# socket (pg_hba trusts `local`, so this works even when the password is
|
||||
# currently mismatched). Idempotent: on a fresh volume it just re-sets the same
|
||||
# value. Survives the later `--force-recreate` because the password lives in the
|
||||
# data volume, not the container.
|
||||
dograh_sync_postgres_password() {
|
||||
local project_dir=$1
|
||||
shift
|
||||
local compose=("$@")
|
||||
local env_file="$project_dir/.env"
|
||||
local password=""
|
||||
local ready=""
|
||||
local i
|
||||
|
||||
[[ ${#compose[@]} -gt 0 ]] || compose=(docker compose)
|
||||
|
||||
if [[ -f "$env_file" ]]; then
|
||||
password="$(awk -F= '/^POSTGRES_PASSWORD=/{sub(/^POSTGRES_PASSWORD=/, ""); print; exit}' "$env_file")"
|
||||
fi
|
||||
|
||||
# No explicit password: the compose fallback (`:-postgres`) governs both the
|
||||
# DB init and the API's DATABASE_URL, so the two already agree — nothing to do.
|
||||
[[ -n "$password" ]] || return 0
|
||||
|
||||
dograh_info "Syncing Postgres password from .env..."
|
||||
( cd "$project_dir" && "${compose[@]}" up -d postgres ) >/dev/null
|
||||
|
||||
for ((i = 0; i < 30; i++)); do
|
||||
if ( cd "$project_dir" && "${compose[@]}" exec -T postgres pg_isready -U postgres ) >/dev/null 2>&1; then
|
||||
ready=1
|
||||
break
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
[[ -n "$ready" ]] || dograh_fail "Postgres did not become ready while syncing POSTGRES_PASSWORD."
|
||||
|
||||
printf '%s\n' "ALTER USER postgres WITH PASSWORD :'pw';" \
|
||||
| ( cd "$project_dir" && "${compose[@]}" exec -T postgres \
|
||||
psql -U postgres -d postgres -v ON_ERROR_STOP=1 -v "pw=$password" ) >/dev/null \
|
||||
|| dograh_fail "Failed to sync Postgres password from .env."
|
||||
dograh_success "✓ Postgres password synced with .env"
|
||||
}
|
||||
|
||||
dograh_prepare_remote_install() {
|
||||
local project_dir=${1:-$(dograh_project_dir)}
|
||||
local env_file="$project_dir/.env"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue