Том Docker — нужны разрешения на запись в базу данных

Я работаю над фляжным сервером (в virtualenv с python 3.5), который используется в качестве REST API (только для разработки, как это предлагается для фляги). Вначале он подключается к локальной базе данных sqlite и как можно скорее фиксирует любые изменения базы данных. Теперь я хотел запустить все в контейнере докера, и мне было интересно, как я могу получить доступ к базе данных, потому что файл sqlite находится в контейнере.

Поэтому я создал том в файле создания докеров, который указывает на файл докеров, создающий приложение.

Докерфайл:

FROM python:latest
ENV HOME /home/parkrep
WORKDIR $HOME
ADD requirements.txt $HOME/requirements.txt
RUN pip install -r requirements.txt
ADD . $HOME
EXPOSE 80
CMD ["python", "server.py"]

.dockerignore

__pycache__
venv
.gitignore
.dockerignore
README.md
Dockerfile
docker-compose.yml

докер-compose.yml

version: '2'
services:
  parkrep:
    build:
      context: ./
      dockerfile: Dockerfile
    volumes:
      - ./output:/home/parkrep/output
    command: ["python", "server.py"]
    ports:
      - "80:80"

Если я запускаю docker-compose up, я получаю следующее

parkrep_1  |   File "/home/parkrep/db_connector.py", line 45, in _connect_db
parkrep_1  |     self._connection = sqlite3.connect(path, check_same_thread=False)
parkrep_1  | sqlite3.OperationalError: unable to open database file
parkrep_parkrep_1 exited with code 1

Если я создам базу данных в output/reports.db и снова запущу docker-compose, она вернет следующую ошибку:

parkrep_1  | sqlite3.OperationalError: attempt to write a readonly database

Так что, очевидно, у меня нет прав на запись в файл. Я проверил это поведение, записав в тестовый файл, который смонтирован следующим образом:

...
volumes:
  - ./output:/home/parkrep/output
  - ./test.txt:/home/parkrep/text.txt
command: bash -c "echo 'hallo' > test.txt"

Сообщение об ошибке:

parkrep_1  | bash: text.txt: Permission denied

Давайте посмотрим, кому принадлежит этот файл:

parkrep_1  | drwxr-xr-x 7 root root 4.0K Dec 19 10:45 .
parkrep_1  | -rw-rw-r-- 1 root root  143 Dec 12 15:08 config.yaml
parkrep_1  | -rw-rw-r-- 1 root root 7.9K Dec 12 14:37 db_connector.py
parkrep_1  | drwxrwxr-x 2 4262 4262 4.0K Dec 19 11:10 output
parkrep_1  | -rw-rw-r-- 1 root root  144 Dec 12 13:20 requirements.txt
parkrep_1  | -rw-rw-r-- 1 root root 2.7K Dec 19 10:14 server.py
parkrep_1  | -rw-rw-r-- 1 4262 4262 2.7K Dec 19 10:14 test.txt

Получается, что в контейнере нет пользователя 4262, но на хост-машине у моей учетной записи есть этот идентификатор. Итак, я думаю, что знаю, в чем проблема, но я понятия не имею, как получить доступ к этим файлам. Я попытался добавить «: rw» в определения томов, но у меня все еще нет прав на запись. Как я могу сказать докеру не менять владельца файла/каталога, если том определен.

Я думаю о проблеме с моим локальным драйвером тома, но, возможно, у кого-то уже была эта проблема, и он может сказать мне, как настроить мой образ, чтобы получить необходимые разрешения.

Привет, Томас

docker info

     Containers: 1
 Running: 0
 Paused: 0
 Stopped: 1
Images: 19
Server Version: 1.12.5
Storage Driver: aufs
 Root Dir: /var/lib/docker/aufs
 Backing Filesystem: extfs
 Dirs: 19
 Dirperm1 Supported: true
Logging Driver: json-file
Cgroup Driver: cgroupfs
Plugins:
 Volume: local
 Network: host bridge null overlay
Swarm: inactive
Runtimes: runc
Default Runtime: runc
Security Options: apparmor seccomp
Kernel Version: 4.4.0-53-generic
Operating System: Ubuntu 16.04.1 LTS
OSType: linux
Architecture: x86_64
CPUs: 8
Total Memory: 15.56 GiB
Name: de3lxd-107769
ID: PU5F:LZ55:EEK7:W3R7:SYR3:336J:2VRH:35H2:MTLY:6Q6L:BWBP:EM5R
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: No swap limit support
Insecure Registries:
 127.0.0.0/8

docker-compose -v

docker-compose version 1.9.0, build 2585387

lsb_release -a

No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 16.04.1 LTS
Release:    16.04
Codename:   xenial

person Chaoste    schedule 19.12.2016    source источник


Ответы (1)


Горячее исправление

Я решил проблему, дав разрешение на запись всем.

mkdir output
touch output/reports.db output/database.log
chmod a+rw output output/*

Это даст пользователю на хост-компьютере и привилегированному пользователю на докер-машине разрешения, независимо от того, кому принадлежат файлы. Это просто грязное исправление, потому что мне нужно было поторопиться. Любой процесс может получить доступ и редактировать/удалять файлы. Было бы лучше, если бы только пользователь докера получил разрешение на запись, но я не мог дать разрешение на запись пользователю root на хост-компьютере.

Лучший подход

В этом сообщении они используют другого пользователя (www-data) в контейнере. После создания образа они получают идентификатор пользователя и заменяют текущего владельца файла этим идентификатором. Если вы запустите контейнер как этот пользователь (www-data), монтирование скопирует файлы с разрешениями и информацией о владельце, чтобы пользователь мог читать и писать в эти файлы.

Это был бы более безопасный способ, потому что вы убедитесь, что только пользователь докера может изменять базу данных/файлы. Потому что я не мог заставить это работать для меня (кажется, не работает для пользователя root с id = 0), но я хотел указать, что есть лучшее решение.

Если вам нужны данные только в конце после остановки докера, вы можете взглянуть на докер cp.

person Chaoste    schedule 21.12.2016