Home > Net >  Running django app with docker, unrecognized runserver arguments
Running django app with docker, unrecognized runserver arguments

Time:08-13

I'm having a problem with starting my django project in docker container. I have tried this in multiple ways, for example:

docker-compose run web python manage.py runserver

or just

docker-compose up

first time i have tried this i got no error, but i couldn't open the app in browser so i tried it again and then it stopped working completely. I'm getting this error:

manage.py runserver: error: unrecognized arguments: python manage.py runserver

My docker-compose.yml

version: "3.9"

services:
  db:
    image: postgres:alpine
    volumes:
      - ./data/db:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=gitlabdumptables
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/code
    ports:
      - "8000:8000"
    environment:
      - POSTGRES_NAME=gitlabdumptables
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
    depends_on:
      - db

My Dockerfile

# syntax=docker/dockerfile:1
FROM python:3
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /code
COPY requirements.txt /code/
RUN pip3 install -r requirements.txt
CMD python manage.py makemigrations
CMD python manage.py migrate
COPY . /code/
ENTRYPOINT [ "python", "manage.py", "runserver", "0.0.0.0:8000" ]

CodePudding user response:

The main process run in a Docker container is made up of two parts. You're providing an ENTRYPOINT in the Dockerfile, and then the equivalent of a CMD with the Compose command: or docker run ./manage.py ... arguments. When you have both an ENTRYPOINT and a CMD, the CMD gets passed as additional arguments to the ENTRYPOINT; so in this case, you're running python manage.py runserver 0.0.0.0:8000 python manage.py runserver 0.0.0.0:8000.

For this setup I'd suggest:

  • If you want to be able to override the command when you launch the container (which is useful), prefer CMD to ENTRYPOINT in your Dockerfile. Then these command overrides will replace the command.
  • If you have a useful default command (which you do), put it as the Dockerfile CMD. You do not need to specify a Compose command:.

You're also trying to run migrations in a way that won't work; again, a container only runs a single process, and the last CMD or the startup-time override wins. I'd use an entrypoint wrapper script to run migrations:

#!/bin/sh
# entrypoint.sh

# Run migrations
python manage.py migrate

# Then run the main container command (passed to us as arguments)
exec "$@"

In your Dockerfile make sure this is COPYed in (the existing COPY command you have will do it) and make this script be the ENTRYPOINT (with JSON-array syntax).

FROM python:3.10
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /code
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY ./ ./
ENTRYPOINT ["./entrypoint.sh"]                           # must be JSON-array form
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"] # not ENTRYPOINT

In your Compose file, you don't need to inject the code with volumes: or replace the command:, these are already part of your Dockerfile.

version: '3.8'
services:
  db: { ... }
  web:
    build: .
    ports:
      - '8000:8000'
    environment: { ... }
    depends_on:
      - db
    # but no volumes: or command:
  • Related