Skip to content

Commit

Permalink
Merge pull request #156 from ucam-department-of-psychiatry/docker-use…
Browse files Browse the repository at this point in the history
…r-has-group

Ensure the crate user in the Docker image belongs to a group
  • Loading branch information
martinburchell authored Jun 24, 2024
2 parents 16041d4 + 1fa66ec commit 8fca559
Show file tree
Hide file tree
Showing 8 changed files with 84 additions and 8 deletions.
5 changes: 4 additions & 1 deletion docker/dockerfiles/crate.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,10 @@ LABEL maintainer="Rudolf Cardinal <[email protected]>"
# https://vsupalov.com/docker-shared-permissions/

ARG USER_ID
RUN adduser --disabled-password --gecos '' --uid $USER_ID crate
ARG GROUP_ID

RUN addgroup --gid $GROUP_ID crate
RUN adduser --disabled-password --gecos '' --uid $USER_ID --gid $GROUP_ID crate

FROM crate-build-1-user AS crate-build-2-files

Expand Down
3 changes: 3 additions & 0 deletions docker/dockerfiles/docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
# CRATE_DOCKER_CONFIG_HOST_DIR
# CRATE_DOCKER_FILES_HOST_DIR
# CRATE_DOCKER_GATE_BIOYODIE_RESOURCES_HOST_DIR
# CRATE_DOCKER_INSTALL_GROUP_ID
# CRATE_DOCKER_INSTALL_USER_ID
# CRATE_DOCKER_MYSQL_CRATE_USER_PASSWORD
# CRATE_DOCKER_MYSQL_CRATE_ROOT_PASSWORD
# CRATE_DOCKER_STATIC_HOST_DIR
Expand Down Expand Up @@ -157,6 +159,7 @@ services:

args:
- USER_ID=${CRATE_DOCKER_INSTALL_USER_ID}
- GROUP_ID=${CRATE_DOCKER_INSTALL_GROUP_ID}
- GATE_VERSION=${CRATE_DOCKER_GATE_VERSION}

# If you specify "image" as well as "build", Compose names the built
Expand Down
2 changes: 2 additions & 0 deletions docs/source/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1658,6 +1658,8 @@ Changes

**0.20.5, in progress**

- When the Docker image is built, it is now possible to specify both a user ID and a group ID
so that file systems shared between the host and the container have the correct permissions.

To do
-----
Expand Down
20 changes: 19 additions & 1 deletion docs/source/installation/docker.rst
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,8 @@ GATE). (You need to download UMLS data and use the
directory used with that command is the directory you should specify here.)
On Windows, ensure this is within the Windows (not WSL2) file system.

.. _CRATE_DOCKER_GATE_VERSION:

.. _CRATE_DOCKER_GATE_VERSION:

CRATE_DOCKER_GATE_VERSION
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand All @@ -317,6 +317,24 @@ CRATE_DOCKER_GATE_VERSION
Version of GATE to be installed.


.. _CRATE_DOCKER_INSTALL_GROUP_ID:

CRATE_DOCKER_INSTALL_GROUP_ID
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**No default. Must be set to the ID of a group on the host so that file systems can be shared.**
See :ref:`CRATE_DOCKER_INSTALL_USER_ID <CRATE_DOCKER_INSTALL_USER_ID>`


.. _CRATE_DOCKER_INSTALL_USER_ID:

CRATE_DOCKER_INSTALL_USER_ID
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

**No default. Must be set to the ID of a user on the host so that file systems can be shared.**
See :ref:`CRATE_DOCKER_INSTALL_GROUP_ID <CRATE_DOCKER_INSTALL_GROUP_ID>`


.. _CRATE_DOCKER_MYSQL_CRATE_DATABASE_NAME:

CRATE_DOCKER_MYSQL_CRATE_DATABASE_NAME
Expand Down
6 changes: 5 additions & 1 deletion github_action_scripts/python_checks.sh
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,8 @@ echo checking packages for vulnerabilities
# install malicious packages.
# 67599 pip. Disputed and only relevant if using --extra-index-url,
# which we're not.
${SAFETY} check --full-report --ignore=51668 --ignore=52495 --ignore=67599
# 70612 jinja2. The maintainer and multiple third parties
# believe that this vulnerability isn't valid because
# users shouldn't use untrusted templates without
# sandboxing.
${SAFETY} check --full-report --ignore=51668 --ignore=52495 --ignore=67599 --ignore=70612
1 change: 1 addition & 0 deletions github_action_scripts/set_crate_docker_environment
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export CRATE_DOCKER_CRATE_DB_ROOT_PASSWORD=shoobydoobydoo
export CRATE_DOCKER_CRATE_DB_USER_PASSWORD=ramalamadingdong
export CRATE_DOCKER_FILES_HOST_DIR=${HOME}/crate_files
export CRATE_DOCKER_GATE_BIOYODIE_RESOURCES_HOST_DIR=${HOME}/bioyodie_resources
export CRATE_DOCKER_INSTALL_GROUP_ID=$(id -g)
export CRATE_DOCKER_INSTALL_USER_ID=$(id -u)
export CRATE_DOCKER_ODBC_USER_CONFIG="odbc_user.ini"
export CRATE_DOCKER_STATIC_HOST_DIR=${HOME}/crate_static
Expand Down
49 changes: 47 additions & 2 deletions installer/installer.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

