I have been reading up and learning about Docker, and am trying to correctly choose the Django setup to use. So far there is either:
I understand that Dockerfiles
are used in Docker Compose
, but I am not sure if it is good practice to put everything in one large Dockerfile with multiple FROM
commands for the different images?
I want to use several different images that include:
uwsgi
nginx
postgres
redis
rabbitmq
celery with cron
Please advise on what is best practices in setting up this type of environment using Docker.
If it helps, I am on a Mac, so using boot2docker.
Some Issues I've had:
- Docker Compose is not compatible with Python3
- I want to containerize my project, so if one large Dockerfile is not ideal, then I feel I'd need to break it up using Docker Compose
- I am ok to make the project Py2 & Py3 compatible, so am leaning towards django-compose
docker-compose exists to keep you having to write a ton of commands you would have to with docker-cli.
docker-compose also makes it easy to startup multiple containers at the same time and automatically connect them together with some form of networking.
The purpose of docker-compose is to function as docker cli but to issue multiple commands much more quickly.
To make use of docker-compose, you need to encode the commands you were running before into a
docker-compose.yml
file.You are not just going to copy paste them into the yaml file, there is a special syntax.
Once created, you have to feed it to the docker-compose cli and it will be up to the cli to parse the file and create all the different containers with the correct configuration we specify.
So you will have separate containers, lets say for example, one is
redis-server
and the second one isnode-app
and you want that created using theDockerfile
in your current directory.Additionally, after making that container you would map some port from the container to the local machine to access everything running inside of it.
So for your
docker-compose.yml
file you would want to start the first line like so:version: '3'
That tells Docker the version of
docker-compose
you want to use. After that you have to add:Please notice the indentation, very important. Also, notice for one service I am grabbing an image, but for another service I am telling
docker-compose
to look inside the current directory to build the image that will be used for the second container.Then you want to specify all the different ports that you want open on this container.
Please notice the dash, a dash in a yaml file is how we specify an array. In this example I am mapping
8081
on my local machine to8081
on the container like so:So the first port is your local machine, and the other is the port on the container, you could also distinguish between the two to avoid confusion like so:
By developing your
docker-compose.yml
file like this it will create these containers on essentially the same network and they will have free access to communicate with each other any way they please and exchange as much information as they want.When the two containers are created using
docker-compose
we do not need any port declarations.Now in my example, we need to do some code configuration in the Nodejs app that looks something like this:
I use this example above to make you aware that there may be some specific configuration you would have to do in addition to the
docker-compose.yml
file that may be specific to your project.Now, if you ever find yourself working with a Nodejs app and redis you want to ensure you are aware of the default port Nodejs uses so I will add this:
So Docker is going to see that the Node app is looking for
redis-server
and redirect that connection over to this running container.The whole time, the
Dockerfile
only contains this:So, whereas before you would have to run
docker run myimage
to create an instance of all the containers or services inside the file you can instead run,docker-compose up
and you don't have to specify an image because Docker will look in the current working directory and look for adocker-compose.yml
file inside of there.Before
docker-compose.yml
, we had to deal with two separate commands ofdocker build .
anddocker run myimage
, but in thedocker-compose
world if you want to rebuild your images you writedocker-compose up --build
. That tells Docker to start up the containers again but rebuild it to get the latest changes.So
docker-compose
makes it easier for working with multiple containers. The next time you need to start this group of containers in the background you can dodocker-compose up -d
and to stop them you can dodocker-compose down
.