docker: bootstrap config and run rootless

This commit is contained in:
Yellowcooln
2026-05-18 10:23:37 -04:00
parent a08c4d093c
commit 72a8755399
3 changed files with 71 additions and 5 deletions
+5 -1
View File
@@ -1,6 +1,10 @@
services:
pymc-repeater:
build: .
build:
context: .
args:
PUID: ${PUID:-1000}
PGID: ${PGID:-1000}
container_name: pymc-repeater
restart: unless-stopped
ports:
+38
View File
@@ -0,0 +1,38 @@
#!/bin/sh
set -eu
INSTALL_DIR="${INSTALL_DIR:-/opt/pymc_repeater}"
CONFIG_DIR="${CONFIG_DIR:-/etc/pymc_repeater}"
CONFIG_PATH="${PYMC_REPEATER_CONFIG:-${CONFIG_DIR}/config.yaml}"
EXAMPLE_PATH="${CONFIG_DIR}/config.yaml.example"
BUNDLED_EXAMPLE_PATH="${INSTALL_DIR}/config.yaml.example"
RUNTIME_USER="${USER:-repeater}"
RUNTIME_UID="${PUID:-unknown}"
RUNTIME_GID="${PGID:-unknown}"
mkdir -p "${CONFIG_DIR}"
copy_or_die() {
src="$1"
dest="$2"
if ! cp "${src}" "${dest}"; then
echo "Failed to initialize ${dest} from ${src}." >&2
echo "If you are bind-mounting ./config.yaml, ensure the host path is writable by ${RUNTIME_USER} (${RUNTIME_UID}:${RUNTIME_GID})." >&2
exit 1
fi
}
if [ ! -f "${EXAMPLE_PATH}" ] && [ -f "${BUNDLED_EXAMPLE_PATH}" ]; then
copy_or_die "${BUNDLED_EXAMPLE_PATH}" "${EXAMPLE_PATH}"
fi
if [ -d "${CONFIG_PATH}" ]; then
if [ ! -s "${CONFIG_PATH}/config.yaml" ] && [ -f "${EXAMPLE_PATH}" ]; then
copy_or_die "${EXAMPLE_PATH}" "${CONFIG_PATH}/config.yaml"
fi
CONFIG_PATH="${CONFIG_PATH}/config.yaml"
elif [ ! -s "${CONFIG_PATH}" ] && [ -f "${EXAMPLE_PATH}" ]; then
copy_or_die "${EXAMPLE_PATH}" "${CONFIG_PATH}"
fi
exec python3 -m repeater.main --config "${CONFIG_PATH}"
+28 -4
View File
@@ -1,15 +1,23 @@
FROM python:3.12-slim-bookworm
ARG PACKAGE_VERSION=1.0.5
ARG USER=repeater
ARG GROUP=repeater
ARG PUID=15888
ARG PGID=15888
ENV INSTALL_DIR=/opt/pymc_repeater \
CONFIG_DIR=/etc/pymc_repeater \
DATA_DIR=/var/lib/pymc_repeater \
HOME_DIR=/home/${USER} \
PATH=/home/${USER}/.local/bin:${PATH} \
PYTHONUNBUFFERED=1 \
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYMC_REPEATER=${PACKAGE_VERSION}
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYMC_REPEATER=${PACKAGE_VERSION} \
PUID=${PUID} \
PGID=${PGID}
# Install runtime dependencies only
RUN apt-get update && apt-get install -y \
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \
libffi-dev \
python3-rrdtool \
jq \
@@ -21,20 +29,36 @@ RUN apt-get update && apt-get install -y \
python3-dev \
&& rm -rf /var/lib/apt/lists/*
# Create the group and user in order to run without root privileges
RUN groupadd --gid "$PGID" "$GROUP" \
&& useradd --uid "$PUID" --gid "$PGID" --home-dir "$HOME_DIR" --create-home --shell /usr/bin/bash "$USER"
# Create runtime directories
RUN mkdir -p ${INSTALL_DIR} ${CONFIG_DIR} ${DATA_DIR}
RUN mkdir -p ${INSTALL_DIR} ${CONFIG_DIR} ${DATA_DIR} \
&& chown -R "$USER":"$GROUP" ${INSTALL_DIR} ${CONFIG_DIR} ${DATA_DIR} ${HOME_DIR}
WORKDIR ${INSTALL_DIR}
# Copy source
COPY repeater ./repeater
COPY pyproject.toml .
COPY config.yaml.example .
COPY radio-presets.json .
COPY radio-settings.json .
COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh
# Switch to the unprivileged runtime user
USER ${USER}
# Install package
RUN pip install --no-cache-dir .
USER root
RUN chmod +x /usr/local/bin/docker-entrypoint.sh
USER ${USER}
EXPOSE 8000
ENTRYPOINT ["python3", "-m", "repeater.main", "--config", "/etc/pymc_repeater/config.yaml"]
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]