跨OS兼容方式在Docker中映射用户

介绍

我正在建立一个项目,我们尝试在其中使用docker.

这是php(symfony)npm项目.我们已经工作并经过了战斗测试(我们在多个项目上使用此设置已超过一年)docker-compose.yaml.

但是为了使开发人员更友好,我想出了设置bin-docker文件夹的方法,即使用direnv将该文件夹放置在用户的PATH中

/.envrc:

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

文件夹包含文件,这些文件应该用docker内的替换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的bin / console即可“神奇地”在docker-container中运行.

问题

唯一的问题和我的问题是,如何正确地将主机用户映射到容器的用户.适用于所有主要操作系统(macOS,Windows(WSL),Linux),因为我们的开发人员都使用了它们.我将讨论npm,因为它使用任何人都可以下载的公共图像.

当我完全不映射用户时,在Linux上,在挂载卷中创建的文件是root拥有的,然后用户必须chmod这些文件.一点都不理想.

当我使用-u“ $(id -u” $USER“):$(id -g” $USER“)”时,它中断了,因为容器内用户现在无权在容器中创建缓存文件夹,在macOS标准上,UID是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状态正确传递给docker run

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 "$@"
}
最佳答案
这可能会回答您的问题.
I came across a tutorial as to how to do setup user namespaces in Ubuntu.注意,本教程中的用例用于使用nvidia-docker和限制权限.金霍恩博士在历史上特别指出:

The main idea of a user-namespace is that a processes UID (user ID) and GID (group ID) can be different inside and outside of a containers namespace. The significant consequence of this is that a container can have it’s root process mapped to a non-privileged user ID on the host.

听起来像您要找的东西.希望这可以帮助.

相关文章

文章浏览阅读8.8k次,点赞2次,收藏7次。本文介绍Docker Com...
文章浏览阅读1.5w次,点赞7次,收藏76次。原网提供的教程需要...
文章浏览阅读940次,点赞20次,收藏20次。通过 docker run 命...
文章浏览阅读1k次,点赞20次,收藏20次。Podman 是一个开源的...
文章浏览阅读2.1k次。请注意,这些命令需要在 Docker 主机上...
文章浏览阅读1.1k次,点赞37次,收藏40次。nacos搭建集群连接...