Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions .github/workflows/emoncms.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ on:
description: 'alpine version'
required: true
type: string
default: '3.20'
default: '3.24'
php_version:
description: 'php version'
required: true
type: string
default: '83'
default: '84'
tag:
description: 'tag : latest or dev_test ?'
required: true
Expand All @@ -60,22 +60,22 @@ jobs:
steps:
-
name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7
-
name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@v4
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
-
name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v5
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/emoncms_w_version.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,12 @@ on:
description: 'alpine version'
required: true
type: string
default: '3.20'
default: '3.24'
php_version:
description: 'php version'
required: true
type: string
default: '83'
default: '84'
use_redispy_apk:
description: 'install redispy through : apk 0 or 1 ?'
required: true
Expand All @@ -59,13 +59,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v7
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
uses: docker/setup-qemu-action@v4
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v4
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v4
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
Expand All @@ -77,7 +77,7 @@ jobs:
echo $version
echo "version=$version" >> "$GITHUB_OUTPUT"
- name: Build and push
uses: docker/build-push-action@v5
uses: docker/build-push-action@v7
with:
context: .
platforms: linux/amd64,linux/arm64,linux/arm/v7
Expand Down
27 changes: 27 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,32 @@
# Changelog

## alpine3.24_emoncms12.2.0

security update : PHP 8.4.27 fixes the critical RCE [GHSA-w8hw-w9fx-j79w](https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w) and [GHSA-6wmf-4rv5-p3rp](https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp)

- alpine 3.24
- PHP 8.4.27
- MariaDB 11.8
- Redis 8.8
- Mosquitto 2.1
- Apache 2.4.69
- s6-overlay 3.2.3.2
- phpredis 6.3.0

MariaDB system tables are upgraded automatically at startup when using an existing database created by an older MariaDB. MariaDB cannot be downgraded : backup before upgrading

if upgrading from an existing installation, update the database structure after upgrading

Emoncms Core v12.1.9
App v3.8.2
Dashboard v4.2.0
Device v2.6.2
Graph v3.5.0
Backup v2.6.0
Postprocess v2.8.1
Sync v3.6.0
EmonScripts v1.9.8

## alpine3.20_emoncms11.9.10

Emoncms Core v11.9.10
Expand Down
68 changes: 45 additions & 23 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
ARG BUILD_FROM=alpine:3.19
ARG BUILD_FROM=alpine:3.24

FROM $BUILD_FROM

ARG \
TARGETPLATFORM \
S6_OVERLAY_VERSION=3.1.6.2 \
S6_OVERLAY_VERSION=3.2.3.2 \
S6_SRC=https://github.com/just-containers/s6-overlay/releases/download \
S6_DIR=/etc/s6-overlay/s6-rc.d \
# since s6-overlay 3.2, the user and user2 bundles live here
S6_BUNDLES=/etc/s6-overlay/user-bundles.d \
PRIMOS="apache2 redis mosquitto mariadb" \
SECONDOS="emoncms_mqtt service-runner feedwriter sync_upload" \
MODULES="graph:stable dashboard:stable app:stable device:stable" \
SYMODULES="sync:master postprocess:master backup:master" \
# PHP_VER needed to install the php-dev apk package and for the path to PHP CONF/INI files
PHP_VER=82 \
# PHP_VER needed to install the php apk packages and for the path to PHP CONF/INI files
PHP_VER=84 \
# we dont modify php.ini, we create new extensions in conf.d
PHP_CONF=/etc/php82/conf.d \
PHP_CONF=/etc/php84/conf.d \
PHPREDIS_VERSION=6.3.0 \
REDIS_CONF=/etc/redis.conf \
USE_REDISPY_APK=1 \
# source for Mosquitto-PHP extension
Expand All @@ -40,20 +43,25 @@ ENV \

