Когда выполнять команду в docker compose, а когда в dockerfile?
Я новичок в docker, так что потерпите меня за потенциально глупый вопрос.
Насколько я понял, если я хочу иметь работающий контейнер, а не исполняемый файл, то в конце нужно написать "command". Okey.
Итак, если мне нужен контейнер, обслуживающий приложение django, я должен добавить что-то вроде:
python manage.py runserver 0.0.0.0:8000
Теперь вопрос в следующем: Добавляем ли мы это в конец dockerfile, определяющего образ?
Или мне добавить эту команду в docker compose, который использует образ, вот так?
services:
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
[...]
                
Вы можете создать sh-файл и запустить его из Dockerfile
boot-strap.sh
python manage.py runserver 0.0.0.0:8007
в Dockerfile:
...
ENTRYPOINT ["sh",".../boot-strap.sh"]
таким образом, вы можете добавить другие команды (например, python manage.py migrate ...)
Если что-то имеет смысл поместить в Dockerfile, то поместите это туда (но не все будет иметь смысл).  Подумайте о других способах запуска этого контейнера (docker run; поместите его в манифест Kubernetes), а также о других средах, в которых его можно запустить (например, когда база данных хранится на другом хосте).  Если что-то будет в основном неизменным при каждом запуске контейнера, поместите это в Dockerfile.
В приведенном вами примере образ, который вы создаете, предназначен для приложения Django. Когда бы вы ни запускали образ, независимо от контекста, вы, вероятно, всегда захотите запустить приложение Django, и именно с этой командной строкой. Поэтому поместите в Dockerfile
CMD ./manage.py runserver 0.0.0.0:8000
 и не предоставлять команду Compose command:, docker run, Kubernetes command: или другие настройки времени развертывания.
И наоборот, ваше базовое хранилище базы данных будет разным в каждой среде. Поэтому имеет смысл указать расположение базы данных с помощью переменной окружения или другой настройки и включить ее в конфигурацию развертывания.
# in a host development environment
export PGHOST=localhost
pipenv run ./manage.py runserver
# docker-compose.yml
version: '3.8'
services:
  db:
    image: postgres
  app:
    build: .
    environment:
      - PGHOST=db # (not a Dockerfile ENV)
    ports:
      - '8000:8000'
 Единственное заметное исключение в отношении command: - это если у вас есть образ, который может делать две вещи.  Комбинация Django и Celery является хорошим примером этого: обе половины будут использовать большую часть одной и той же кодовой базы, поэтому для запуска Celery worker вам нужно запустить тот же образ, но с другой командой 
version: '3.8'
services:
  redis:
    image: redis
  app:
    build: .
    environment: [REDIS_HOST=redis]
    ports: ['8000:8000']
  worker:
    build: .
    environment: [REDIS_HOST=redis]
    command: celery worker ...