在容器内使用docker-compose命令运行一个shell脚本

18

我尝试在Docker容器内使用docker-compose运行一个shell脚本。我使用Dockerfile构建容器环境并安装所有依赖项。然后将所有项目文件复制到容器中。据我所知,这很有效。(我对docker和docker-compose仍然相当新手)

我的Dockerfile:

FROM python:3.6-alpine3.7

RUN apk add --no-cache --update \
    python3 python3-dev gcc \
    gfortran musl-dev \
    libffi-dev openssl-dev

RUN pip install --upgrade pip

ENV PYTHONUNBUFFERED 1
ENV APP /app

RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir $APP
WORKDIR $APP

ADD requirements.txt .
RUN pip install -r requirements.txt

COPY . .

我目前正在尝试的是:

docker-compose文件:

version: "2"

services:
  nginx:
    image: nginx:latest
    container_name: nginx
    ports:
      - "8000:8000"
      - "443:443"
    volumes:
      - ./:/app
      - ./config/nginx:/etc/nginx/conf.d
      - ./config/nginx/ssl/certs:/etc/ssl/certs
      - ./config/nginx/ssl/private:/etc/ssl/private
    depends_on:
      - api
  api:
    build: .
    container_name: app
    command: /bin/sh -c "entrypoint.sh"
    expose:
      - "5000"

这将导致容器无法启动,并且从日志中我得到以下信息:

/bin/sh: 1: entrypoint.sh: not found

更多参考和信息,请查看我的entrypoint.sh脚本:

python manage.py db init
python manage.py db migrate --message 'initial database migration'
python manage.py db upgrade
gunicorn -w 1 -b 0.0.0.0:5000 manage:app
基本上,我知道我可以在dockerfile的命令行中只使用上面的gunicorn命令来运行容器。但是,我正在使用app容器内部的一个sqlite数据库,并且真正需要运行数据库命令以初始化/迁移数据库。
仅供参考,这是一个基本的Flask Python Web应用程序,使用nginx反向代理和gunicorn。
任何见解将不胜感激。谢谢。

1
请提供entrypoint.sh的确切路径:command: /bin/sh -c "/path/to/entrypoint.sh" - mchawre
谢谢,我成功解决了问题。最终我不得不通过ssh进入容器,才发现entrypoint.sh脚本从未被包含在容器中。正如下面[Adiii]所提供的解决方案,在找到问题时非常有用。 - Kevin Smith
2个回答

20
首先,您正在将 entrypoint.sh 复制到从构建参数传递的 $APP 中,但您没有提到这一点。其次,您需要为 entrypoint.sh 设置权限。最好添加这三行代码,这样您就不需要在 docker-compose 文件中添加 command
FROM python:3.6-alpine3.7
RUN apk add --no-cache --update \
    python3 python3-dev gcc \
    gfortran musl-dev \
    libffi-dev openssl-dev
RUN pip install --upgrade pip
ENV PYTHONUNBUFFERED 1
ENV APP /app
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
RUN mkdir $APP
WORKDIR $APP
ADD requirements.txt .
RUN pip install -r requirements.txt

COPY . .
# These line for /entrypoint.sh
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT "/entrypoint.sh"

API 的 Docker Compose 将会是:

  api:
    build: .
    container_name: app
    expose:
      - "5000"

或者你也可以使用你自己的,也能正常工作。
version: "2"

services:
  api:
    build: .
    container_name: app
    command: /bin/sh -c "entrypoint.sh"
    expose:
      - "5000"

现在你也可以使用docker run命令进行检查。

docker run -it --rm myapp


1
谢谢,这解决了我的问题。我最终只使用了添加到Dockerfile的前两行,并从docker-compose运行/bin/sh -c "/entrypoint.sh"命令。基本上是为了允许容器构建与运行容器分离。 - Kevin Smith
在 Dockerfile 中,entrypoint "/entrypoint.sh" 这一行是做什么用的?请回答。 - dumbledad
明白了,只需要 ENTRYPOINT "/entrypoint.sh",不要大写。 - dumbledad

0

entrypoint.sh 需要指定其完整路径。

从您的问题中不清楚您安装它的确切位置;如果它在当前目录中,./entrypoint.sh 应该可以工作。

(顺便提一下,如果您想运行单个脚本文件,则 sh-c 选项是多余的。)


感谢您的见解。我最终不得不通过ssh进入容器,并发现entrypoint.sh不存在,通过在Dockerfile中包含它来解决了这个问题。 - Kevin Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接