Задать вопрос
yaleksandr89
@yaleksandr89
PHP developer

Как настроить права в Docker?

Решил поразбираться в Docker и сделать себе сборку для laravel (LEMP).

Структура сборки:
  • docker - файлы настроек и Dockerfile для mysql,php,nginx
  • hosts - настройки вир.хостов (nginx)
  • logs - логи nginx
  • mysql - файлы БД
  • www ‒ директории проектов


Столкнулся с проблемой, когда логи nginx, которые попадают в директорию ./logs - создаются под root. Соответственно, если требуется их удалить - необходимо лезть в консоль для: sudo rm *.log
docker-compose.yml

version: '3'
services:
  #Php-fpm Service
  app:
    build:
      context: ./docker/php/
      dockerfile: php-fpm.docker
    container_name: app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./www:/var/www
      - ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
    links:
      - db
    networks:
      - laravel-network

  #Nginx Service
  webserver:
    build:
      context: ./docker/nginx/
      dockerfile: nginx.docker
    container_name: webserver
    restart: unless-stopped
    tty: true
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./www:/var/www
      - ./hosts/:/etc/nginx/conf.d
      - ./logs:/var/log/nginx
    links:
      - app
      - db
    networks:
      - laravel-network

  #MariaDB Service
  db:
    build:
      context: ./docker/mysql/
      dockerfile: mariadb.docker
    container_name: db
    restart: unless-stopped
    tty: true
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: secret
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - ./mysql:/var/lib/mysql/
      - ./docker/mysql/my.cnf:/etc/mysql/my.cnf
    networks:
      - laravel-network

  #PHPMyadmin Service
  pma:
    image: phpmyadmin:latest
    container_name: pma
    restart: unless-stopped
    tty: true
    ports:
      - 81:80
    environment:
      PMA_HOST: db
      MYSQL_USERNAME: root
      MYSQL_ROOT_PASSWORD: secret
    links:
      - db
    networks:
      - laravel-network


#Docker Networks
networks:
  laravel-network:
    driver: bridge


Изначально была аналогичная проблема с MariaDB - все файлы создавались под root, пофиксил - запустив контейнер не от root пользователя.
Dockerfile для mariadb

FROM mariadb:latest

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
USER www


Такой же прием попробовал применить для контейнера Nginx, но возникла проблема.
Содержание Dockerfile для nginx

FROM nginx

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www

USER www


В таком виде - nginx не стартует, ошибки:
webserver    | 2020/10/28 07:09:25 [warn] 1#1: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
webserver    | nginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
webserver    | 2020/10/28 07:09:25 [emerg] 1#1: mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)
webserver    | nginx: [emerg] mkdir() "/var/cache/nginx/client_temp" failed (13: Permission denied)

Если попробовать выдать 777 на /var/cache/nginx/ (RUN chmod -R 777 /var/cache/nginx/), то появляется другая ошибка:
webserver    | 2020/10/28 07:12:54 [warn] 1#1: the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
webserver    | nginx: [warn] the "user" directive makes sense only if the master process runs with super-user privileges, ignored in /etc/nginx/nginx.conf:2
webserver    | 2020/10/28 07:12:54 [emerg] 1#1: bind() to 0.0.0.0:80 failed (13: Permission denied)
webserver    | nginx: [emerg] bind() to 0.0.0.0:80 failed (13: Permission denied)


Могу предположить - проблема связана с правами, но я не могу разобраться, как заставить nginx стартовать от имени созданного пользователя (www) или иным способом обойти проблему, то есть выдать на создаваемые логи полные права (или права www пользователя).

С докером познакомился "буквально вчера", поэтому может не вижу очевидного решения проблемы. Не подскажите, как пофиксить данную проблему или может посоветуете вариант получше?
  • Вопрос задан
  • 4507 просмотров
Подписаться 2 Средний Комментировать
Решения вопроса 1
yaleksandr89
@yaleksandr89 Автор вопроса
PHP developer
Разобрался, может будет кому пригодится... Проблема заключалась: Если запускать контейнер (nignx) с понижением прав (не root). Нельзя использовать порты ниже 1000, а также с хоста в контейнер нужно пробросить модифицированный nginx.conf.

модифицированный nginx.conf

# worker_processes по количеству ядер процессора
worker_processes  6;

error_log  /var/log/nginx/error.log warn;
pid        /tmp/nginx.pid;

events {
    worker_connections  1024;
}

