mirror of
https://github.com/pyMC-dev/pyMC_Repeater.git
synced 2026-06-16 08:05:00 +02:00
Merge branch 'pr-285' into dev
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
# Copy this file to .env before running Docker Compose:
|
||||
# cp .env.example .env
|
||||
|
||||
# Published image to run. Use a different repository or tag if you are testing
|
||||
# a fork or a specific release.
|
||||
PYMC_REPEATER_IMAGE=pymcdev/pymc-repeater:main
|
||||
|
||||
# Storage defaults to Docker named volumes. This is the safest option for
|
||||
# Portainer and fresh installs because Docker preserves the image ownership.
|
||||
# To use host bind mounts instead, create the folders first and make them
|
||||
# writable by UID/GID 15888:
|
||||
# sudo mkdir -p /opt/pymc-repeater/config /opt/pymc-repeater/data
|
||||
# sudo chown -R 15888:15888 /opt/pymc-repeater/config /opt/pymc-repeater/data
|
||||
# Then uncomment and adjust these paths:
|
||||
# PYMC_CONFIG_VOLUME=/opt/pymc-repeater/config
|
||||
# PYMC_DATA_VOLUME=/opt/pymc-repeater/data
|
||||
|
||||
# SPI/GPIO access uses the host's numeric group IDs. Check your host with:
|
||||
# getent group gpio
|
||||
# getent group spi
|
||||
# Example output:
|
||||
# gpio:x:997:
|
||||
# spi:x:999:
|
||||
# Put the third field from each output line below.
|
||||
GPIO_GID=986
|
||||
SPI_GID=989
|
||||
|
||||
# Local build only. These are used by docker-compose.build.yml if you build the
|
||||
# image yourself instead of pulling PYMC_REPEATER_IMAGE.
|
||||
PUID=15888
|
||||
PGID=15888
|
||||
@@ -51,6 +51,7 @@ htmlcov/
|
||||
*~
|
||||
|
||||
# Config
|
||||
.env
|
||||
config.yaml
|
||||
config.yaml.backup
|
||||
identity.json
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
services:
|
||||
pymc-repeater:
|
||||
image: pymc-repeater:local
|
||||
build:
|
||||
context: .
|
||||
dockerfile: dockerfile
|
||||
args:
|
||||
PUID: ${PUID:-15888}
|
||||
PGID: ${PGID:-15888}
|
||||
GPIO_GID: ${GPIO_GID:-986}
|
||||
SPI_GID: ${SPI_GID:-989}
|
||||
+11
-9
@@ -1,10 +1,6 @@
|
||||
services:
|
||||
pymc-repeater:
|
||||
build:
|
||||
context: .
|
||||
args:
|
||||
PUID: ${PUID:-1000}
|
||||
PGID: ${PGID:-1000}
|
||||
image: ${PYMC_REPEATER_IMAGE:-pymcdev/pymc-repeater:main}
|
||||
container_name: pymc-repeater
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
@@ -18,9 +14,15 @@ services:
|
||||
# SPI DEVICES PERMISSIONS
|
||||
cap_add:
|
||||
- SYS_RAWIO
|
||||
# USB DEVICSE PERMISSIONS
|
||||
# USB DEVICE PERMISSIONS
|
||||
group_add:
|
||||
- plugdev
|
||||
- "${GPIO_GID:-986}"
|
||||
- "${SPI_GID:-989}"
|
||||
- plugdev
|
||||
volumes:
|
||||
- ./config:/etc/pymc_repeater
|
||||
- ./data:/var/lib/pymc_repeater
|
||||
- ${PYMC_CONFIG_VOLUME:-pymc-repeater-config}:/etc/pymc_repeater
|
||||
- ${PYMC_DATA_VOLUME:-pymc-repeater-data}:/var/lib/pymc_repeater
|
||||
|
||||
volumes:
|
||||
pymc-repeater-config:
|
||||
pymc-repeater-data:
|
||||
|
||||
+46
-3
@@ -13,16 +13,48 @@ YQ_CMD="${YQ_CMD:-/usr/local/bin/yq}"
|
||||
|
||||
mkdir -p "${CONFIG_DIR}"
|
||||
|
||||
print_permission_help() {
|
||||
echo "If you are bind-mounting ./config or ./data, ensure the host paths are writable by ${RUNTIME_USER} (${RUNTIME_UID}:${RUNTIME_GID})." >&2
|
||||
echo "For the default image user, run: sudo chown -R ${RUNTIME_UID}:${RUNTIME_GID} ./config ./data" >&2
|
||||
}
|
||||
|
||||
fail_bad_config_mount() {
|
||||
echo "Invalid Docker config mount: ${CONFIG_PATH} is a directory, but it must be the config file." >&2
|
||||
echo "This usually happens when ./config.yaml is bind-mounted before that host file exists." >&2
|
||||
echo "Use the supported folder mount instead:" >&2
|
||||
echo " - ./config:/etc/pymc_repeater" >&2
|
||||
echo "Then place the config at ./config/config.yaml." >&2
|
||||
print_permission_help
|
||||
exit 1
|
||||
}
|
||||
|
||||
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
|
||||
print_permission_help
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
use_runtime_merged_config() {
|
||||
src="$1"
|
||||
runtime_dir="$(mktemp -d /tmp/pymc-repeater-config.XXXXXX)"
|
||||
runtime_config="${runtime_dir}/config.yaml"
|
||||
|
||||
if ! cp "${src}" "${runtime_config}"; then
|
||||
echo "Failed to prepare temporary merged config at ${runtime_config}; keeping the existing config." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
CONFIG_PATH="${runtime_config}"
|
||||
echo "Using merged config from ${CONFIG_PATH} for this container start only." >&2
|
||||
echo "Fix the bind-mounted config ownership so future upgrades can persist merged config changes." >&2
|
||||
print_permission_help
|
||||
return 0
|
||||
}
|
||||
|
||||
merge_config_from_example() {
|
||||
config_path="$1"
|
||||
|
||||
@@ -62,15 +94,26 @@ merge_config_from_example() {
|
||||
fi
|
||||
|
||||
if ! cmp -s "${config_path}" "${merged_config}"; then
|
||||
copy_or_die "${merged_config}" "${config_path}"
|
||||
if ! cp "${merged_config}" "${config_path}"; then
|
||||
echo "Failed to update ${config_path} from merged config; the bind-mounted config is not writable." >&2
|
||||
use_runtime_merged_config "${merged_config}" || true
|
||||
fi
|
||||
fi
|
||||
|
||||
cleanup_merge
|
||||
trap - EXIT HUP INT TERM
|
||||
}
|
||||
|
||||
if [ -d "${CONFIG_PATH}" ] && [ "$(basename "${CONFIG_PATH}")" = "config.yaml" ]; then
|
||||
fail_bad_config_mount
|
||||
fi
|
||||
|
||||
if [ ! -f "${EXAMPLE_PATH}" ] && [ -f "${BUNDLED_EXAMPLE_PATH}" ]; then
|
||||
copy_or_die "${BUNDLED_EXAMPLE_PATH}" "${EXAMPLE_PATH}"
|
||||
if ! cp "${BUNDLED_EXAMPLE_PATH}" "${EXAMPLE_PATH}"; then
|
||||
echo "Could not copy bundled example config to ${EXAMPLE_PATH}; using bundled example for config merge only." >&2
|
||||
print_permission_help
|
||||
EXAMPLE_PATH="${BUNDLED_EXAMPLE_PATH}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -d "${CONFIG_PATH}" ]; then
|
||||
|
||||
+9
-2
@@ -5,6 +5,8 @@ ARG USER=repeater
|
||||
ARG GROUP=repeater
|
||||
ARG PUID=15888
|
||||
ARG PGID=15888
|
||||
ARG GPIO_GID=986
|
||||
ARG SPI_GID=989
|
||||
ARG TARGETARCH
|
||||
ARG YQ_VERSION=v4.40.5
|
||||
|
||||
@@ -16,7 +18,9 @@ ENV INSTALL_DIR=/opt/pymc_repeater \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
SETUPTOOLS_SCM_PRETEND_VERSION_FOR_PYMC_REPEATER=${PACKAGE_VERSION} \
|
||||
PUID=${PUID} \
|
||||
PGID=${PGID}
|
||||
PGID=${PGID} \
|
||||
GPIO_GID=${GPIO_GID} \
|
||||
SPI_GID=${SPI_GID}
|
||||
|
||||
# Install runtime dependencies only
|
||||
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y \
|
||||
@@ -45,7 +49,10 @@ RUN arch="${TARGETARCH:-}" \
|
||||
|
||||
# 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"
|
||||
&& groupadd --gid "$GPIO_GID" gpio \
|
||||
&& groupadd --gid "$SPI_GID" spi \
|
||||
&& useradd --uid "$PUID" --gid "$PGID" --home-dir "$HOME_DIR" --create-home --shell /usr/bin/bash "$USER" \
|
||||
&& usermod -a -G gpio,spi "$USER"
|
||||
|
||||
# Create runtime directories
|
||||
RUN mkdir -p ${INSTALL_DIR} ${CONFIG_DIR} ${DATA_DIR} \
|
||||
|
||||
Reference in New Issue
Block a user