Кросс-ОС-совместимый способ отображения пользователя в докере - PullRequest
0 голосов
/ 26 февраля 2019

Введение

Я создаю проект, в котором мы пытаемся использовать docker для всего.

Это проект php (symfony) + npm.У нас есть рабочие и боевые испытания (мы используем эту установку более года в нескольких проектах) docker-compose.yaml.

Но чтобы сделать его более удобным для разработчиков, я предложил настроить папку bin-docker, то есть, используя direnv , помещенную первой в пользовательскую переменную PATH

/.envrc:

export PATH="$(pwd)/bin-docker:$PATH"

Папка содержит файлы, которые должны заменить файлы bin на файлы в докере

❯ tree bin-docker
bin-docker
├── _tty.sh
├── composer
├── npm
├── php
└── php-xdebug

Например php файл содержит:

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PROJECT_ROOT="$(dirname "$DIR")"

source ${DIR}/_tty.sh

if [ $(docker-compose ps php | grep Up | wc -l) -gt 0 ]; then
    docker_compose_exec \
        --workdir=/src${PWD:${#PROJECT_ROOT}} \
        php php "$@"
else
    docker_compose_run \
        --entrypoint=/usr/local/bin/php \
        --workdir=/src${PWD:${#PROJECT_ROOT}} \
        php "$@"
fi

npm:

#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PROJECT_ROOT="$(dirname "$DIR")"

source ${DIR}/_tty.sh

docker_run --init \
    --entrypoint=npm \
    -v "$PROJECT_ROOT":"$PROJECT_ROOT" \
    -w "$(pwd)" \
    -u "$(id -u "$USER"):$(id -g "$USER")" \
    mangoweb/mango-cli:v2.3.2 "$@"

Это прекрасно работает, вы можете просто использовать Symfony's bin/console, и он будет «волшебным образом» работать в док-контейнере.

Проблема

Единственная проблема, и мой вопрос заключается в том, как правильно сопоставить пользователя хоста с пользователем контейнера.Правильно для всех основных ОС (macOS, Windows (WSL), Linux), потому что наши разработчики используют их все.Я буду говорить о npm, потому что он использует общедоступный образ, который любой может загрузить.

Когда я вообще не сопоставляю пользователя, в Linux файлы, создаваемые в смонтированном томе, принадлежат пользователю root, и пользователи должны впоследствии выполнить chmod для файлов.Совсем не идеально.

Когда я использую -u "$(id -u "$USER"):$(id -g "$USER")", он ломается, потому что у пользователя в контейнере нет прав на создание папки кэша в контейнере, также для стандартного UID macOS это 501, что нарушаетвсе.

Как правильно отобразить пользователя или есть какой-либо другой лучший способ выполнить какую-либо часть этой настройки?

Вложения:

docker-compose.yaml: (Сокращено из конфиденциальной или не важной информации)

version: '2.4'

x-php-service-base: &php-service-base
    restart: on-failure
    depends_on:
        - redis
        - elasticsearch
    working_dir: /src
    volumes:
        - .:/src:cached

    environment:
        APP_ENV: dev
        SESSION_STORE_URI: tcp://redis:6379

services:
    elasticsearch:
        image: docker.elastic.co/elasticsearch/elasticsearch:6.2.3
        environment:
            discovery.type: single-node
            xpack.security.enabled: "false"

    kibana:
        image: docker.elastic.co/kibana/kibana:6.2.3
        environment:
            SERVER_NAME: localhost
            ELASTICSEARCH_URL: http://elasticsearch:9200
        depends_on:
            - elasticsearch

    redis:
        image: redis:4.0.8-alpine

    php:
        <<: *php-service-base
        image: custom-php-image:7.2

    php-xdebug:
        <<: *php-service-base
        image: custom-php-image-with-xdebug:7.2

    nginx:
        image: custom-nginx-image
        restart: on-failure
        depends_on:
            - php
            - php-xdebug

_tty.sh: Только для правильной передачи статуса tty в докер * run 1050 *

if [ -t 1 ]; then
    DC_INTERACTIVITY=""
else
    DC_INTERACTIVITY="-T"
fi

function docker_run {
    if [ -t 1 ]; then
        docker run --rm --interactive --tty=true "$@"
    else
        docker run --rm --interactive --tty=false "$@"
    fi
}

function docker_compose_run {
    docker-compose run --rm $DC_INTERACTIVITY "$@"
}

function docker_compose_exec {
    docker-compose exec $DC_INTERACTIVITY "$@"
}

1 Ответ

0 голосов
/ 24 апреля 2019

Это может решить вашу проблему. Я наткнулся на руководство по настройке пользовательских пространств имен в Ubuntu. Обратите внимание, что сценарий использования в руководстве предназначен для использования nvidia-docker и ограничения разрешений.В частности, д-р Кингхорн в своей истории пишет:

Основная идея пространства имен пользователя заключается в том, что UID процессов (идентификатор пользователя) и GID (идентификатор группы) могут отличаться внутри и снаружипространство имен контейнеров.Важным следствием этого является то, что контейнер может иметь корневой процесс, сопоставленный с непривилегированным идентификатором пользователя на хосте.

Что звучит так, как вы ищете.Надеюсь, это поможет.

...