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
halfer
  • 19,824
  • 17
  • 99
  • 186
Joey Coder
  • 3,199
  • 8
  • 28
  • 60

2 Answers2

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/

Michael Barany
  • 1,639
  • 1
  • 12
  • 15
  • it starts a new shell. this is a docker limitation if you want to run multiple commands after each other with `&&` – Michael Barany Oct 22 '18 at 22:30
  • 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? – Joey Coder Oct 22 '18 at 22:43
  • 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 – Michael Barany Oct 23 '18 at 00:24
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:

basquiatraphaeu
  • 525
  • 7
  • 19