Kevin Smith
Kevin Smith

Reputation: 676

Run a shell script from docker-compose command, inside the container

I am attempting to run a shell script by using docker-compose inside the docker container. I am using the Dockerfile to build the container environment and installing all dependancies. I then copy all the project files to the container. This works well as far as I can determine. (I am still fairly new to docker, docker-compose)

My 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 . .

What I am currently attempting is this:

docker-compose file:

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"

This results in the container not starting up, and from the log I get the following:

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

For more reference and information this is my entrypoint.sh script:

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

Basically, I know I could run the container with only the gunicorn line above in the command line of the dockerfile. But, I am using a sqlite db inside the app container, and really need to run the db commands for the database to initialise/migrate.

Just for reference this is a basic Flask python web app with a nginx reverse proxy using gunicorn.

Any insight will be appreciated. Thanks.

Upvotes: 22

Views: 129475

Answers (2)

tripleee
tripleee

Reputation: 189936

entrypoint.sh needs to be specified with its full path.

It's not clear from your question where exactly you install it; if it's in the current directory, ./entrypoint.sh should work.

In some more detail, the working directory inside the container is set by WORKDIR; and so, for example, if WORKDIR is /foo then ./entrypoint.sh is equivalent to /foo/entrypoint.sh

(Tangentially, the -c option to sh is superfluous if you want to run a single script file.)

Upvotes: 0

Adiii
Adiii

Reputation: 60144

First thing, You are copying entrypoint.sh to $APP which you passed from your build args but you did not mentioned that and second thing you need to set permission for entrypoint.sh. Better to add these three lines so you will not need to add command in docker-compose file.

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"

docker compose for api will be

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

or you can use you own also will work fine

version: "2"

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

Now you can check with docker run command too.

docker run -it --rm myapp

Upvotes: 21

Related Questions