Docker卷 - 需要写入数据库的权限

时间:2016-12-19 11:25:19

标签: python sqlite docker docker-compose docker-volume

我正在使用一个烧瓶服务器(在带有python 3.5的virtualenv中),它用作REST API(仅用于烧瓶建议的开发)。在开始时它连接到本地sqlite数据库,它将尽快提交任何数据库更改。现在我想在docker容器中运行所有内容,我想知道如何访问数据库,因为sqlite文件位于容器中。

所以我在docker-compose文件中创建了一个卷,该文件指向构建应用程序的dockerfile。

Dockerfile:

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但在主机上我的用户帐户具有此ID。所以我想我现在知道问题是什么,但我不知道如何访问这些文件。我尝试添加":rw"到卷定义但我仍然没有写权限。如果定义了卷,如何告诉docker不要更改文件/目录所有者。

我正在考虑本地卷驱动程序的问题,但也许其他人已经遇到此问题并且可以告诉我如何配置我的图像以获得所需的权限。

问候, 托马斯

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

1 个答案:

答案 0 :(得分:0)

Hot Fix

我通过向每个人提供作家许可来解决问题。

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

这将为主机上的用户和docker机器中的root用户授予权限,无论谁拥有这些文件。这只是一个肮脏的修复,因为我不得不快点。任何进程都可以访问和编辑/删除文件。如果只有docker用户获得写入权限会更好,但是我无法向主机上的root用户授予writer权限。

更好的方法

在这个post中,他们在容器中使用另一个用户(www-data)。构建映像后,他们获取用户的id并用此id替换当前文件所有者。如果以此用户(www-data)启动容器,则mount将复制具有权限和所有者信息的文件,以便用户可以读取和写入这些文件。

这将是一种更安全的方式,因为您确保只有docker用户可以更改数据库/文件。因为我不能让这项工作对我来说(似乎对id = 0的root用户不起作用),但我想指出,有一个更好的解决方案。

如果您在泊坞窗停止后只需要最后的数据,则可以查看docker cp