【发布时间】:2020-03-08 08:56:21
【问题描述】:
docker-compose 忽略已安装的虚拟环境
我正在尝试对我现有的 django 应用程序进行 dockerize。另外我是 docker 新手,所以请原谅我,如果这是某种“只需阅读说明”的事情。问题 51490937 似乎有些相关,但我不确定。我的应用程序使用 pip install mod-wsgi 运行 apache,并且它已经很好地部署到本机 ubuntu 18 和 19 vm。 我运行 win10,使用 Docker 版本 19.03.4 的 linux 容器,构建 9013bf5,运行 python:3.7 基础映像。
我的问题:当我使用 docker-compose up 时运行我安装的图像失败,但当我手动运行时成功。我首先假设,我有一个缓存问题,但尝试https://forums.docker.com/t/how-to-delete-cache/5753 建议的所有事情都没有帮助。此外,我的本地项目文件夹的时间戳与手动运行容器的时间戳和 Dockerfile 返回的时间戳相同。所以现在我假设我的 docker-compose.yml 有问题,或者我激活了一些我不知道的分支。 (文件附在最后)为了调试,我删除了 postgress 服务,现在运行默认的 sqlite db。
docker-compose up (ls -la && source venv/bin/activate) 返回:
some other files...
302_game_container | -rwxr-xr-x 1 root root 400 Nov 11 16:49 test.py
302_game_container | drwxrwxrwx 2 root root 0 Nov 12 11:55 web_project
302_game_container | bash: venv/bin/activate: No such file or directory <---- The ERROR
302_game_container exited with code 1
注意:此处显示的时间戳为 (11:55 web_project),并且缺少 venv 文件夹。看起来 venv 没有正确安装。
但是,当我现在手动运行相同的图像时,键入:
docker run -it -d 302_chess_game_2019_11_12_15_20_33_354574
docker exec -it myDockerContainer bash
ls -la && source venv/bin/activate
我得到了想要的结果:
some other files...
-rwxr-xr-x 1 root root 400 Nov 11 16:49 test.py
drwxr-xr-x 5 root root 4096 Nov 12 11:57 venv
drwxrwxrwx 1 root www-data 4096 Nov 12 11:59 web_project
(venv) root@d98fde4a6316:/302_chess_game#
然后我可以成功运行 python web_project/manage.py runserver 甚至 sudo /etc/wsgi-port-8000/apachectl restart。所以图像包含已安装的 venv。然后我可以查看 0.0.0.0:8000 下的页面。
我的设置:
Dockerfile 运行一个 script.sh,它安装所有 prod 程序,创建我的 venv,安装 requirements.txt,激活 venv,然后运行 makemigrations、migrate 和 collectstatic。所有任务都成功运行。进入的最后一步
Dockerfile RUNs ls -la 返回:
some other files...
-rwxr-xr-x 1 root root 400 Nov 11 16:49 test.py
drwxr-xr-x 5 root root 4096 Nov 12 11:57 venv
drwxrwxrwx 1 root www-data 4096 Nov 12 11:59 web_project
如您所见,venv 安装在映像中,web_project 文件夹的时间戳为 (11:59 web_project)。
这是我的缩减版docker-compose.yml(project=302_chess_game,timeStamp=_2019_11_12_15_20_33_354574,port=8000,image=python:3.7)
version: '3'
services:
python:
image: {{ project }}{{ timeStamp }}
container_name: 302_game_container
volumes:
- .:/{{ project }}
ports:
- {{ port }}:{{ port }}
command: >
bash -c "ls -la && source venv/bin/activate"
这是我的 Dockerfile
FROM {{ image }}
# install ubuntu stuff
RUN apt -y update
RUN apt -y upgrade
RUN apt-get -y install sudo
# copy files
RUN sudo mkdir /{{ project }}
WORKDIR /{{ project }}
COPY . /{{ project }}/
# set default evn variables
ENV PYTHONUNBUFFERED 1
ENV LANG C.UTF-8
#ENV DEBIAN_FRONTEND=noninteractive
# set environment variables
ENV PORT={{ port }}
ENV PRODUCTION=1
ENV SERVER={{ server }}
ENV DEBUG={{ debug }}
ENV DATABASE={{ database }}
# install shell script
RUN chmod 777 ./resources/{{ install_sh }}
RUN sed -i -e 's/\r$//' ./resources/{{ install_sh }}
RUN ./resources/{{ install_sh }}
RUN ls -la
EXPOSE {{ port }}
# add user implemented later
#RUN useradd -ms /bin/bash {{ username }}
#RUN echo '{{ username }}:test321' | chpasswd
#RUN adduser {{ username }} sudo
#RUN chown -R {{ username }}:sudo /{{ project }}
#USER {{ username }}
这里是shell脚本:
#!/bin/bash
sudo apt install vim -y
sudo apt install net-tools
sudo apt install -y python3-pip
sudo apt install build-essential libssl-dev libffi-dev python3-dev -y
sudo apt install apache2 -y
sudo apt install apache2-dev -y
sudo apt install -y python3-venv
pip3 install mod_wsgi
python3 -m venv venv
source venv/bin/activate
python -m pip install --upgrade pip
pip install --upgrade setuptools
pip install -r requirements.txt
pip install mod_wsgi
sudo mkdir /etc/wsgi-port-{{ port }}
sudo chown -R {{ username }}:{{ username }} /etc/wsgi-port-{{ port }}
sudo groupadd www-data
sudo adduser www-data www-data
sudo chown -R :www-data web_project/media/
sudo chmod -R 775 web_project/media/
sudo chown -R :www-data web_project
sudo chmod 777 web_project
sudo chown :www-data web_project/{{ project }}.sqlite3
sudo chmod 664 web_project/{{ project }}.sqlite3
python web_project/manage.py makemigrations
python web_project/manage.py migrate
python web_project/manage.py collectstatic
python web_project/manage.py runmodwsgi --server-root /etc/wsgi-port-{{ port }} --user www-data --group www-data --port {{ port }} --url-alias /static static --url-alias /media media --setup-only
#
# sudo cp conf_files/sshd_config /etc/ssh/sshd_config
# sudo systemctl restart sshd
# sudo apt install ufw -y
# sudo ufw default allow outgoing
# sudo ufw default deny incoming
# sudo ufw allow ssh
# sudo ufw allow http/tcp
# sudo ufw allow https/tcp
# sudo ufw allow 3389
# sudo ufw enable
# sudo passwd {{ username }}
# netstat -nat | grep LISTEN
# sudo ufw status
# sudo /etc/wsgi-port-{{ port }}/apachectl restart
# sudo apt install xrdp
# sudo apt remove lightdm
# sudo apt install xfce4
# sudo apt-get install xfce4-terminal tango-icon-theme
# echo xfce4-session > ~/.xsession
# sudo apt install libexo-1-0
# sudo apt install firefox
# sudo service xrdp restart
# sudo /etc/wsgi-port-{{ port }}/apachectl restart
要重现运行以下 docker-compose.yml:
version: '3'
services:
python:
image: lmielke/302_chess_game_2019_11_12_15_49_04_892687:testcontainer
container_name: 302_game_container
volumes:
- .:/302_chess_game
ports:
- 8000:8000
command: >
bash -c "source venv/bin/activate &&
sudo apachectl stop &&
sudo /etc/wsgi-port-8000/apachectl start"
这将拉取映像,但容器构建将失败,如所述。然后运行:
docker run -it -d (imgId),
docker exec -it (containerId),
source venv/bin/activate,
sudo /etc/wsgi-port-8000/apachectl start,
它会显示一些别名警告,但运行正常。你可以在 bash cmds 中添加ls -la 来查看没有 venv 文件夹。
【问题讨论】:
-
你能把它缩减为minimal reproducible example吗?您通常不需要 Docker 中的虚拟环境(容器本身提供隔离),这似乎解决了您的问题的核心。您通常也不需要
sudo,但您的 Dockerfile 确实需要CMD指令来告诉容器如何运行应用程序。 -
@David:你说得对,我会优化安装程序的运行。至于 CMD 指令,我希望使用 docker-compose.yml 命令标签来执行此操作。第三个命令将是 sudo /etc/wsgi-port-8000/apachectl restart 但由于我什至没有在那里完成,所以我将其排除在示例之外。
标签: python django docker docker-compose mod-wsgi