Yêu cầu thg 7 12, 2021 12:56 CH 778 3 2
  • 778 3 2
+3

Hỏi về lệnh chown trong Dockerfile

Chia sẻ
  • 778 3 2

Chào mọi người, em đang dùng Dockerfile để build image.
Tuy nhiên gặp một vấn đề mà em chưa biết nó sai ở đâu, mong mọi người giúp đỡ.

FROM php:7.4-fpm

# Set working directory
WORKDIR /var/www

# Copy composer.lock and composer.json
# COPY composer.lock composer.json /var/www/

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip \
    vim \
    supervisor 

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd

# Install PHP Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Use the default production configuration for PHP-FPM ($PHP_INI_DIR variable already set by the default image)
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

# Add UID '1000' to www-data
RUN usermod -u 1000 www-data

# Copy existing application directory
COPY . .

# Chang app directory permission
RUN chown -R www-data:www-data .

# Setup supervisord
COPY .docker/supervisord.conf /etc/supervisord.conf
COPY .docker/supervisor.d /etc/supervisor.d


CMD supervisord -n -c /etc/supervisord.conf

Mặc dù image của em build thành công, chạy container cũng ko vấn đề. Nhưng em nhận thấy lệnh RUN chown -R www-data:www-data . không hề đc phản ánh, kiểu vô tác dụng.
Khi em exec vào bên trong container ls la thì permission vẫn đang là root:root.
Hình như có lỗi gì đó, nên khi build image, e thấy nó rất lâu và đứng lại ở lệnh chown cả 5 phút.

Mọi người cho em hỏi là có vấn đề gì với Dockerfile của em ko ạ.
Em cảm ơn.

2 CÂU TRẢ LỜI


Đã trả lời thg 7 12, 2021 2:02 CH
Đã được chấp nhận
+4

e thấy nó rất lâu và đứng lại ở lệnh chown cả 5 phút

cái đó là do nó phải đổi permission cho từng file ở trong vendornode_modules(nếu có) nên lâu e nhé

Về lỗi đã chạy RUN chown ... mà vẫn ko thay được permission, thì khả năng cao là do e đang mount toàn bộ source từ bên ngoài vào, nên nó ăn theo permission bên ngoài (confirm lại có phải thế ko e nhé)

khi build docker image, thường nếu người ta muốn đổi permission thì họ làm trực tiếp tại bước COPY luôn, ví dụ trong trường hợp của e:

COPY --chown=www-data:www-data . .

Đoạn này a hiểu là e đang follow theo bài của a nên mới làm vậy, để a update lại bài của a 😄

Chia sẻ
Avatar iamfresher @benkyou
thg 7 23, 2021 2:22 CH

@maitrungduc1410 e thử đổi theo cách này, nhưng lúc check lại nó vẫn ko chown đc, quyền vẫn là root ạ..
A xem giúp em xem có sai gì ko ạ?

FROM php:7.4-fpm

# Set working directory
WORKDIR /var/www

# Copy composer.lock and composer.json
# COPY composer.lock composer.json /var/www/

# Install system dependencies
RUN apt-get update && apt-get install -y \
    git \
    curl \
    libpng-dev \
    libonig-dev \
    libxml2-dev \
    zip \
    unzip \
    libzip-dev \
    vim \
    supervisor \
    mariadb-client

# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*

# Install PHP extensions
RUN docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd zip

# Install PHP Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer

# Use the default production configuration for PHP-FPM ($PHP_INI_DIR variable already set by the default image)
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini"

# Add UID '1000' to www-data
RUN usermod -u 1000 www-data

# Copy existing application directory and change permision
# COPY . .
# RUN chown -R www-data:www-data .
COPY --chown=www-data:www-data . .

# Setup supervisord
COPY .docker/supervisord.conf /etc/supervisord.conf
COPY .docker/supervisor.d /etc/supervisor.d

Avatar Mai Trung Đức @maitrungduc1410
thg 7 23, 2021 3:02 CH

@benkyou note câu này của a nhé "thì khả năng cao là do e đang mount toàn bộ source từ bên ngoài vào, nên nó ăn theo permission bên ngoài"

lúc chạy container lên, thì e có mount source code từ ngoài vào ko, nếu làm như bài a hướng dẫn thì có, thì nó sẽ lấy theo permission từ phía ngoài.

để test xem cấu hình DOckerfile của e có ok hay ko, thì e bỏ mount volume (ở docker-compose.yml) ra nhé, sau đó chạy lên và exec vào e sẽ thấy

Avatar iamfresher @benkyou
thg 7 26, 2021 12:47 SA

@maitrungduc1410 Dạ đúng là e đang mount từ bên ngoài vào ạ.
E bỏ mount đi, exec bình thường thì thấy nó phản ánh đúng permission.
Vậy giờ có cách nào mount mà vẫn giữ đúng đc permission ko ạ

Avatar Mai Trung Đức @maitrungduc1410
thg 7 26, 2021 2:38 SA

@benkyou vì file từ bên ngoài sẽ luôn luôn override bên trong khi e mount vào.

Nên a nghĩ solution là e setup file bên trong sao cho nó thuộc sở hữu của user bên ngoài, cách làm:

  • ở môi trường ngoài check uid + gid user hiện tại bằng command “id -u” và “id -g”
  • trong dockerfile tạo 1 user với đúng uid + gid như vậy, và dùng user đó
  • trước khi start container thì chuyển về user đó (USER my_user) và chuyển toàn bộ tất cả các file về thuộc sở hữu của user đó luôn (chown)
  • xong 😃)

Nếu vẫn có thắc mắc thì xem bài chạy docker container với non root user của a nhé

Đã trả lời thg 7 13, 2021 6:28 SA
+2
  1. trong docker để set quyền tốt nhất dùng USERID, đừng dùng chown làm gì, cái này sẽ tránh được việc xung đột quyền giữa các container, vì 1 file có thể sẽ được mount vào nhiều container
RUN usermod -u 1000 www-data

Câu lệnh này sẽ làm user www-data có tất cả quyền tương ứng user có id 1000 ở docker host (os linux của bạn), mà user đang có quyền ower của project chưa chắc có USERID=1000 thì sẽ chẳng có tác dụng gì cả.

=> Hãy sử dụng env hoặc arg để đặt USERID, vì env sẽ đè arg, env varible ở ngoài sẽ đè biến env trong docker nên bạn hãy set theo thứ tự này.

  1. Tại sao không mount nó vào giữ nguyên quyền rồi set user bên trong container có quyền giống user ngoài mà phải copy ?
Chia sẻ
Avatar iamfresher @benkyou
thg 7 16, 2021 6:59 SA

Thank bạn! Bạn có thể nói rõ hơn cách làm của ý 2. đc ko ?

thg 7 29, 2021 7:31 SA

@benkyou bạn mount vào như đường dẫn bạn copy, trong container bạn tạo 1 user với userID giống như user ở bên ngoài

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí