Измените VOLUME, чтобы автоматически создавать разрешения по умолчанию.
VOLUME проблема с разрешением по умолчанию
В Dockerfile, если вам нужно сохранить данные на локальном компьютере, вам нужно смонтировать каталог с ключевым словом VOLUME, и тогда файловые операции в этом каталоге будут сохранены на локальном компьютере.
Если смонтированный каталог не существует локально, Docker автоматически поможет создать каталог, и в это время это действие выполняется от имени пользователя root, поэтому права доступа к созданному каталогу принадлежат пользователю root и группе пользователей root, а затем Docker. Если выполнение служба в каталоге выполняется от имени другого пользователя, при записи в этот каталог и т. д. будет выдаваться сообщение о том, что у пользователя недостаточно прав.
Если вы не измените dockerfile в это время, вам нужно быстро решить эту проблему.
-
Вы можете напрямую передать локально сопоставленный каталог через
chmod -R 777 your/pathКоманда открывает все разрешения, эта операция небезопасна, потому что открытие всех разрешений означает, что любой пользователь может выполнять произвольные операции с этим каталогом, и могут возникнуть проблемы с безопасностью, такие как неправильная работа -
Найдите имя пользователя, соответствующее этому контейнеру, а затем передайте каталог команде
chownПередайте право собственности найденному пользователю, поэтому нет проблем по сравнению с описанной выше операцией, но операция доставит много хлопот.# 找到镜像的名称 docker images # 通过交互模式在镜像中执行 bash 命令 docker run -it api_demo_api bash # 查看镜像中的用户 root@20fcb7c63dee:/home/www# cat /etc/passwd ...... www:x:101:65534::/home/www:/bin/false # 对本地映射的目录,授权为镜像中查看到的用户 chown -R 101 /data/apiDemoНо есть проблема в том, что эти операции должны выполняться пользователем и требуют обучения или предварительной документации.Если вы можете решить эту проблему напрямую при написании dockerfile, то это, несомненно, лучший способ
Напишите Dockerfile для фляжного приложения.
Предполагая, что приложение python flask уже существует, структура проекта сервиса выглядит следующим образом:
./
├── Dockerfile
├── README.md
├── docker-compose.yml
├── entrypoint.sh
└── src
├── app
├── gun.py
├── requirements.txt
└── server.py
Сервис написан на основе образа Python 3.6.6, а dockerfile выглядит следующим образом:
FROM python:3.6.6
# 安装依赖环境,单独 copy 一个文件,如果不改动这个文件,这一层产生的镜像都可以命中缓存
# 安装库比较费时间
COPY ./src/requirements.txt /home/app/requirements.txt
RUN pip install --upgrade pip && pip install -r /home/app/requirements.txt
# 通过 ENTRYPOINT 关键字,在镜像服务启动之前执行一个脚本
COPY ./entrypoint.sh /usr/local/bin/
RUN chmod 755 /usr/local/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
# 创建一个镜像内的用户 www 及用户组 www,并且将用户 www 配置进 www 用户组中
RUN addgroup www && adduser --system www && adduser www www
# 将整个项目源码都 copy 进工作目录下
WORKDIR /home/www
COPY ./src /home/www
# 在镜像中创建目录并且进行授权,并且将日志目录写入镜像的环境变量中后续使用
ENV LOG_DIR /log
RUN mkdir -p "$LOG_DIR" && chown -R www:www "$LOG_DIR"
VOLUME /log
Авторизовать каталоги в entrypoint.sh
#!/bin/sh
# 如果执行用户是 root 则进行授权操作
if [ "$(id -u)" = '0' ]; then
# !表示对结果取反,表示找出所有用户不是 www 的文件,最后的 + 表示将所有找出的文件一起执行 chown 命令
find "$LOG_DIR" \! -user www -exec chown www '{}' +
fi
# 执行 docker 传递进行来的命令,如果没有这行,docker执行完 entrypoint.sh 就会直接退出
exec "$@"
Уведомление:
Работающая программа запускается с созданным пользователем, но процесс выполнения Dockerfile и скрипта entrypoint.sh весь выполняется пользователем root, иначе права на авторизацию нет, поэтому Dockerfile здесь не используется.
USERЗаказ
Быстрый старт с docker-compose
version: '3.7'
services:
api:
build: ./
command: gunicorn -c gun.py server:app
ports:
- 12345:12345
environment:
- SERVER_ENV=$SERVER_ENV
- HOST_ID=$HOST_ID
volumes:
- "/data/apiDemo:/log"
Обратите внимание, что пользователь работает с правами root, поэтому операции, которые необходимо выполнить с другими правами пользователя, должны выполняться путем выполнения команды Мы используем gunicorn в качестве контейнера для запуска службы, поэтому он находится в файле конфигурации gunicorn. py Для настройки ссылка на файл конфигурации выглядит следующим образом:
import multiprocessing
import os
from app.config import LOG_PATH
# 指定运行用户身份
user = 'www'
group = 'www'
debug = False
deamon = False
loglevel = 'info'
bind = '0.0.0.0:12345'
max_requests = 50000
worker_connections = 50000
x_forwarded_for_header = "X-Real-IP"
# 启动的进程数
workers = multiprocessing.cpu_count()
# workers = 3
worker_class = "gevent"
# 日志写入目录配置为授权的目录日志目录
accesslog = os.path.join(LOG_PATH, 'access.log')
access_log_format = '%({X-Real-IP}i)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s"'
errorlog = os.path.join(LOG_PATH, 'error.log')
timeout = 60
Беги, чтобы увидеть эффект
# 执行命令进行打包和运行
docker-compose build
docker-compose up
# 查看写入的日志文件
ll /data/
drwxr-xr-x 2 101 ssh_keys 4096 12月 17 15:09 apiDemo
ll /data/apiDemo/
-rw-r--r-- 1 101 ssh_keys 82 12月 17 15:08 access.log
-rw-r--r-- 1 101 ssh_keys 64 12月 17 15:08 api.log
-rw-r--r-- 1 101 ssh_keys 914 12月 17 16:12 error.log
Конфигурация полного проекта может быть отнесена к:api_demo