mirror of
https://github.com/alexbelgium/hassio-addons.git
synced 2026-11-04 03:42:14 +00:00
/etc/sudoers is created before sudo is installed and holds only the wger rule, so dpkg keeps it and parks the default (with the root rule) as sudoers.dpkg-new. The cont-init scripts run as root and call sudo -u wger, which failed with 'root is not in the sudoers file', breaking the PowerSync SQLite import and JWT key generation. Co-authored-by: BirdNET-Go Addon Builder <addon-builder@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
180 lines
6.8 KiB
Docker
180 lines
6.8 KiB
Docker
#============================#
|
|
# ALEXBELGIUM'S DOCKERFILE #
|
|
#============================#
|
|
# _.------.
|
|
# _.-` ('>.-`"""-.
|
|
# '.--'` _'` _ .--.)
|
|
# -' '-.-';` `
|
|
# ' - _.' ``'--.
|
|
# '---` .-'""`
|
|
# /`
|
|
#=== Home Assistant Addon ===#
|
|
|
|
#################
|
|
# 1 Build Image #
|
|
#################
|
|
|
|
ARG BUILD_VERSION
|
|
ARG BUILD_FROM
|
|
|
|
# PowerSync is only started when the POWERSYNC_ENABLED option is set, but its files
|
|
# always ship in the image: an add-on is a single container, so there is nowhere else
|
|
# to put them. Pinned on purpose - the service tree is copied onto an Ubuntu 24.04
|
|
# base, so the glibc/libstdc++ floor of its node binary has to stay a known quantity.
|
|
FROM docker.io/journeyapps/powersync-service:1.27.0 AS powersync
|
|
|
|
FROM wger/server:latest
|
|
|
|
##################
|
|
# 2 Modify Image #
|
|
##################
|
|
|
|
# Set S6 wait time
|
|
ENV S6_CMD_WAIT_FOR_SERVICES=1 \
|
|
S6_CMD_WAIT_FOR_SERVICES_MAXTIME=0 \
|
|
S6_SERVICES_GRACETIME=0
|
|
|
|
|
|
# The upstream image no longer ships database defaults; settings/main.py reads
|
|
# DJANGO_DB_ENGINE and DJANGO_DB_DATABASE with no fallback, so they must be set here.
|
|
# DJANGO_DEBUG=False must be explicit: upstream's entrypoint only runs collectstatic
|
|
# when the variable is literally "False", otherwise node/fontawesome assets 404
|
|
ENV SYNC_EXERCISES_ON_STARTUP=True \
|
|
DOWNLOAD_EXERCISE_IMAGES_ON_STARTUP=True \
|
|
FROM_EMAIL='wger Workout Manager <wger@example.com>' \
|
|
DJANGO_DB_ENGINE="django.db.backends.sqlite3" \
|
|
DJANGO_DB_DATABASE="/data/database.sqlite" \
|
|
DJANGO_DEBUG=False \
|
|
DJANGO_PERFORM_MIGRATIONS=True \
|
|
DJANGO_MEDIA_ROOT="/data/media" \
|
|
DJANGO_STATIC_ROOT="/data/static"
|
|
|
|
# PowerSync defaults. Inert unless 89-powersync-run.sh starts the service: PS_PORT and
|
|
# PS_JWKS_URL are read only by PowerSync itself, and the wger settings already default
|
|
# PS_STORAGE_PG_URI, which the user has to override to a reachable database anyway.
|
|
ENV PS_PORT=8080 \
|
|
PS_JWKS_URL="http://127.0.0.1:8000/api/v2/powersync-keys" \
|
|
POWERSYNC_CONFIG_PATH=/etc/powersync/powersync.yaml
|
|
|
|
USER root
|
|
|
|
# The third sed is the guard that stops a failed SQLite import from turning into a
|
|
# fresh instance: 89-powersync-run.sh writes that marker and the add-on stops here,
|
|
# before "wger bootstrap" can create an admin user in the empty Postgres database and
|
|
# make the import look unnecessary for ever after.
|
|
RUN echo "wger ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers && \
|
|
sed -i "1a sudo -E /./ha_entrypoint.sh" /home/wger/entrypoint.sh && \
|
|
sed -i "/ha_entrypoint/a . /data/env.sh" /home/wger/entrypoint.sh && \
|
|
sed -i '/data\/env.sh/a if [ -f /data/powersync/import-failed ]; then echo "The SQLite import into Postgres did not complete; refusing to start wger so the data stays importable. See the errors above."; exit 1; fi' /home/wger/entrypoint.sh
|
|
|
|
##################
|
|
# 3 Install apps #
|
|
##################
|
|
|
|
# PowerSync service tree and its own node runtime. Copying node from the upstream
|
|
# image rather than installing one keeps the exact runtime it was built against; the
|
|
# version check below fails the build loudly if that binary cannot run on this base.
|
|
# FSL-1.1-ALv2 permits this redistribution and requires the licence to travel with it.
|
|
COPY --from=powersync /app /opt/powersync
|
|
COPY --from=powersync /usr/local/bin/node /opt/powersync/bin/node
|
|
# node --version exercises the full dynamic link of the interpreter; the ldd clauses
|
|
# then assert that the tree's one native module was found and that every library it
|
|
# needs resolves on this base. Between them the build fails loudly here rather than
|
|
# at runtime if a future PowerSync release raises its ABI floor.
|
|
RUN /opt/powersync/bin/node --version && \
|
|
find /opt/powersync -name '*.node' -exec ldd {} + > /tmp/ldd.out && \
|
|
grep -c "=> /" /tmp/ldd.out && \
|
|
! grep "not found" /tmp/ldd.out && \
|
|
rm /tmp/ldd.out && \
|
|
mkdir -p /opt/powersync/.probes /etc/nginx/ps && \
|
|
chown -R wger:wger /opt/powersync/.probes
|
|
|
|
# Add rootfs
|
|
COPY rootfs/ /
|
|
RUN find . -type f \( -name "*.sh" -o -name "run" -o -name "finish" \) -print -exec chmod +x {} \;
|
|
|
|
# Uses /bin for compatibility purposes
|
|
# hadolint ignore=DL4005
|
|
RUN if [ ! -f /bin/sh ] && [ -f /usr/bin/sh ]; then ln -s /usr/bin/sh /bin/sh; fi && \
|
|
if [ ! -f /bin/bash ] && [ -f /usr/bin/bash ]; then ln -s /usr/bin/bash /bin/bash; fi
|
|
|
|
# Modules
|
|
ARG MODULES="00-banner.sh 01-custom_script.sh 01-config_yaml.sh"
|
|
|
|
# Automatic modules download
|
|
COPY ha_automodules.sh /ha_automodules.sh
|
|
RUN chmod 744 /ha_automodules.sh && /ha_automodules.sh "$MODULES" && rm /ha_automodules.sh
|
|
|
|
# Manual apps
|
|
ENV PACKAGES="sudo nginx"
|
|
|
|
# Automatic apps & bashio
|
|
COPY ha_autoapps.sh /ha_autoapps.sh
|
|
RUN chmod 744 /ha_autoapps.sh && /ha_autoapps.sh "$PACKAGES" || true && rm /ha_autoapps.sh
|
|
|
|
# /etc/sudoers was created above holding only the wger rule, so installing sudo keeps it
|
|
# and parks its default (with the root rule) as sudoers.dpkg-new. The cont-init scripts
|
|
# run as root and call "sudo -u wger", which fails without a root rule.
|
|
RUN echo "root ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
|
|
|
|
################
|
|
# 4 Entrypoint #
|
|
################
|
|
|
|
# Add entrypoint
|
|
ENV S6_STAGE2_HOOK=/ha_entrypoint.sh
|
|
COPY ha_entrypoint.sh /ha_entrypoint.sh
|
|
RUN chmod 777 /ha_entrypoint.sh
|
|
|
|
# Install bashio
|
|
COPY bashio-standalone.sh /usr/local/lib/bashio-standalone.sh
|
|
RUN chmod 0755 /usr/local/lib/bashio-standalone.sh
|
|
|
|
USER wger
|
|
#ENTRYPOINT ["/usr/bin/env"]
|
|
#CMD ["/ha_entrypoint.sh"]
|
|
|
|
############
|
|
# 5 Labels #
|
|
############
|
|
|
|
ARG BUILD_ARCH
|
|
ARG BUILD_DATE
|
|
ARG BUILD_DESCRIPTION
|
|
ARG BUILD_NAME
|
|
ARG BUILD_REF
|
|
ARG BUILD_REPOSITORY
|
|
ARG BUILD_VERSION
|
|
ENV BUILD_VERSION="${BUILD_VERSION}"
|
|
LABEL \
|
|
io.hass.name="${BUILD_NAME}" \
|
|
io.hass.description="${BUILD_DESCRIPTION}" \
|
|
io.hass.arch="${BUILD_ARCH}" \
|
|
io.hass.type="addon" \
|
|
io.hass.version=${BUILD_VERSION} \
|
|
maintainer="alexbelgium (https://github.com/alexbelgium)" \
|
|
org.opencontainers.image.title="${BUILD_NAME}" \
|
|
org.opencontainers.image.description="${BUILD_DESCRIPTION}" \
|
|
org.opencontainers.image.vendor="Home Assistant Add-ons" \
|
|
org.opencontainers.image.authors="alexbelgium (https://github.com/alexbelgium)" \
|
|
org.opencontainers.image.licenses="MIT" \
|
|
org.opencontainers.image.url="https://github.com/alexbelgium" \
|
|
org.opencontainers.image.source="https://github.com/${BUILD_REPOSITORY}" \
|
|
org.opencontainers.image.documentation="https://github.com/${BUILD_REPOSITORY}/blob/main/README.md" \
|
|
org.opencontainers.image.created=${BUILD_DATE} \
|
|
org.opencontainers.image.revision=${BUILD_REF} \
|
|
org.opencontainers.image.version=${BUILD_VERSION}
|
|
|
|
#################
|
|
# 6 Healthcheck #
|
|
#################
|
|
|
|
ENV HEALTH_PORT="80" \
|
|
HEALTH_URL=""
|
|
HEALTHCHECK \
|
|
--interval=5s \
|
|
--retries=5 \
|
|
--start-period=30s \
|
|
--timeout=25s \
|
|
CMD curl -A "HealthCheck: Docker/1.0" -s -f "http://127.0.0.1:${HEALTH_PORT}${HEALTH_URL}" &>/dev/null || exit 1
|