from argparse import ArgumentParser
import collections
import grp
import os
from pathlib import Path
from platform import uname
Expand Down Expand Up @@ -184,6 +185,7 @@ class DockerEnvVar(EnvVar):
f"{PREFIX}_GATE_BIOYODIE_RESOURCES_HOST_DIR"
)
IMAGE_TAG = f"{PREFIX}_IMAGE_TAG"
INSTALL_GROUP_ID = f"{PREFIX}_INSTALL_GROUP_ID"
INSTALL_USER_ID = f"{PREFIX}_INSTALL_USER_ID"

CRATE_DB_DATABASE_NAME = f"{PREFIX}_CRATE_DB_DATABASE_NAME"
Expand Down Expand Up @@ -640,6 +642,7 @@ def check_setup(self) -> None:
def configure(self) -> None:
try:
self.configure_user()
self.configure_group()
self.configure_tag()
self.configure_config_files()
self.configure_files_dir()
Expand All @@ -663,6 +666,11 @@ def configure_user(self) -> None:
DockerEnvVar.INSTALL_USER_ID, self.get_docker_install_user_id
)

def configure_group(self) -> None:
self.setenv(
DockerEnvVar.INSTALL_GROUP_ID, self.get_docker_install_group_id
)

def configure_tag(self) -> None:
tag = self.env_dict[DockerEnvVar.IMAGE_TAG]
self.setenv(DockerEnvVar.IMAGE_TAG, tag)
Expand Down Expand Up @@ -1270,9 +1278,46 @@ def report_status(self) -> None:
# Fetching information from environment variables or statically
# -------------------------------------------------------------------------

def get_docker_install_user_id(self) -> str:
return str(self._get_user_id())

def get_docker_install_group_id(self) -> str:
self.info(
"The CRATE Docker image will be created with your user ID and one "
"of your user's group IDs so that file permissions will be "
"correct for any file systems shared between the host and "
"container."
)
# This is a bit slow with sssd
self.info("Fetching groups...")
choice_dict = {}

# https://stackoverflow.com/questions/9323834/python-how-to-get-group-ids-of-one-username-like-id-gn
# Works with sssd. Maybe not everything else.
for group_id in os.getgroups():
# Ignore any groups created by the OS so we don't clash when we try
# to create a group with the same ID on the server
if group_id >= 1000:
try:
choice_dict[str(group_id)] = grp.getgrgid(group_id).gr_name
except KeyError:
# One poster reported that this happens for some reason
pass

if len(choice_dict) == 1:
self.info("Only one group found for this user. Using that.")
return next(iter(choice_dict))

return self.get_user_choice(
"Select the group to use. If a mounted file system needs to "
"be shared between multiple users, choose a group that includes "
"all of those users.",
choice_dict,
)

@staticmethod
def get_docker_install_user_id() -> str:
return str(os.geteuid())
def _get_user_id() -> int:
return os.geteuid()

@staticmethod
def get_hmac_md5_key() -> str:
Expand Down
6 changes: 3 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,10 @@
"pyramid==1.10.4", # Pyramid web framework
"pyramid_tm==2.4", # Pyramid transaction management
"redis==4.5.4", # interface to Redis in-memory key-value database
"requests==2.32.0", # HTTP requests
"tornado==6.3.3", # web framework
"requests==2.32.2", # HTTP requests
"tornado==6.4.1", # web framework
"transaction==3.0.0", # generic transaction management
"urllib3==1.26.18", # used by requests
"urllib3==1.26.19", # used by requests
"waitress==2.1.2", # pure-Python WSGI server
"zope.sqlalchemy==1.3", # Zope/SQLAlchemy transaction integration
# -------------------------------------------------------------------------
Expand Down

0 comments on commit 8fca559

Please sign in to comment.