docker: tolerate read-only config during merge

This commit is contained in:
Yellowcooln
2026-05-28 14:31:59 -04:00
parent a308ddc00d
commit 9e8c152f0b
3 changed files with 49 additions and 11 deletions
+15 -6
View File
@@ -349,23 +349,32 @@ You can now run pyMC Repeater from within a [Docker Container](https://www.docke
Here is what you'll need to do in order to get the container running:
1. Copy the `config.yaml.example` to `config.yaml`
1. Create the bind mount directories and copy the example config into the
Docker config directory.
```bash
cp ./config.yaml.example ./config.yaml
mkdir -p ./config ./data
cp ./config.yaml.example ./config/config.yaml
```
2. Run the configuration script and follow the prompts.
```bash
sudo bash ./setup-radio-config.sh
sudo bash ./setup-radio-config.sh ./config
```
3. Modify the `config.yaml` file with a unique web UI password. This allows you to bypass the `/setup` page when logging for the first time. You can find the value under `repeater.security.admin_password`. Change to _anything_ besides the default of `admin123`.
3. Modify `./config/config.yaml` with a unique web UI password. This allows you to bypass the `/setup` page when logging for the first time. You can find the value under `repeater.security.admin_password`. Change to _anything_ besides the default of `admin123`.
4. Configure the [docker compose](./docker-compose.yml) to your specific hardware and file paths. Be sure to comment-out or delete lines that aren't required for your hardware. Please note that your hardware devices might be at a different path than those listed in the docker compose file.
5. If you are using SPI/GPIO hardware, make sure the `GPIO_GID` and `SPI_GID`
5. Make the bind mount directories writable by the container user. The image
runs as UID/GID `15888` by default unless you override `PUID` and `PGID`.
```bash
sudo chown -R 15888:15888 ./config ./data
```
6. If you are using SPI/GPIO hardware, make sure the `GPIO_GID` and `SPI_GID`
values match the numeric group IDs on your host. The compose file defaults
to `GPIO_GID=986` and `SPI_GID=989`.
@@ -374,7 +383,7 @@ getent group gpio
getent group spi
```
6. Build and start the container.
7. Build and start the container.
```bash
docker compose up -d --force-recreate --build
+2 -2
View File
@@ -4,8 +4,8 @@ services:
context: .
dockerfile: dockerfile
args:
PUID: ${PUID:-1000}
PGID: ${PGID:-1000}
PUID: ${PUID:-15888}
PGID: ${PGID:-15888}
GPIO_GID: ${GPIO_GID:-986}
SPI_GID: ${SPI_GID:-989}
container_name: pymc-repeater
+32 -3
View File
@@ -13,16 +13,38 @@ 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
}
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,7 +84,10 @@ 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
@@ -70,7 +95,11 @@ merge_config_from_example() {
}
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