http {
    client_body_temp_path /tmp/client_body_temp;
    proxy_temp_path /tmp/proxy_temp;
    fastcgi_temp_path /tmp/fastcgi_temp;
    uwsgi_temp_path /tmp/uwsgi_temp;
    scgi_temp_path /tmp/scgi_temp;

    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    #gzip  on;

    include /etc/nginx/conf.d/*.conf;
}


docker-compose.yml

version: '3'
services:
  #Php-fpm Service
  app:
    build:
      context: ./docker/php/
      dockerfile: Dockerfile
    container_name: app
    restart: unless-stopped
    tty: true
    environment:
      SERVICE_NAME: app
      SERVICE_TAGS: dev
    working_dir: /var/www
    volumes:
      - ./www:/var/www
      - ./logssss:/var/log/
      - ./docker/php/local.ini:/usr/local/etc/php/conf.d/local.ini
    links:
      - db
    networks:
      - laravel-network

  #Nginx Service
  webserver:
    build:
      context: ./docker/nginx/
      dockerfile: Dockerfile
    container_name: webserver
    restart: unless-stopped
    tty: true
    ports:
      - '80:8080'
      - '443:4430'
    volumes:
      - ./www:/var/www
      - ./hosts/:/etc/nginx/conf.d
      - ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./logs:/var/log/nginx
    links:
      - app
      - db
    networks:
      - laravel-network

  #MariaDB Service
  db:
    build:
      context: ./docker/mysql/
      dockerfile: Dockerfile
    container_name: db
    restart: unless-stopped
    tty: true
    ports:
      - "3306:3306"
    environment:
      MYSQL_DATABASE: laravel
      MYSQL_ROOT_PASSWORD: secret
      SERVICE_TAGS: dev
      SERVICE_NAME: mysql
    volumes:
      - ./mysql:/var/lib/mysql/
      - ./docker/mysql/my.cnf:/etc/mysql/my.cnf
    networks:
      - laravel-network

  #PHPMyadmin Service
  pma:
    image: phpmyadmin:latest
    container_name: pma
    restart: unless-stopped
    tty: true
    ports:
      - 81:80
    environment:
      PMA_HOST: db
      MYSQL_USERNAME: root
      MYSQL_ROOT_PASSWORD: secret
    links:
      - db
    networks:
      - laravel-network


#Docker Networks
networks:
  laravel-network:
    driver: bridge


Dockerfile(Nginx)

FROM nginx

# Add user for laravel application
RUN groupadd -g 1000 www
RUN useradd -u 1000 -ms /bin/bash -g www www
USER www


После этого и nginx завелся и логи из контейнера в хосте создаются не под root
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
glaphire
@glaphire
PHP developer
Возможно что-то не до конца скопипастила, просто нет живого проекта под рукой. Для своих пет проектов я настроила работу докера из под моего обычного юзера системы. Сначала сделала так, чтобы docker и docker-compose работали от юзера (есть инструкция в интернете, надо пошаманить с группами юзеров), потом в docker-compose.env добавила такое
#run echo $(id -u):$(id -g) and copypaste it to HOST_USER variable
#HOST_USER is needed to run docker containers under current user on host machine
HOST_USER=1234:1234

Потом в docker-compose.yml
version: "3"
services:
    nginx:
        image: nginx:latest
        ports:
            - "8081:80"
        volumes:
            - .:/app
            - ./docker/nginx/:/etc/nginx/conf.d/
        depends_on:
            - php-fpm
        working_dir: /app
        networks:
            - internal
    php-fpm:
        user: ${HOST_USER}
        working_dir: /app
        build:
            context: ./docker/php-fpm
            dockerfile: Dockerfile
        volumes:
            - .:/app
            - ./docker/php-fpm/log/:/var/log/
            - /etc/group:/etc/group:ro #####вот
            - /etc/passwd:/etc/passwd:ro #####вот
        ports:
            - '9000:9000'
        networks:
            - internal
        environment:
            XDEBUG_CONFIG: "remote_host=192.168.220.1 remote_enable=1"
            PHP_IDE_CONFIG: "serverName=PHPSTORM"

В докерфайлах ничего не дописывала. У меня это только для php-fpm, но думаю что для nginx и mysql можно делать по аналогии
Ответ написан
SlavikF
@SlavikF
Вот тут есть пример контейнера в котором nginx и PHP работают под пользователем nobody:

https://github.com/TrafeX/docker-php-nginx/blob/ma...

P.S. писать веб логи из контейнера в файл на хосте - плохая практика.
Стандартное решение - писать логи в stdout / stderr, а уже на хосте решать что с ними делать.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы