Skip to content
This repository has been archived by the owner on Jan 8, 2024. It is now read-only.

Commit

Permalink
423/ feature provide a uid and gid at run time (#451)
Browse files Browse the repository at this point in the history
* feat: run as uid

* fix: fpm can run as delegated user

* feat: apache runs a delegaed usert

* docs: added documantaion for user and group id
  • Loading branch information
tobybatch authored Jan 22, 2023
1 parent 505557f commit 99dea36
Show file tree
Hide file tree
Showing 6 changed files with 145 additions and 56 deletions.
5 changes: 3 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,7 @@ RUN ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime && echo ${TZ} > /etc/timezo

# copy startup script & DB checking script
COPY assets/startup.sh /startup.sh
COPY assets/service.sh /service.sh
COPY assets/self-test.sh /self-test.sh
COPY assets/dbtest.php /dbtest.php

Expand Down Expand Up @@ -250,6 +251,8 @@ ENV COMPOSER_MEMORY_LIMIT=-1
# If this set then the image will start, run a self test and then exit. It's used for the release process
ENV TEST_AND_EXIT=
ENV COMPOSER_ALLOW_SUPERUSER=1
ENV USER_ID=1000

This comment has been minimized.

Copy link
@pbek

pbek Jan 23, 2023

Contributor

Hi @tobybatch, I think those two new settings might have broke my kimai2 (I'm only reporting in case someone else has this too), see #456.

ENV GROUP_ID=1000

VOLUME [ "/opt/kimai/var" ]

Expand Down Expand Up @@ -284,7 +287,6 @@ RUN \
ENV APP_ENV=dev
ENV DATABASE_URL=
ENV memory_limit=256
USER www-data

# production build
FROM base AS prod
Expand All @@ -308,4 +310,3 @@ RUN \
ENV APP_ENV=prod
ENV DATABASE_URL=
ENV memory_limit=128
USER www-data
60 changes: 60 additions & 0 deletions assets/service.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/bash -x

function waitForDB() {
# Parse sql connection data
if [ ! -z "$DATABASE_URL" ]; then
DB_TYPE=$(awk -F '[/:@]' '{print $1}' <<< "$DATABASE_URL")
DB_USER=$(awk -F '[/:@]' '{print $4}' <<< "$DATABASE_URL")
DB_PASS=$(awk -F '[/:@]' '{print $5}' <<< "$DATABASE_URL")
DB_HOST=$(awk -F '[/:@]' '{print $6}' <<< "$DATABASE_URL")
DB_PORT=$(awk -F '[/:@]' '{print $7}' <<< "$DATABASE_URL")
DB_BASE=$(awk -F '[/?]' '{print $4}' <<< "$DATABASE_URL")
else
DB_TYPE=${DB_TYPE:mysql}
if [ "$DB_TYPE" == "mysql" ]; then
export DATABASE_URL="${DB_TYPE}://${DB_USER:=kimai}:${DB_PASS:=kimai}@${DB_HOST:=sqldb}:${DB_PORT:=3306}/${DB_BASE:=kimai}"
else
echo "Unknown database type, cannot proceed. Only 'mysql' is supported, received: [$DB_TYPE]"
exit 1
fi
fi

re='^[0-9]+$'
if ! [[ $DB_PORT =~ $re ]] ; then
DB_PORT=3306
fi

echo "Wait for MySQL DB connection ..."
until php /dbtest.php $DB_HOST $DB_BASE $DB_PORT $DB_USER $DB_PASS; do
echo Checking DB: $?
sleep 3
done
echo "Connection established"
}

function handleStartup() {
# These are idempotent, run them anyway
/opt/kimai/bin/console -n kimai:install
/opt/kimai/bin/console -n kimai:update
if [ ! -z "$ADMINPASS" ] && [ ! -a "$ADMINMAIL" ]; then
/opt/kimai/bin/console kimai:create-user superadmin "$ADMINMAIL" ROLE_SUPER_ADMIN "$ADMINPASS"
fi
echo "$KIMAI" > /opt/kimai/var/installed
echo "Kimai2 ready"
}

function runServer() {
/opt/kimai/bin/console kimai:reload --env="$APP_ENV"
if [ -e /use_apache ]; then
/usr/sbin/apache2ctl -D FOREGROUND
elif [ -e /use_fpm ]; then
exec php-fpm
else
echo "Error, unknown server type"
fi
}

waitForDB
handleStartup
runServer
exit
92 changes: 38 additions & 54 deletions assets/startup.sh
Original file line number Diff line number Diff line change
@@ -1,81 +1,65 @@
#!/bin/bash
#!/bin/bash -x

echo $KIMAI
# shellcheck disable=SC2155
export KIMAI=$(/opt/kimai/bin/console kimai:version --short)
echo "***********************************************"
echo "STARTING KIMAI VERSION ${KIMAI} in ${APP_ENV}"
echo "***********************************************"

function waitForDB() {
# Parse sql connection data
if [ ! -z "$DATABASE_URL" ]; then
DB_TYPE=$(awk -F '[/:@]' '{print $1}' <<< $DATABASE_URL)
DB_USER=$(awk -F '[/:@]' '{print $4}' <<< $DATABASE_URL)
DB_PASS=$(awk -F '[/:@]' '{print $5}' <<< $DATABASE_URL)
DB_HOST=$(awk -F '[/:@]' '{print $6}' <<< $DATABASE_URL)
DB_PORT=$(awk -F '[/:@]' '{print $7}' <<< $DATABASE_URL)
DB_BASE=$(awk -F '[/?]' '{print $4}' <<< $DATABASE_URL)
else
DB_TYPE=${DB_TYPE:mysql}
if [ "$DB_TYPE" == "mysql" ]; then
export DATABASE_URL="${DB_TYPE}://${DB_USER:=kimai}:${DB_PASS:=kimai}@${DB_HOST:=sqldb}:${DB_PORT:=3306}/${DB_BASE:=kimai}"
else
echo "Unknown database type, cannot proceed. Only 'mysql' is supported, received: [$DB_TYPE]"
exit 1
fi
fi

re='^[0-9]+$'
if ! [[ $DB_PORT =~ $re ]] ; then
DB_PORT=3306
function config() {
# set mem limits and copy in custom logger config
if [ -z "$memory_limit" ]; then
memory_limit=256
fi

echo "Wait for MySQL DB connection ..."
until php /dbtest.php $DB_HOST $DB_BASE $DB_PORT $DB_USER $DB_PASS; do
echo Checking DB: $?
sleep 3
done
echo "Connection established"
}

function handleStartup() {
# set mem limits and copy in custom logger config
if [ "${APP_ENV}" == "prod" ]; then
sed "s/128M/${memory_limit}M/g" /usr/local/etc/php/php.ini-production > /usr/local/etc/php/php.ini
if [ "${KIMAI:0:1}" -lt "2" ]; then
cp /assets/monolog-prod.yaml /opt/kimai/config/packages/monolog.yaml
else
assets/monolog.yaml /opt/kimai/config/packages/monolog.yaml
cp /assets/monolog.yaml /opt/kimai/config/packages/monolog.yaml
fi
else
sed "s/128M/${memory_limit}M/g" /usr/local/etc/php/php.ini-development > /usr/local/etc/php/php.ini
if [ "${KIMAI:0:1}" -lt "2" ]; then
cp /assets/monolog-dev.yaml /opt/kimai/config/packages/monolog.yaml
else
assets/monolog.yaml /opt/kimai/config/packages/monolog.yaml
cp /assets/monolog.yaml /opt/kimai/config/packages/monolog.yaml
fi
fi

# These are idempotent, run them anyway
tar -zx -C /opt/kimai -f /var/tmp/public.tgz
/opt/kimai/bin/console -n kimai:install
/opt/kimai/bin/console -n kimai:update
if [ ! -z "$ADMINPASS" ] && [ ! -a "$ADMINMAIL" ]; then
/opt/kimai/bin/console kimai:create-user superadmin $ADMINMAIL ROLE_SUPER_ADMIN $ADMINPASS

if [ -z "$USER_ID" ]; then
USER_ID=$(id -u www-data)
fi
if [ -z "$GROUP_ID" ]; then
GROUP_ID=$(id -g www-data)
fi
export KIMAI=$(/opt/kimai/bin/console kimai:version --short)
echo $KIMAI > /opt/kimai/var/installed
echo "Kimai2 ready"
}

function runServer() {
/opt/kimai/bin/console kimai:reload --env=$APP_ENV
if [ -e /use_apache ]; then
/usr/sbin/apache2ctl -D FOREGROUND
elif [ -e /use_fpm ]; then
exec php-fpm
chown -R $USER_ID:$GROUP_ID /opt/kimai/var

# if user doesn't exist
if id $USER_ID &>/dev/null; then
echo User already exists
else
echo "Error, unknown server type"
echo www-kimai:x:$USER_ID:$GROUP_ID:www-kimai:/var/www:/usr/sbin/nologin >> /etc/passwd
echo www-data:x:33: >> /etc/group
pwconv
fi

if [ -e /use_apache ]; then
export APACHE_RUN_USER=$(id -nu 33)
export APACHE_RUN_GROUP=$(id -ng 33)
elif [ -e /use_fpm ]; then
sed -i "s/user = .*/user = $USER_ID/g" /usr/local/etc/php-fpm.d/www.conf
sed -i "s/group = .*/group = $GROUP_ID/g" /usr/local/etc/php-fpm.d/www.conf
else
echo "Error, unknown server type"
fi
}

waitForDB
handleStartup
runServer
config
/service.sh
exit
33 changes: 33 additions & 0 deletions compose/docker-compose.apache.cli.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
version: '3.5'
services:

sqldb:
image: mysql:5.7
environment:
- MYSQL_DATABASE=kimai
- MYSQL_USER=kimaiuser
- MYSQL_PASSWORD=kimaipassword
- MYSQL_ROOT_PASSWORD=changemeplease
command: --default-storage-engine innodb
restart: unless-stopped
healthcheck:
test: mysqladmin -p$$MYSQL_ROOT_PASSWORD ping -h localhost
interval: 20s
start_period: 10s
timeout: 10s
retries: 3

kimai:
image: kimai/kimai2:apache-dev
ports:
- 8001:8001
environment:
- [email protected]
- ADMINPASS=changemeplease
- DATABASE_URL=mysql://kimaiuser:kimaipassword@sqldb/kimai
- TRUSTED_HOSTS=nginx,localhost,127.0.0.1
restart: unless-stopped
entrypoint: sh
stdin_open: true # docker run -i
tty: true # docker run -t

2 changes: 2 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ services:
- ADMINPASS=changemeplease
- DATABASE_URL=mysql://kimaiuser:kimaipassword@sqldb/kimai
- TRUSTED_HOSTS=nginx,localhost,127.0.0.1
- USER_ID=1009
- GROUP_ID=1009
volumes:
- public:/opt/kimai/public
# - var:/opt/kimai/var
Expand Down
9 changes: 9 additions & 0 deletions docs/runtime-args.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,15 @@ ADMINPASS=
ADMINMAIL=
```

## Changing UID and GID

It is possible to set the user that FPM or Apache run as. If the user does not exist a new user called www-kimai is created and the server is then run under that user.

```bash
USER_ID=1000
GROUP_ID=1000
```

## Alternate DB config

It is possible to pass the DB config in individual values. If the ENV variable ```DB_TYPE``` is set then the following values will be expected:
Expand Down

0 comments on commit 99dea36

Please sign in to comment.