首页 > 解决方案 > 如何在 docker-compose 中运行 shell 脚本

问题描述

我有一个用例,我正在尝试构建一个基于 django 的 rest api,然后在将更改推送到 github 时使用 travis CI 使用持续集成。我还使用 docker 来构建和 docker-compose 来扩展我的服务。问题是当我将更改推送到 github 时,我想运行 pytest 和 flake8。现在我没有添加任何测试,因此 pytest 命令给出的退出状态为 5。

为了解决这个问题,我尝试创建一个脚本来执行此操作:

#!/bin/bash

pytest;
err=$? ;
if (( $err != 5 )) ;
then
  exit $err;
fi
flake8 ;

但我无法让 docker-compose 运行它。当我使用命令运行脚本时:

docker-compose run app sh -c "run_script.sh"

它给出以下错误消息: sh: run_script.sh: not found

下面是我的 docker-compose yml 文件:

version: "3"

services:
  app:
    build:
      context: .
    ports:
      - "8000:8000"
    volumes:
      - ./app:/app
    command: >
      sh -c "python manage.py runserver 0.0.0.0:8000"

下面是dockerfile:

FROM python:3.7-alpine

MAINTAINER Subhayan Bhattacharya

ENV PYTHONUNBUFFERED 1

COPY Pipfile* /tmp/

RUN cd /tmp && pip install pipenv && pipenv lock --requirements > requirements.txt

RUN pip install -r /tmp/requirements.txt

RUN mkdir /app

WORKDIR /app

COPY ./app /app

RUN adduser -D user
USER user

这应该是一个简单的问题,但我不知道如何解决这个问题。

有人可以帮我找到解决方案吗

标签: djangodockerdocker-composetravis-ci

解决方案


您的脚本不起作用,因为 Alpine 基础映像没有 GNU bash。您的脚本几乎仅限于POSIX Shell 命令语言;如果这样做,您可以将“shebang”行更改为#!/bin/sh.

#!/bin/sh
# ^^^ not bash
pytest    # individual lines don't need to end with ;
err=$?
# use [ ... ] (test), not ((...))
if [ "$err" -ne 5 ] && [ "$err" -ne 0 ]; then
  exit "$err"
fi
flake8

在 CI 系统的上下文中,删除将volumes:本地目录挂载到容器目录上的行很重要/app:拥有该行意味着您根本没有测试镜像中的内容,而是可能相关的代码树主机系统。

在实践中,我建议在非 Docker 环境中运行这两个工具。运行它们并收集它们的结果会更简单。特别是像样式检查器这样的样式检查器flake8对系统包或其他正在启动的容器的依赖很少,理想情况下,您的单元测试也可以在没有像数据库容器那样难以设置的上下文的情况下运行。我建议这样的顺序:

  1. 查看源代码。
  2. 创建一个虚拟环境并安装其依赖项。
  3. 运行pytestflake8和类似的测试工具。
  4. 然后构建一个 Docker 映像,无需仅测试工具。
  5. 运行带有各种依赖项的图像。
  6. 根据对容器的网络调用运行进一步的测试。

推荐阅读