Why is this not in the Dockerfile? - python

I've been messing with Docker and Django lately and rather than clutter up my system, I decided to make a dev container for Django.
I've got it working but I want to know the "why" of this situation.
I followed this tutorial on the Docker website and finally got everything working. I don't get why we do
docker-compose run web django-admin startproject composeexample and not put the django-admin startproject composeexample inside the Dockerfile or the compose file?
EDIT: Here's what I have tried with my limited Docker knowledge:
On separate Dockerfiles I've tried...
CMD django-admin startproject django-tests and CMD ['django-admin startproject django-tests']
And I tried...
command: django-admin startproject django-tests
I've tried to do both but it wont work, it builds the image but without a django project being created. I get a manage.py not found error.
I feel like the project should be inside the image and not have to be run at the end of the docker-compose run command.
So why do we do this and why doesn't putting it inside the Dockerfile work?

I don't get why we do docker-compose run web django-admin startproject composeexample and not put the django-admin startproject composeexample inside the Dockerfile or the compose file?
Because this command is a one-time initialization command that creates a Django project template in your current directory on the host. It doesn't make sense to bake this into a Dockerfile; you will only ever run this once when first creating your project. That's why you're using docker-compose run here, which is for short-lived ad-hoc commands.
Compare the directory before docker-compose run web django-admin startproject composeexample .:
$ ls
docker-compose.yml Dockerfile requirements.txt
And after:
$ ls
composeexample docker-compose.yml Dockerfile manage.py requirements.txt
Running that command created the composeexample directory tree and manage.py files for us.
This works because of the volume configuration in the
docker-compose.yml file:
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
That mounts the current directory (.) as /code inside the
container. Meanwhile, the Dockerfile makes /code the current
working directory:
WORKDIR /code
So when we run the startproject command, files are created inside
/code inside the container which corresponds to our local directory
on the host.

