The Drunken Wiz
The Drunken Wiz

Reputation: 51

Docker pull Django image and run container

So, I have followed this tutorial by Docker to create a Django image.

It completely works on my local machine by just running a docker-compose up command from the root directory of my project.

But, after pushing the image to docker hub https://hub.docker.com/repository/docker/vivanks/firsttry

I am pulling the image to another machine and then running:

docker run -p 8020:8020 vivanks/firsttry

But it's not getting started and showing this error:

EXITED(0)

Can anyone help me on how to pull this image and run it?

My Dockerfile

FROM python:3
ENV PYTHONUNBUFFERED 1
RUN mkdir /code
WORKDIR /code
COPY requirements.txt /code/
RUN pip install -r requirements.txt
COPY . /code/

My docker-compose.yml

  version: '3'
    
  services:
    db:
      image: postgres
      environment:
        - POSTGRES_DB=postgres
        - POSTGRES_USER=postgres
        - POSTGRES_PASSWORD=postgres
    web:
      build: .
      command: python manage.py runserver 0.0.0.0:8000
      volumes:
        - .:/code
      ports:
        - "8000:8000"
      depends_on:
        - db

Upvotes: 4

Views: 520

Answers (2)

Konrad Botor
Konrad Botor

Reputation: 5043

As @larsks mentioned in his answer your problem is that your command is in the Compose file, rather than in Dockerfile.

To run your project on another machine as-is, use the following docker-compose.yml:

version: '3' 
services:
    db:
      image: postgres
      environment:
        - POSTGRES_DB=postgres
        - POSTGRES_USER=postgres
        - POSTGRES_PASSWORD=postgres
    web:
      image: vivanks/firsttry:latest
      command: python manage.py runserver 0.0.0.0:8000
      ports:
        - "8000:8000"
      depends_on:
        - db

If you already added CMD python manage.py runserver 0.0.0.0:8000 to your Dockerfile and rebuilt the image, the above can be further simplified to:

version: '3' 
services:
    db:
      image: postgres
      environment:
        - POSTGRES_DB=postgres
        - POSTGRES_USER=postgres
        - POSTGRES_PASSWORD=postgres
    web:
      image: vivanks/firsttry:latest
      ports:
        - "8000:8000"
      depends_on:
        - db

Using docker run will fail in either case, since it won't set up a database.

Edit:

OP, I admire your persistence, but at the same time do not understand the insistence on using Docker CLI rather than docker-compose. I recommend using one of the above docker-compose.yml files to start your app.

Nevertheless, I accept the challenge of running it without docker-compose.

Your application fails to start when you use docker run command, because it tries to connect to database on host db, which does not exist. In your (and mine) docker-compose.yml there is a definition of a service called db. Docker-compose uses that definition to set up a database container for you and makes it available for your application under hostname db.

To start your application without using docker-compose, you need to manually do everything it does for you automatically (the commands below assume you have added CMD... to your Dockerfile:

docker network create --driver bridge django-test-network
docker run --detach --env POSTGRES_DB=postgres --env POSTGRES_USER=postgres --env POSTGRES_PASSWORD=postgres --network django-test-network --name db postgres:latest
docker run -it --rm --network django-test-network --publish 8080:8000 vivanks/firsttry:latest

The above 3 commands create a new bridged network, create and start a detached (background) container with properly configured database connected to that network and finally create and start an attached (foreground) container based on your image, also attached to that new network. Since both containers are on the same, non-default bridged network, your application will be able to resolve hostname db to internal IP address of the database container and start properly.

Once you shut it down with Ctrl+C, the container with your application will delete itself (as it was started with option --rm), but you need to also manually clean up the rest. To do so run the following commands:

docker stop db
docker rm -v db
docker network remove django-test-network

The first one stops the database container, the second one removes it and its anonymous volume and the third one removes the network.

I hope this explains everything.

Upvotes: 1

larsks
larsks

Reputation: 311606

Your Dockerfile doesn't specify a CMD or ENTRYPOINT. When you run...

docker run -p 8020:8020 vivanks/firsttry

...the container has nothing to do (which means it will actually try to start a Python interactive shell, but since you're not allocating a terminal with -t, the shell just exits. Successfully). In your docker-compose.yml, you're passing in an explicit command:

      command: python manage.py runserver 0.0.0.0:8000

So the equivalent docker run command line would look like:

docker run -docker run -p 8020:8020 vivanks/firsttry python manage.py runserver 0.0.0.0:8000

But you probably want to bake that into your Dockerfile like this:

CMD python manage.py runserver 0.0.0.0:8000

Upvotes: 1

Related Questions