Skip to content
Advertisement

Dynamically pick the user GUI and UID who’s running Docker at the host from entrypoint

I have the following script as the ENTRYPOINT of my Dockerfile and therefore Docker image:

#!/bin/bash
set -e

# Setup permissions
data_dir="/var/www/html"

usermod -u 1000 www-data && groupmod -g 1000 www-data
chown -R www-data:root "$data_dir"

if  [ -d "$data_dir" ]; then
    chgrp -R www-data "$data_dir"
    chmod -R g+w "$data_dir"
    find "$data_dir" -type d -exec chmod 2775 {} +
    find "$data_dir" -type f -exec chmod ug+rw {} +
fi 

# Enable rewrite
a2enmod rewrite expires

# Apache gets grumpy about PID files pre-existing
rm -f /var/run/apache2/apache2.pid

source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND "$@"

Everything is running fine for Linux since the GUI and UID for most of the distros is 1000 (we’re using Fedora and Ubuntu). Windows – I think – doesn’t care about it, but again the script works properly and everything goes well.

The problem comes when I try to run this in Mac (OSX) since the GUI and UID for the first user is 500. That makes the permissions not to work properly.

I know I can always change the values from 500 to 1000 but ….

Is there any way to get this from inside the script so this is transparent for the user?

UPDATE

AS per the answer below, this is how my script looks like:

#!/bin/bash
set -e

# Setup permissions
data_dir="/var/www/html"

usermod -u ${UID} www-data && groupmod -g ${GUID} www-data

chown -R www-data:root "$data_dir"

if  [ -d "$data_dir" ]; then
    chgrp -RH www-data "$data_dir"
    chmod -R g+w "$data_dir"
    find "$data_dir" -type d -exec chmod 2775 {} +
    find "$data_dir" -type f -exec chmod ug+rw {} +
fi

# Enable rewrite
a2enmod rewrite expires

# Apache gets grumpy about PID files pre-existing
rm -f /var/run/apache2/apache2.pid

source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND "$@"

What would happen if I hasn’t defined the UID or GUID? Is there any way to rely on default values as 1000:1000 (first created user)?

Advertisement

Answer

Your best bet is passing (optional) environment variables to your docker container that can be processed by your startup script.

docker-compose.yml:

version: '2.1'
services:
  www:
    image: somenginx
    environment:
      - ${UID}
      - ${GID}

Then use the values of $UID/$GID in your entrypoint script for updating the user’s uid/gid.

Sadly docker-compose does not provide the basic ability to reference the current user’s UID/GID (relevant issue), so this approach requires each user to ensure the environment variables exist on the host. Example ~/.bashrc snippet that would take care of that:

export UID
export GID="$(id -g $(whoami))"

Not quite optimal but at the moment there is no better way unless you have some other host orchestration besides docker/docker-compose. A shell script that handles container start for example would make this trivial. Another approach is templating your docker-compose.yml via some external build tool like gradle that wraps docker-compose and takes care of inserting the current UID/GID before the containers are started.

Advertisement