# /data creation and apk installation
# php-gettext available via apk
RUN mkdir -p /data;\
# set -e so that a missing package fails the build
RUN set -ex;\
mkdir -p /data;\
mkdir -p /config;\
apk update && apk upgrade;\
apk add --no-cache tzdata xz bash git make tar jq;\
apk add --no-cache sed nano;\
apk add --no-cache python3;\
apk add --no-cache ca-certificates wget;\
apk add --no-cache apache2 apache2-ssl gettext;\
apk add --no-cache mariadb mariadb-client;\
# mariadb-server-utils provides mariadb-upgrade
apk add --no-cache mariadb mariadb-client mariadb-server-utils;\
apk add --no-cache redis;\
apk add --no-cache mosquitto;\
apk add --no-cache php php-gettext php-apache2 php-mysqli;\
apk add --no-cache php-gd php-curl php-common php-mbstring;\
apk add --no-cache php-session php-ctype
apk add --no-cache php$PHP_VER php$PHP_VER-gettext php$PHP_VER-apache2 php$PHP_VER-mysqli;\
apk add --no-cache php$PHP_VER-gd php$PHP_VER-curl php$PHP_VER-common php$PHP_VER-mbstring;\
apk add --no-cache php$PHP_VER-session php$PHP_VER-ctype;\
# alpine only provides /usr/bin/phpXX, workers and modules call php
[ -e /usr/bin/php ] || ln -s /usr/bin/php$PHP_VER /usr/bin/php

# it is possible to install s6-overlay with apk but it does not provide user2
#RUN apk add --no-cache s6-overlay
Expand Down Expand Up @@ -116,20 +124,34 @@ RUN set -x; \
# build-base is required to compile with gcc
# mosquitto-dev is needed to compile mosquitto-PHP
# we need phpize so we install php-dev
RUN set -x;\
RUN set -ex;\
apk add --no-cache build-base mosquitto-dev;\
apk add --no-cache py3-pip php$PHP_VER-dev;\
sed -i "s/^save 900 1/#save 900 1/" $REDIS_CONF;\
sed -i "s/^save 300 1/#save 300 1/" $REDIS_CONF;\
sed -i "s/^save 60 1/#save 60 1/" $REDIS_CONF;\
git clone https://github.com/phpredis/phpredis;\
cd phpredis && phpize && ./configure && make && make install;\
git clone --depth 1 -b $PHPREDIS_VERSION https://github.com/phpredis/phpredis;\
# no && chains here, set -e would not catch a failure inside them
# alpine only provides versioned phpize and php-config
cd phpredis;\
phpize$PHP_VER;\
./configure --with-php-config=php-config$PHP_VER;\
make;\
make install;\
printf "extension=redis.so" | tee $PHP_CONF/redis.ini 1>&2;\
if [ "$USE_REDISPY_APK" -ne 0 ]; then apk add --no-cache py3-redis; fi;\
if [ "$USE_REDISPY_APK" -eq 0 ]; then pip3 install redis; fi;\
git clone $MOSQUITTO_PHP;\
cd Mosquitto-PHP && phpize && ./configure && make && make install;\
if [ "$USE_REDISPY_APK" -eq 0 ]; then pip3 install --break-system-packages redis; fi;\
git clone --depth 1 $MOSQUITTO_PHP;\
cd Mosquitto-PHP;\
phpize$PHP_VER;\
# musl strerror_r returns int, not char *, and gcc 14+ makes that an error

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably something like that which works both for posix and gnu

PHP_MOSQUITTO_API char *php_mosquitto_strerror_wrapper(int err)
{
    char *buf = ecalloc(256, sizeof(char));

#if defined(__GLIBC__) && defined(_GNU_SOURCE)
    char *msg = strerror_r(err, buf, 256);

    if (msg != buf) {
        char *result = estrdup(msg);
        efree(buf);
        buf = result;
    }
#else
    if (strerror_r(err, buf, 256) != 0) {
        efree(buf);
        return NULL;
    }
#endif

    if (!buf[0]) {
        efree(buf);
        return NULL;
    }

    return buf;
}

@alexandrecuer alexandrecuer Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

working nicely on amd

just produced a new image

docker pull alexjunk/emoncms:alpine3.24_emoncms12.2.0
image image

mosquitto is fine

image

# the return value is not used so it is safe to keep it a warning
./configure --with-php-config=php-config$PHP_VER CFLAGS="-O2 -Wno-error=int-conversion";\
make;\
make install;\
printf "extension=mosquitto.so" | tee $PHP_CONF/mosquitto.ini 1>&2;\
php -m | grep -qx redis;\
php -m | grep -qx mosquitto;\
apk del --no-cache build-base mosquitto-dev;\
apk del --no-cache py3-pip php$PHP_VER-dev;\
# this will remove sources for phpredis and Mosquitto-PHP
Expand All @@ -139,7 +161,7 @@ COPY emoncms_pre.sh sql_ready.sh ./

# we create dynamically the database update script
# as it uses the $WWW env which will not be available at run time in php
RUN set -x;\
RUN set -ex;\
echo "<?php" > emoncmsdbupdate.php;\
echo "\$applychanges = true;" >> emoncmsdbupdate.php;\
echo "define('EMONCMS_EXEC', 1);" >> emoncmsdbupdate.php;\
Expand All @@ -158,19 +180,19 @@ RUN set -x;\

