6

It seems my docker-compose commands only execute the last command. In this case runserver.

command: python3 manage.py collectstatic --noinput
command: python3 manage.py migrate --noinput
command: python3 manage.py runserver 0.0.0.0:8000

I tried to move these commands into an entrypoint.sh file. However, I can't figure out how to implement this into my dockerfile & docker-compose.

The following is my dockerfile:

# Pull base image
FROM python:3

# Set environment varibles
ENV PYTHONUNBUFFERED 1

# Set work directory
RUN mkdir /code
WORKDIR /code

# Install dependencies
RUN pip install --upgrade pip
RUN pip install pipenv
COPY ./Pipfile /code/Pipfile
RUN pipenv install --deploy --system --skip-lock --dev

# Copy project
COPY . /code/

My docker-compose:

version: '3'

services:
  db:
    image: postgres
    ports:
      - "5432:5432"
  web:
    build: .
    command: python3 manage.py collectstatic --noinput
    command: python3 manage.py migrate --noinput
    command: python3 manage.py runserver 0.0.0.0:8000
    env_file: .env
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    depends_on:
      - db

entrypoint.sh

#!/bin/bash

# Collect static files
echo "Collect static files"
python manage.py collectstatic --noinput

# Apply database migrations
echo "Apply database migrations"
python manage.py migrate

# Start server
echo "Starting server"
python manage.py runserver 0.0.0.0:8000

2 Answers 2

13

That is because you can only have one command.

You can combine multiple commands like this:

command: sh -c "python3 manage.py collectstatic --noinput && python3 manage.py migrate --noinput && python3 manage.py runserver 0.0.0.0:8000"

Alternatively as you mentioned the entrypoint, you can specify the entrypoint in the Dockerfile or in docker-compose.yml. Make sure to remove the commands as you won't need them anymore.

Here's a good article on entrypoint vs cmd vs run: http://goinbigdata.com/docker-run-vs-cmd-vs-entrypoint/

Sign up to request clarification or add additional context in comments.

3 Comments

it starts a new shell. this is a docker limitation if you want to run multiple commands after each other with &&
Ah ok great, understood. I now tried the other way and added entrypoint: /code/docker-entrypoint.sh to my docker-compose. Dockerfile I kept unchanged. However, I always receive Cannot start service db: driver failed programming external connectivity on endpoint. Do you have any idea why it doesn't work?
that's probably because you're trying to bind to the host's port on 5432, but there's already something running on that port
0

Alternatively, to Michael's answer, you could've used the wrapper syntax as indicated on the docs.

version: "2"
services:
  web:
    build: .
    ports:
      - "80:8000"
    depends_on:
      - "db"
    command: ["./wait-for-it.sh", "db:5432", "--", "python", "app.py"]
  db:
    image: postgres

More:

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.