Hỏi về lệnh chown trong Dockerfile
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
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 vendor
và node_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 . .
Đ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
@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
@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
@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 ạ
@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é
- 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.
- 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 ?
Thank bạn! Bạn có thể nói rõ hơn cách làm của ý 2. đc ko ?
@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