# if s6-overlay is installed via apk, use bin and not command for execlineb !!
# cf https://github.com/just-containers/s6-overlay/issues/449
RUN set -x;\
RUN set -ex;\
# initialize timeseries and mariadb with a oneshot service called emoncms_pre
mkdir $S6_DIR/emoncms_pre;\
mkdir $S6_DIR/emoncms_pre/dependencies.d;\
touch $S6_DIR/emoncms_pre/dependencies.d/base;\
echo "oneshot" > $S6_DIR/emoncms_pre/type;\
echo "$OEM_DIR/emoncms_pre.sh" > $S6_DIR/emoncms_pre/up;\
touch $S6_DIR/user/contents.d/emoncms_pre;\
touch $S6_BUNDLES/user/contents.d/emoncms_pre;\
# start primo services after emoncms_pre
for i in $PRIMOS; do mkdir $S6_DIR/$i; done;\
for i in $PRIMOS; do mkdir $S6_DIR/$i/dependencies.d; done;\
for i in $PRIMOS; do touch $S6_DIR/$i/dependencies.d/emoncms_pre; done;\
for i in $PRIMOS; do touch $S6_DIR/user/contents.d/$i; done;\
for i in $PRIMOS; do touch $S6_BUNDLES/user/contents.d/$i; done;\
for i in $PRIMOS; do echo "longrun" > $S6_DIR/$i/type; done;\
for i in $PRIMOS; do echo "#!/command/execlineb -P" > $S6_DIR/$i/run; done;\
echo "/command/foreground { rm -f /var/run/apache2/httpd.pid } /usr/sbin/httpd -D FOREGROUND" >> $S6_DIR/apache2/run;\
Expand All @@ -182,19 +204,19 @@ RUN set -x;\
echo "mysqld --user=root" >> $S6_DIR/mariadb/run

# user2 level services = workers
RUN set -x;\
RUN set -ex;\
# check if SQL is fully ready with a oneshot service
mkdir $S6_DIR/sql_ready;\
mkdir $S6_DIR/sql_ready/dependencies.d;\
touch $S6_DIR/sql_ready/dependencies.d/legacy-services;\
echo "oneshot" > $S6_DIR/sql_ready/type;\
echo "$OEM_DIR/sql_ready.sh" > $S6_DIR/sql_ready/up;\
touch $S6_DIR/user2/contents.d/sql_ready;\
touch $S6_BUNDLES/user2/contents.d/sql_ready;\
# start all long running workers after sql_ready
for i in $SECONDOS; do mkdir $S6_DIR/$i; done;\
for i in $SECONDOS; do mkdir $S6_DIR/$i/dependencies.d; done;\
for i in $SECONDOS; do touch $S6_DIR/$i/dependencies.d/sql_ready; done;\
for i in $SECONDOS; do touch $S6_DIR/user2/contents.d/$i; done;\
for i in $SECONDOS; do touch $S6_BUNDLES/user2/contents.d/$i; done;\
for i in $SECONDOS; do echo "longrun" > $S6_DIR/$i/type; done;\
for i in $SECONDOS; do echo "#!/command/execlineb -P" > $S6_DIR/$i/run; done;\
echo "s6-setuidgid $DAEMON" >> $S6_DIR/emoncms_mqtt/run;\
Expand Down
2 changes: 1 addition & 1 deletion config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: emoncms
description: The webapp for energy monitoring and more
version: alpine3.20_emoncms11.9.10
version: alpine3.24_emoncms12.2.0
image: alexjunk/emoncms
slug: emoncms
url: https://github.com/Open-Building-Management/emoncms/issues
Expand Down
5 changes: 5 additions & 0 deletions sql_ready.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,9 @@ if [ "$NEW_INSTALL" -eq 1 ]; then
# home assistant, to access through a phpmyadmin container used as a addon
mysql -e "GRANT ALL ON $MYSQL_DATABASE.* TO '$MYSQL_USER'@'172.30.33.%' IDENTIFIED BY '$MYSQL_PASSWORD'; flush privileges;"
php "$OEM_DIR/emoncmsdbupdate.php"
else
# upgrade system tables if the datadir was created by an older mariadb
# does nothing if they are already up to date
echo "Checking if mariadb system tables need an upgrade"
mariadb-upgrade
fi