Chạy docker mount volume trong môi trường dev (Nguồn ảnh: blaize.net)
Tình huống
Khi dev với Docker, thường thì chúng ta sẽ mount thư mục code vào Docker Container. Khi thay đổi code ở máy dev thì trong code trong container thay đổi luôn, không cần build lại.
Vấn đề
- Với máy Linux, user ở máy dev thường có user_id = 1000.
- Trong container, thường chạy với user root, có user_id khác 1000.
→ Gặp vấn đề: ở máy dev không sửa được file, gặp lỗi “Permission Denied” vì không phải là owner của file source code.
Ví dụ: Khi chạy container wordpress, thư mục /var/www/html có owner là www-data:www-data
1 2 |
root@wordpress:/var/www/html# ls -ld /var/www/html/ drwxr-xr-x 5 www-data www-data 4096 Jul 26 15:54 /var/www/html/ |
Khi ở máy dev, thực hiện sửa file sẽ bị lỗi “Permission Denied”
1 2 3 4 5 6 7 8 9 10 11 12 13 |
➜ $ ls -la total 204K drwxr-xr-x 5 www-data www-data 4.0K Jun 13 13:54 . drwxr-xr-x 5 cuongtran cuongtran 4.0K Jun 29 01:16 .. -rw-r--r-- 1 www-data www-data 235 Jun 13 13:52 .htaccess -rw-r--r-- 1 www-data www-data 418 Sep 25 2013 index.php -rw-r--r-- 1 www-data www-data 20K Jun 13 13:53 license.txt -rw-r--r-- 1 root root 72 Jun 13 13:54 php.ini -rw-r--r-- 1 www-data www-data 7.2K Jun 13 13:53 readme.html cuongtran@coc-ubu [/data/compose/wordpress/wordpress-data] git:(master) [23:40:53] ➜ $ touch hello.html touch: cannot touch 'hello.html': Permission denied |
Giải pháp
Thực hiện đổi user_id của user trong container, sao cho giống với user_id của máy dev. Cần build Docker Image theo cách sau:
- Sử dụng biến MAP_USERID để có thể truyền giá trị biến phù hợp.
- Khi chạy Docker Container, câu lệnh đầu tiên được chạy là docker-entrypoint.sh, sẽ thực hiện việc sửa user_id và chown thư mục phù hợp.
Ví dụ: docker-entrypoint.sh
1 2 3 4 5 6 7 8 |
# Set default WWW_DATA_USERID if not exist # password is limited by 8 characters : ${WWW_DATA_USERID:=33} usermod -u $WWW_DATA_USERID www-data groupmod -g $WWW_DATA_USERID www-data chown -R www-data:www-data /var/www/html |
Khi chạy với docker-compose, có thể dùng docker-compose.yml có dạng sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
version: "2" services: wordpress: image: cuongtransc/wordpress:4.8 depends_on: - mariadb environment: - WORDPRESS_DB_HOST=mariadb - WORDPRESS_DB_USER=wordpress - WORDPRESS_DB_PASSWORD=wordpress@123 - WORDPRESS_DB_NAME=wordpress - WWW_DATA_USERID=1000 |
Ngoài ra, có thể sử dụng kết hợp gosu và chạy process trong container dưới quyền user thường, không phải user root để đảm bảo vấn đề security.
Tài liệu tham khảo
- https://github.com/cuongtransc/docker-training
- https://github.com/cuongtransc/docker-image-tmpl
- https://github.com/tianon/gosu
Cuong Tran
Latest posts by Cuong Tran (see all)
- Thay đổi owner của mount volume khi dev với Docker - 2017-07-27
- Các cách build docker image cần biên dịch mã nguồn - 2017-05-17
- Tổng kết sự kiện “Định hướng phát triển cá nhân” - 2017-03-13