Sqlite3 数据库在 Docker 容器中保持只读且不可创建。如何让它可写?

Posted

技术标签:

【中文标题】Sqlite3 数据库在 Docker 容器中保持只读且不可创建。如何让它可写?【英文标题】:Sqlite3 database remains read-only and un-creatable in a Docker container. How to make it writeable? 【发布时间】:2021-11-19 20:38:29 【问题描述】:

我已经看过相关的问题。这些解决方案都没有奏效。这是我的码头文件。我正在使用 Flask 和 SQLAlchemy 来写入与 Flask 应用程序位于同一文件夹中的数据库。

FROM ubuntu:latest
RUN apt-get -y update && apt-get -y install sudo
RUN sudo apt-get install -y sqlite3
RUN sudo apt-get install -y python
RUN sudo apt-get install -y python3-pip
WORKDIR /usr/src/app
COPY . .
#RUN sudo chmod 777 /usr/src/app/db.sqlite
#RUN chmod a+rw /usr/src/app/db.sqlite
#RUN useradd -m docker && sudo usermod -u 1200 www-data && sudo usermod -G docker www-data
#RUN chown www-data:www-data /usr/src/app/db.sqlite
RUN useradd -m docker && echo "docker:docker" | chpasswd && adduser docker sudo
RUN sudo chown docker /usr/src/app/db.sqlite
USER docker
CMD /bin/bash

RUN pip install -r requirements.txt
ENV PATH="/home/docker/.local/bin:$PATH"
ENV FLASK_APP=__init__.py
ENV FLASK_DEBUG=1
ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_ENV=development 
CMD ["flask", "run"]  

被注释掉的行,显示了我已经尝试过的命令。 所以我使用docker exec -it <container_id> bash登录到容器并尝试直接更改权限和所有权,但仍然没有用。 然后我删除了db.sqlite 文件并尝试使用sqlite3 db.sqlite 创建一个。但是数据库甚至不会被创建:

docker@5aeeb3039ef1:/usr/src/app$ sqlite3 db.sqlite
SQLite version 3.31.1 2020-01-27 19:55:54
Enter ".help" for usage hints.
sqlite> .tables
Error: unable to open database "db.sqlite": unable to open database file

在您的系统上测试它: 有人可以帮忙吗?为了测试它,你可以创建上面的 Dockerfile 并在同一目录下创建一个数据库,你只需要在你的系统上安装 sqlite3 并使用sqlite3 db.sqlite 创建数据库。要创建表,您可以使用CREATE TABLE user (id INTEGER NOT NULL, username VARCHAR(10), password VARCHAR(20), name VARCHAR(100), PRIMARY KEY (id), UNIQUE (email));

ps:我最终选择了having to create 这个复杂的 Dockerfile,因为 sqlite3 不会安装在预装了 Flask 的简单 python 映像中。

【问题讨论】:

更典型的做法是在单独的容器中使用基于服务器的关系数据库(PostgreSQL、mysql)。这避免了在您删除和重新创建容器时尝试保留一个文件的问题,它避免了您在此处描述的权限问题,如果您需要运行应用程序的多个副本,您可以在不单独复制数据库的情况下执行此操作。 我同意。但现在,我需要让 Sqlite 数据库可写。登录到 Docker 容器后,我可以使用sudo sqlite3 db.sqlite 创建一个数据库。所以必须有办法通过使用正确的权限来做到这一点。 无论如何,你真的不应该在容器中使用 sudo 如前所述,您可以批量挂载外部 SQLite 文件,而不是在其生命周期内丢失容器中的文件 @OneCricketeer:我同意。但是现在,我需要按原样使用它。解决问题的一些帮助将有助于更多地了解 Docker 文件系统权限。 【参考方案1】:

解决了。事实证明,不需要切换到USER docker

FROM ubuntu:latest
RUN apt-get -y update
RUN apt-get install -y sqlite3 python python3-pip 
WORKDIR /usr/src/app
COPY . .
RUN pip install -r requirements.txt
ENV PATH="/home/docker/.local/bin:$PATH"
ENV FLASK_APP=__init__.py
ENV FLASK_DEBUG=1
ENV FLASK_RUN_HOST=0.0.0.0
ENV FLASK_ENV=development 
CMD ["flask", "run"]

【讨论】:

以上是关于Sqlite3 数据库在 Docker 容器中保持只读且不可创建。如何让它可写?的主要内容,如果未能解决你的问题,请参考以下文章

Docker Compose 保持容器运行

docker数据管理

docker数据卷容器

如何运行多进程Docker容器

深入理解docker volume

docker学习-docker容器运行