Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Fix #50] Enhance dockerfile with runtime uid/gid flexibility #64

Open
wants to merge 2 commits into
base: next
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions kaldi/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ RUN apt-get update && \
libtool \
pkg-config \
ca-certificates \
gosu \
&& rm -rf /var/lib/apt/lists/*

# Build vosk-kaldi
Expand Down
49 changes: 45 additions & 4 deletions kaldi/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,43 @@ set -ea

echo "RUNNING STT"

# Set default UID and GID (defaults to www-data: 33:33 if not specified)
USER_ID=${USER_ID:-33}
GROUP_ID=${GROUP_ID:-33}

# Default values for user and group names
USER_NAME="appuser"
GROUP_NAME="appgroup"

# Function to create a user/group if needed and adjust permissions
function setup_user() {
echo "Configuring runtime user with UID=$USER_ID and GID=$GROUP_ID"

# Check if a group with the specified GID already exists
if getent group "$GROUP_ID" >/dev/null 2>&1; then
GROUP_NAME=$(getent group "$GROUP_ID" | cut -d: -f1)
echo "A group with GID=$GROUP_ID already exists: $GROUP_NAME"
else
# Create the group if it does not exist
echo "Creating group with GID=$GROUP_ID"
groupadd -g "$GROUP_ID" "$GROUP_NAME"
fi

# Check if a user with the specified UID already exists
if id -u "$USER_ID" >/dev/null 2>&1; then
USER_NAME=$(getent passwd "$USER_ID" | cut -d: -f1)
echo "A user with UID=$USER_ID already exists: $USER_NAME"
else
# Create the user if it does not exist
echo "Creating user with UID=$USER_ID and GID=$GROUP_ID"
useradd -m -u "$USER_ID" -g "$GROUP_NAME" "$USER_NAME"
fi

# Adjust ownership of the application directories
echo "Adjusting ownership of application directories"
chown -R "$USER_NAME:$GROUP_NAME" /usr/src/app
}

# Check model
echo "Checking model format ..."
if [ -z "$MODEL_TYPE" ]
Expand All @@ -22,6 +59,10 @@ then
else
echo "Unknown model type $MODEL_TYPE. Assuming vosk model"
fi

# Setup the runtime user
setup_user

# Launch parameters, environement variables and dependencies check
if [ -z "$SERVICE_MODE" ]
then
Expand All @@ -31,7 +72,7 @@ else
if [ "$SERVICE_MODE" = "http" ]
then
echo "RUNNING STT HTTP SERVER"
python http_server/ingress.py --debug
gosu "$USER_NAME" python http_server/ingress.py --debug
elif [ "$SERVICE_MODE" == "task" ]
then
if [[ -z "$SERVICES_BROKER" ]]
Expand All @@ -41,16 +82,16 @@ else
fi
/usr/src/app/wait-for-it.sh $(echo $SERVICES_BROKER | cut -d'/' -f 3) --timeout=20 --strict -- echo " $SERVICES_BROKER (Service Broker) is up"
echo "RUNNING STT CELERY WORKER"
celery --app=celery_app.celeryapp worker -Ofair --queues=${SERVICE_NAME} -c ${CONCURRENCY} -n ${SERVICE_NAME}_worker@%h
gosu "$USER_NAME" celery --app=celery_app.celeryapp worker -Ofair --queues=${SERVICE_NAME} -c ${CONCURRENCY} -n ${SERVICE_NAME}_worker@%h

elif [ "$SERVICE_MODE" == "websocket" ]
then
echo "Running Websocket server on port ${STREAMING_PORT:=80}"
python websocket/websocketserver.py
gosu "$USER_NAME" python websocket/websocketserver.py
else
echo "ERROR: Must specify an environment variable SERVICE_MODE in [ http | task | websocket ] (got SERVICE_MODE=$SERVICE_MODE)"
exit -1
fi
fi

echo "Service stopped"
echo "Service stopped"
4 changes: 2 additions & 2 deletions whisper/Dockerfile.ctranslate2
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM ghcr.io/opennmt/ctranslate2:latest-ubuntu20.04-cuda12.2
LABEL maintainer="[email protected], [email protected], [email protected]"

RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ffmpeg git curl netcat-traditional
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ffmpeg git curl netcat-traditional gosu

# Install python dependencies
COPY whisper/requirements.ctranslate2.txt ./
Expand All @@ -21,4 +21,4 @@ ENV PYTHONPATH="${PYTHONPATH}:/usr/src/app/stt"

HEALTHCHECK CMD ./healthcheck.sh

ENTRYPOINT ["./docker-entrypoint.sh"]
ENTRYPOINT ["./docker-entrypoint.sh"]
4 changes: 2 additions & 2 deletions whisper/Dockerfile.ctranslate2.cpu
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM python:3.8
LABEL maintainer="[email protected], [email protected], [email protected]"

RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ffmpeg git curl netcat-traditional
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends ffmpeg git curl netcat-traditional gosu

# Install python dependencies
COPY whisper/requirements.ctranslate2.txt ./
Expand All @@ -20,4 +20,4 @@ ENV PYTHONPATH="${PYTHONPATH}:/usr/src/app/stt"

HEALTHCHECK CMD ./healthcheck.sh

ENTRYPOINT ["./docker-entrypoint.sh"]
ENTRYPOINT ["./docker-entrypoint.sh"]
4 changes: 2 additions & 2 deletions whisper/Dockerfile.torch
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM python:3.8
LABEL maintainer="[email protected], [email protected], [email protected]"

RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg curl netcat-traditional
RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg curl netcat-traditional gosu

# Install python dependencies
COPY whisper/requirements.torch.txt ./
Expand All @@ -21,4 +21,4 @@ ENV PYTHONPATH="${PYTHONPATH}:/usr/src/app/stt"

HEALTHCHECK CMD ./healthcheck.sh

ENTRYPOINT ["./docker-entrypoint.sh"]
ENTRYPOINT ["./docker-entrypoint.sh"]
4 changes: 2 additions & 2 deletions whisper/Dockerfile.torch.cpu
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM python:3.8
LABEL maintainer="[email protected], [email protected], [email protected]"

RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg curl netcat-traditional
RUN apt-get update && apt-get install -y --no-install-recommends ffmpeg curl netcat-traditional gosu

# Force CPU versions of torch
RUN pip3 install \
Expand All @@ -26,4 +26,4 @@ ENV PYTHONPATH="${PYTHONPATH}:/usr/src/app/stt"

HEALTHCHECK CMD ./healthcheck.sh

ENTRYPOINT ["./docker-entrypoint.sh"]
ENTRYPOINT ["./docker-entrypoint.sh"]
69 changes: 65 additions & 4 deletions whisper/docker-entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,64 @@ set -a

echo "RUNNING STT"

# Set default UID and GID (defaults to www-data: 33:33 if not specified)
USER_ID=${USER_ID:-33}
GROUP_ID=${GROUP_ID:-33}
#
# Default values for user and group names
USER_NAME="appuser"
GROUP_NAME="appgroup"
#
# Function to create a user/group if needed and adjust permissions
function setup_user() {
echo "Configuring runtime user with UID=$USER_ID and GID=$GROUP_ID"
#
# Check if a group with the specified GID already exists
if getent group "$GROUP_ID" >/dev/null 2>&1; then
GROUP_NAME=$(getent group "$GROUP_ID" | cut -d: -f1)
echo "A group with GID=$GROUP_ID already exists: $GROUP_NAME"
else
# Create the group if it does not exist
echo "Creating group with GID=$GROUP_ID"
groupadd -g "$GROUP_ID" "$GROUP_NAME"
fi
#
# Check if a user with the specified UID already exists
if id -u "$USER_ID" >/dev/null 2>&1; then
USER_NAME=$(getent passwd "$USER_ID" | cut -d: -f1)
echo "A user with UID=$USER_ID already exists: $USER_NAME"
else
# Create the user if it does not exist
echo "Creating user with UID=$USER_ID and GID=$GROUP_ID"
useradd -m -u "$USER_ID" -g "$GROUP_NAME" "$USER_NAME"
fi

# Adjust ownership of the application directories
echo "Adjusting ownership of application directories"
chown -R "$USER_NAME:$GROUP_NAME" /usr/src/app

# Get the user's home directory from the system
USER_HOME=$(getent passwd "$USER_NAME" | cut -d: -f6)

# Ensure the home directory exists
if [ ! -d "$USER_HOME" ]; then
echo "Ensure home directory exists: $USER_HOME"
mkdir -p "$USER_HOME"
chown "$USER_NAME:$GROUP_NAME" "$USER_HOME"
fi

# Grant full permissions to the user on their home directory
# Needed for downloading the models
echo "Granting full permissions to $USER_NAME on $USER_HOME"
chmod -R u+rwx "$USER_HOME"

# Grant full permissions to /opt for user $USER_NAME
# Needed for downloading the models
echo "Granting full permissions to $USER_NAME on /opt"
chmod g+rwx /opt
usermod -aG $(stat -c %G /opt) "$USER_NAME"
}

# Check model
echo "Checking model format ..."
if [ -z "$MODEL" ]
Expand All @@ -11,6 +69,9 @@ then
export MODEL=medium
fi

# Setup the runtime user
setup_user

# Launch parameters, environement variables and dependencies check
if [ -z "$SERVICE_MODE" ]
then
Expand All @@ -20,7 +81,7 @@ else
if [[ "$SERVICE_MODE" == "http" && "$ENABLE_STREAMING" != "true" ]]
then
echo "RUNNING STT HTTP SERVER"
python3 http_server/ingress.py --debug
gosu "$USER_NAME" python3 http_server/ingress.py --debug
elif [ "$SERVICE_MODE" == "task" ]
then
if [[ -z "$SERVICES_BROKER" ]]
Expand All @@ -40,15 +101,15 @@ else
fi
/usr/src/app/wait-for-it.sh $(echo $SERVICES_BROKER | cut -d'/' -f 3) --timeout=20 --strict -- echo " $SERVICES_BROKER (Service Broker) is up" || exit 1
echo "RUNNING STT CELERY WORKER"
celery --app=celery_app.celeryapp worker $OPT -Ofair --queues=${SERVICE_NAME} -c ${CONCURRENCY} -n ${SERVICE_NAME}_worker@%h
gosu "$USER_NAME" celery --app=celery_app.celeryapp worker $OPT -Ofair --queues=${SERVICE_NAME} -c ${CONCURRENCY} -n ${SERVICE_NAME}_worker@%h
elif [[ ("$SERVICE_MODE" == "http" && "$ENABLE_STREAMING" == "true") || "$SERVICE_MODE" == "websocket" ]]
then
echo "Running Websocket server on port ${STREAMING_PORT:=80}"
python3 websocket/websocketserver.py
gosu "$USER_NAME" python3 websocket/websocketserver.py
else
echo "ERROR: Must specify an environment variable SERVICE_MODE in [ http | task | websocket ] (got SERVICE_MODE=$SERVICE_MODE)"
exit -1
fi
fi

echo "Service stopped"
echo "Service stopped"