Користувач у Docker

Андрій Копилов, наш технічний директор, любить, активно використовує та пропагує Docker. У новій статті він розповідає, як створити користувачів у Docker. Правильна робота з ними, чому користувачів не можна залишати з root правами і, як вирішити задачу розбіжності індикаторів в Dockerfile.

Всі процеси в контейнері будуть працювати з-під користувача root, якщо його не вказати спеціальним чином. Це здається дуже зручно, адже цей користувач не має жодних обмежень. Саме тому працювати під рутом неправильно з погляду безпеки. Якщо на локальному комп'ютері ніхто при здоровому глузді не працює з рутовими правами, то багато хто запускає процеси під рутом у контейнерах.

Завжди є баги, які дозволять зловреді вибратися з контейнера та потрапити на хостовий комп'ютер. Припускаючи найгірше, ми повинні забезпечити запуск процесів усередині контейнера від користувача, який не має жодних прав на хостовій машині.

Створення користувача

Створення користувача в контейнері не відрізняється від створення в лінуксових дистрибутивах. Однак, для різних базових образів команди можуть різнитися.

Для дистрибутивів, заснованих на debian, в Dockerfile необхідно додати:

RUN groupadd --gid 2000 node 
  && useradd --uid 2000 --gid node --shell /bin/bash --create-home node

Для Alpine:

RUN addgroup -g 2000 node 
    && adduser -u 2000 -G node -s /bin/sh -D node

Запуск процесів від користувача

Для запуску всіх наступних процесів від користувача з UID 2000 виконайте:

USER 2000

Для запуску всіх наступних процесів від користувача node виконайте:

USER node

Детальніше в документації.

Монтування томів

При монтуванні томів усередину контейнера забезпечте користувачеві можливість читати та (або) писати файли. Для цього користувача UID (GID) у контейнері та користувача за межами контейнера, у якого є відповідні права на доступ до файлу, повинні відповідати. При цьому імена користувачів не мають значення.

Часто на лінуксовому комп'ютері користувача UID і GID рівні 1000. Ці ідентифікатори присвоюються першому користувачеві комп'ютера.

Дізнатися про свої ідентифікатори просто:

id

Ви отримаєте вичерпну інформацію про свого користувача.
Замініть 2000 прикладів на свій ідентифікатор і все буде в порядку.

Присвоєння користувачеві UID та GID

Якщо користувач створений раніше, але необхідно змінити ідентифікатори, можна зробити це так:

RUN usermod -u 1000 node 
  && groupmod -g 1000 node

Якщо ви використовуєте базовий образ alpine, потрібно встановити пакет shadow:

RUN apk add —no-cache shadow

Передача ідентифікатора користувача всередину контейнера при побудові образу

Якщо ваш ідентифікатор та ідентифікатори всіх людей, які працюють над проектом, збігаються, достатньо вказати цей ідентифікатор у Dockerfile. Однак, часто ідентифікатори користувачів не збігаються.

Як здійснити бажане не одразу зрозуміло. Для мене це було найскладнішим у процесі освоєння docker. Багато користувачів docker не замислюються над тим, що є різні етапи життя способу. Спочатку образ збирається для цього, використовуючи Dockerfile. Під час запуску контейнера з Dockerfile вже не використовується.

Створення користувачів має відбуватися під час побудови образу. Це стосується і визначення користувача, з-під якого запускаються процеси. Отже, ми маємо якимось чином передати всередину контейнера UID (GID).

Для використання зовнішніх змінних у Dockerfile служать директиви ENV и ARG. Детальне порівняння директив тут.

Докер-файл

ARG UID=1000
ARG GID=1000
ENV UID=${UID}
ENV GID=${GID}
RUN usermod -u $UID node 
  && groupmod -g $GID node

Надіслати аргументи через docker-compose можна так:

докер-створити

build:
  context: ./src/backend
  args:
    UID: 1000
    GID: 1000

PS Для освоєння всіх премудростей docker недостатньо читати документацію чи статті. Потрібно багато практикуватись, потрібно відчути docker.

Джерело: habr.com

Додати коментар або відгук