I don't get why we do docker-compose run web django-admin startproject composeexample and not put the django-admin startproject composeexample inside the Dockerfile or the compose file?
Because you don't want to create a new project inside a container. We want to build it locally, add it to container and have the container ready to go with all necessary files wherever this container is deployed.
manage.py not found
This means that you either have not copied the project files into your container or you run you command inside the wrong directory. You can do WORKDIR in the docker-compose or you can get inside your container (it must be running) with
docker exec -it <mycontainer> bash
and see which folder your project is in (if it's there)

Related

I defined a command in compose.yml like command: "python manage.py runserver 0.0.0.0:8000" it works fine. But when I built t

I defined a command in compose.yml like command: "python manage.py runserver 0.0.0.0:8000" and a port mapping when I try docker-compose up it works fine.
But when I built the image and try to run docker run image it exit immediately.
Only things like docker run -d -p 8000:8000 twitch_test_app python manage.py runserver 0.0.0.0:8000 works even though I already defined the command and the port mapping in docker-compose.yml.
Is there any way to just run ```docker run image without repeating the command that is defined in compose.yml file?
Thanks alot.
I think you are confused between docker-compose and docker.
Think docker-compose as a helper utility that help you easily setup docker environment. When you do docker-compose up, it will create a new image and setup docker container for you with all the configuration that you have specified. Your application will run inside the docker container. Docker-compose just makes life little easier.
However, if you want to just use the docker command you need to specify the same port-mapping and other configurations in the dockerfile itself.
When you do docker run image it will create container for you. But you need to provide entrypoint or command to start your application otherwise it will just exit as docker does not know what to do next. In your case I suppose is a Django project and you need to specify "python manage.py runserver" to start your django server. In dockerfile you can specify it using CMD attribute:
CMD [ "python", "manage.py", "runserver" ]

Django in Docker - Entrypoint to initiate Django App Files

at the moment I am trying to build a Django App, that other users should be able to use as Docker-Container. I want them to easily do a run command or starting a prewritten docker-compose file to start the container.
Now, I have problems with the persistence of the data. I am using the volume flag in docker-compose for example to bind mount a local folder of the host into the container, where the app data and config files are located on the container. The host folder is empty on the first run, as the user just installed docker and is just starting the docker-compose.
As it is a bind mount, the empty folder overrides the folder in Docker as far as I understood and so the Container-Folder, containing the Django-App is now empty and so it is not startable.
I searched a bit and as far as I understood, I need to create a entrypoint.sh file that copies the app data folder into the folder of the container after the startup, where the volume is.
Now to my questions:
Is there a Best Practice of how to copy the files via an entrypoint.sh file?
What about a second run, after 1. worked and files already exist, how to not override the maybe changed config files with the default ones in the temp folder?
My example code for now:
Dockerfile
# pull official base image
FROM python:3.6
# set work directory
RUN mkdir /app
WORKDIR /app
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# copy project
COPY . /app/
# install dependencies
RUN pip install --upgrade pip
RUN pip install -r requirements.txt
#one of my tries to make data persistent
VOLUME /app
docker-compose.yml
version: '3.5'
services:
app:
image: app:latest
ports:
- '8000:8000'
command: python manage.py runserver 0.0.0.0:8000
deploy:
replicas: 1
restart_policy:
condition: on-failure
volumes:
- /folder/to/app/data:/app
networks:
- overlay-core
networks:
overlay-core:
external: true
entrypoint.sh
#empty for now
You should restructure your application to store the application code and its data in different directories. Even if the data is a subdirectory of the application, that's good enough. Once you do that, you can bind-mount only the data directory and leave the application code from the image intact.
version: '3.5'
services:
app:
image: app:latest
ports:
- '8000:8000'
volumes:
- ./data:/app/data # not /app
There's no particular reason to put a VOLUME declaration in your Dockerfile, but you should declare the CMD your image should run there.

how to run server using docker container?

Django server is running well in localhost. however, When I try to run server on the docker container, it doesn't find the manage.py file when using docker-compose file and even I run the container manually and run the server, it doesn't appear in browser. how can I solve this problem?
So I wrote all the code testing on my local server and using the dockerfile, I built the image of my project.
and I tried to run server on the docker container, suddenly this doesn't run.
what's worse, if I use docker-compose to run the server, it doesn't find the manage.py file though I already checked with 'docker run -it $image_name sh'
here is the code of my project
I am new to docker and new to programming.
hope you can give me a help. thanks!
file structure
current directory
└─example
└─db.sqlite3
└─docker-compose.yml
└─Dockerfile
└─manage.py
└─Pipfile
└─Pipfile.lock
Docker file
# Base image - Python version
FROM python:3.6-alpine
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Set work directory
WORKDIR /code
# Copy Pipfile
COPY Pipfile /code
COPY Pipfile.lock /code
# Install dependencies
RUN pip install pipenv
RUN pipenv install --system
# Copy files
COPY . /code/
docker-compose.yml
# docker-compose.yml
version: '3.3'
services:
web:
build: .
command: python /code/manage.py runserver 0.0.0.0:8000
volumes:
- .:/code
ports:
- 8000:8000
expected result : running server in web browser like in chrome
actual result :
when using docker-compose :
ERROR like this in the prompt : web_1 | python: can't open file '/code/manage.py': [Errno 2] No such file or directory
when running the container manually with 'docker run -it $image_name sh' and 'python manage.py runserver' on the shell :
server is running but, doesn't connect to web browser. (doesn't show up in browser like chrome'
Yo have done same thing in many ways. You have copy source files using a COPY command and then you have mounted a host volume in your docker-compose.yml file. In first place you don't need a volume because volume mounts are to persisting data generated by and used by Docker containers.
Following simplified Dockerfile and docker-compose file would fix the problem.
# Base image - Python version
FROM python:3.6-alpine
# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# Copy files
COPY . /code/
# Set work directory
WORKDIR /code
# Install dependencies
RUN pip install pipenv
RUN pipenv install --system
docker-compose.yml -:
# docker-compose.yml
version: '3.3'
services:
web:
build: .
command: python ./manage.py runserver 0.0.0.0:8000
ports:
- 8000:8000

Unable to connect to server when running docker django container

I have looked through the questions on this site, but I have not been able to fix this problem.
I created and ran an image of my django app, but when I try to view the app from the browser, the page does not load (can't establish a connection to the server)
I am using docker toolbox, I am using OS X El Capitan and the Macbook is from 2009.
The container IP is: 192.168.99.100
The django project root is called "Web app" and is the directory containing manage.py. My Dockerfile and my requirements.txt files are in this directory.
My dockerfile is:
FROM python:3.5
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
My requirements.txt has django and mysqlclient
My django app uses Mysql, and I tried to view the dockerized django app in the browser with and without linking it to the standard mysql image. In both cases, I only see the following error:
problem loading page couldn't establish connection to server
When I did try linking the django container to the mysql container I used:
docker run --link mysqlapp:mysql -d app
Where mysqlapp is my mysql image and 'app' is my django image.
In my django settings.py, the allowed hosts are:
ALLOWED_HOSTS: ['localhost', '127.0.0.1', '0.0.0.0', '192.168.99.100']
Again, the image is successfully created when I used docker build, and it is successfully run as a container. Why is the page not loading in the browser?
I suggest to use yml file and docker compose. Below is a template to get you started:
[Dockerfile]
FROM python:2.7
RUN pip install Django
RUN mkdir /code
WORKDIR /code
COPY code/ /code/
where your files are located in code directory.
[docker-compose.yml]
version: '2'
services:
db:
image: mysql
web0:
build: .
command: python manage.py runserver 0.0.0.0:8000
ports:
- "8000:8000"
depends_on:
- db
There might be a problem with your working directory path defined in Dockerfile. Hope above helps.
Solution provided by salehinejad seems to be good enough ,although i have not tested it personally but if you do not want to use yml file and want to go your way then you should expose the port by adding
-p 0:8000
in your run command
So your should look like this :
docker run -p 0:8000 --link mysqlapp:mysql -d app
I suspect you have not told Docker to talk to your VM, and that your containers are running on your host machine (if you can access at localhost, this is the issue).
Please see this post for resolution:
Connect to docker container using IP

run django in docker container

I'm trying to make a simple example of Django app running in docker container.
using this image https://hub.docker.com/_/django/
just for simplicity. Don't tell me please that i shouldn't use it in production :) app is very simple and i'm ok with using very basic Django server.
So, the problem is i'm always getting this error when trying to run the container image
C:\Users\slipo\PycharmProjects\simple_blog>docker run -p 8000:8000 my-blog
python: can't open file './manage.py runserver 0.0.0.0:8000 --settings=mysite.settings.prod': [Errno 2] No such file or directory
however, ./manage.py and mysite.settings.prod both definitely existing in container.
container creation log showing the file exists:
Step 7 : RUN ls -a
---> Running in 932ed2ad3e4c
.
..
.idea
Dockerfile
blog
manage.py
mysite
requirements.txt
templates
---> e7f938c1cbf2
Removing intermediate container 932ed2ad3e4c
Step 8 : CMD python ./manage.py runserver 0.0.0.0:8000 --settings=mysite.settings.prod
---> Running in f99bcafbc269
---> aca534e9ccb6
Removing intermediate container f99bcafbc269
Successfully built aca534e9ccb6
Dockerfile:
FROM django
EXPOSE 8000
ADD . /simple_blog
WORKDIR /simple_blog
RUN pip install -r requirements.txt
RUN pip install django-tinymce
RUN ls -a
CMD [ "python", "./manage.py runserver 0.0.0.0:8000 --settings=mysite.settings.prod" ]
Thank you.
can't open file './manage.py runserver 0.0.0.0:8000 --settings=mysite.settings.prod'
This is telling you that it is treating that entire string as a single filename.
I assume something like this works:
CMD [ "python", "./manage.py", "runserver", "0.0.0.0:8000", "--settings=mysite.settings.prod" ]
Try to execute this code.
CMD [ "python", "../manage.py runserver 0.0.0.0:8080 --settings=my_site.settings.prd"

Categories