基于Ubuntu的Docker镜像中Python可执行文件缺失问题求助
问题:Celery Worker/Beat/Flower容器中Python命令找不到
基于Ubuntu基础镜像用docker-compose构建4个镜像时,celery_worker、celery_beat和flower这3个容器的entrypoint脚本执行失败,提示找不到python可执行文件。进入容器后发现二进制文件实际为python3.10,在Dockerfile里创建了符号链接ln -s /usr/bin/python3.10 /usr/bin/python,但该链接在这三个容器里不生效,web容器则正常。
测试结果
Web容器测试
$ docker-compose exec web bash root@9feff05c4ea1:/app# python Python 3.10.4 (main, Jun 29 2022, 12:14:53) [GCC 11.2.0] on linux Type "help", "copyright", "credits" or "license" for more information. >>>
Flower容器测试
$ docker-compose exec flower bash root@fa9d93403410:/app# python bash: python: command not found
相关配置文件
docker-compose.yml
version: '3.8' services: web: build: context: . dockerfile: ./compose/local/django/Dockerfile image: front_office command: /start volumes: - .:/app ports: - 8010:8000 env_file: - ./front_office/.env depends_on: - redis - db db: image: postgres volumes: - postgres_data:/var/lib/postgresql/data/ environment: - POSTGRES_DB=hello_django - POSTGRES_USER=hello_django - POSTGRES_PASSWORD=hello_django redis: image: redis celery_worker: build: context: . dockerfile: ./compose/local/django/Dockerfile image: front_office_worker command: /start-celeryworker volumes: - .:/app env_file: - ./front_office/.env depends_on: - redis - db celery_beat: build: context: . dockerfile: ./compose/local/django/Dockerfile image: front_office_beat command: /start-celerybeat volumes: - .:/app env_file: - ./front_office/.env depends_on: - redis - db flower: build: context: . dockerfile: ./compose/local/django/Dockerfile image: front_office_flower command: /start-flower volumes: - .:/app env_file: - ./front_office/.env ports: - 5557:5555 depends_on: - redis - db volumes: postgres_data:
Dockerfile
FROM ubuntu ENV PYTHONUNBUFFERED 1 ENV PYTHONDONTWRITEBYTECODE 1 RUN apt-get update \ && apt-get install -y build-essential \ && apt-get install -y libpq-dev \ && apt-get install -y gettext \ && apt-get install -y python3.10 \ && apt-get install -y python-pip \ && apt-get install -y python3-pip \ && apt-get install -y git \ && apt-get install -y openssh-client \ && apt-get install -y libcurl4-openssl-dev libssl-dev \ && apt-get install -y python3-requests \ && apt-get install -y cargo \ && apt-get install -y procps \ && apt-get purge -y --auto-remove -o APT::AutoRemove::RecommendsImportant=false \ && rm -rf /var/lib/apt/lists/* RUN ln -s /usr/bin/python3.10 /usr/bin/python # Requirements are installed here to ensure they will be cached. COPY ./requirements.txt /requirements.txt RUN pip install -r /requirements.txt COPY ./compose/local/django/entrypoint /entrypoint RUN sed -i 's/\r$//g' /entrypoint RUN chmod +x /entrypoint COPY ./compose/local/django/start /start RUN sed -i 's/\r$//g' /start RUN chmod +x /start COPY ./compose/local/django/celery/worker/start /start-celeryworker RUN sed -i 's/\r$//g' /start-celeryworker RUN chmod +x /start-celeryworker COPY ./compose/local/django/celery/beat/start /start-celerybeat RUN sed -i 's/\r$//g' /start-celerybeat RUN chmod +x /start-celerybeat COPY ./compose/local/django/celery/flower/start /start-flower RUN sed -i 's/\r$//g' /start-flower RUN chmod +x /start-flower WORKDIR /app ENTRYPOINT ["/entrypoint"]
entrypoint脚本
#!/bin/bash # if any of the commands in your code fails for any reason, the entire script fails set -o errexit # fail exit if one of your pipe command fails set -o pipefail # exits if any of your variables is not set set -o nounset postgres_ready() { python << END import sys import psycopg2 try: psycopg2.connect( dbname="${SQL_DATABASE}", user="${SQL_USER}", password="${SQL_PASSWORD}", host="${SQL_HOST}", port="${SQL_PORT}", ) except psycopg2.OperationalError: sys.exit(-1) sys.exit(0) END } until postgres_ready; do >&2 echo 'Waiting for PostgreSQL to become available...' sleep 1 done >&2 echo 'PostgreSQL is available' exec "$@"
容器日志
front_office-celery_worker-1 | Waiting for PostgreSQL to become available... front_office-celery_worker-1 | /entrypoint: line 11: python: command not found front_office-celery_worker-1 | Waiting for PostgreSQL to become available... front_office-celery_beat-1 | /entrypoint: line 11: python: command not found front_office-celery_beat-1 | Waiting for PostgreSQL to become available... front_office-celery_worker-1 | /entrypoint: line 11: python: command not found front_office-celery_worker-1 | Waiting for PostgreSQL to become available... front_office-flower-1 | /entrypoint: line 11: python: command not found front_office-flower-1 | Waiting for PostgreSQL to become available... front_office-celery_beat-1 | /entrypoint: line 11: python: command not found front_office-celery_beat-1 | Waiting for PostgreSQL to become available... front_office-flower-1 | /entrypoint: line 11: python: command not found front_office-flower-1 | Waiting for PostgreSQL to become available... front_office-celery_worker-1 | /entrypoint: line 11: python: command not found
解决方案
方法1:强制重新构建镜像,避免缓存问题
符号链接命令本身正确,但可能因为镜像缓存导致新修改未生效,执行以下命令强制重新构建所有服务:
docker-compose build --no-cache docker-compose up -d
方法2:直接修改entrypoint脚本使用python3.10
如果符号链接仍不生效,直接在entrypoint脚本中替换python为python3.10:
postgres_ready() { python3.10 << END # ... 原有代码保持不变 END }
方法3:用update-alternatives设置默认Python版本(更规范)
在Dockerfile中替换手动创建符号链接的命令,使用Ubuntu官方工具设置默认Python:
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1 RUN update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1
该方式比手动创建符号链接更稳定,能确保系统全局识别python命令。
方法4:检查volume挂载是否干扰系统目录
确认docker-compose中所有服务的volume仅挂载本地目录到容器/app,没有误挂载到/usr/bin等系统目录,避免覆盖容器内的Python可执行文件或符号链接。
内容的提问来源于stack exchange,提问作者Florent
相关产品推荐
相关产品推荐

