Введение
Я создаю проект, в котором мы пытаемся использовать 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 "$@"
}