A
A
Aleksandr Yurchenko2020-10-28 10:23:45
MySQL
Aleksandr Yurchenko, 2020-10-28 10:23:45

How to set permissions in Docker?

I decided to tinker with Docker and make myself an assembly for laravel (LEMP).

Build structure:

  • docker - settings files and Dockerfile for mysql,php,nginx
  • hosts - settings for virtual hosts (nginx)
  • logs - nginx logs
  • mysql - database files
  • www ‒ project directories


I ran into a problem when nginx logs that fall into the ./logs directory are created under root. Accordingly, if you want to delete them, you need to go to the console to: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


Initially, there was a similar problem with MariaDB - all files were created under root, fixed - by running the container not as root user.
mariadb dockerfile

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


I tried the same technique for the Nginx container, but there was a problem.
Dockerfile content for 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


In this form - nginx does not start, errors:
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)

If you try to issue 777 on /var/cache/nginx/ (RUN chmod -R 777 /var/cache/nginx/), another error appears:
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)


I can assume that the problem is related to rights, but I can’t figure out how to make nginx start on behalf of the created user (www) or otherwise get around the problem, that is, give full rights (or www user rights) to the generated logs.

I got acquainted with the docker "just yesterday", so maybe I don't see an obvious solution to the problem. Do not tell me how to fix this problem or can you advise a better option?

Answer the question

In order to leave comments, you need to log in

5 answer(s)
N
nozzy, 2016-05-06
@Pettttttro

Try with a variable

SELECT t1.id AS company_id,
(SELECT @lists_id := GROUP_CONCAT(id) from lists_prod where campaign_id = t1.id),

(SELECT COUNT(*)
  FROM `sent`
        WHERE `list_id` IN (@lists_id)
       ) AS count
       
      FROM companies t1 LIMIT 100;

M
Melkij, 2016-05-05
@melkij

SELECT t1.id AS company_id,
(SELECT COUNT(*)
  FROM `sent`
        WHERE `list_id` IN (SELECT id from lists_prod where campaign_id = t1.id)
       ) AS count
      FROM companies t1 LIMIT 100;

The next step is to rewrite it in join with a subquery.
If you need to do this often, make companies a separate field and save count there. You can keep up-to-date with triggers, you can periodically recalculate, you can do something between these two options.

A
Aleksandr Yurchenko, 2020-10-29
@yaleksandr89

Understood, maybe someone will come in handy ... The problem was: If you run the container (nignx) with lowered rights (not root). You cannot use ports below 1000 , and you must forward the modified nginx.conf from the host to the container.

modified 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


After that, nginx started up and the logs from the container in the host are not created under root

D
Daria Motorina, 2020-10-28
@glaphire

Perhaps something is not completely copied and pasted, there is simply no live project at hand. For my pet projects, I set up docker to work from under my usual user of the system. First, I made docker and docker-compose work as a user (there is an instruction on the Internet, you need to play around with groups of users), then I added this to 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

Then in 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"

I didn't add anything to the dockerfiles. I have it only for php-fpm, but I think that for nginx and mysql it can be done by analogy

S
SlavikF, 2020-10-28
@SlavikF

Here is an example of a container in which nginx and PHP run under the nobody user:
https://github.com/TrafeX/docker-php-nginx/blob/ma...
PS Writing web logs from a container to a file on the host is bad practice .
The standard solution is to write logs to stdout / stderr, and then decide what to do with them on the host.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question