This chapter will set up a local container Django project to get a feel for how Docker works.
preparation
The development environment
There are windows-based versions of Docker, but they are not very compatible (and difficult to install), so it is recommended that you install your own Linux or Mac system before learning. You can do it on Windows if you want.
Don’t worry, Django projects can still be developed on Windows, just without Docker.
Software installation
- Docker: Learn Docker of course to install Docker software (free community version), installation method see official documentation.
- Docker-compose: Docker is an official tool for composing and running multiple containers. See the official documentation for the installation method. Most of this tutorial is about it.
- Python3: The tutorial deploys a Django project, so Python3 is a must (including Python’s package management tool PIP).
Move on when you’re ready.
Creating a Django project
Open a Linux/Mac terminal and install the Django library:
$PIP install django = = 2.2
Copy the code
Create a new Django project in a location you like (such as /home/) :
$ django-admin startproject django_app
Copy the code
Go to the project root directory:
$ cd django_app
Copy the code
The rest of the tutorial is done in this directory. For easy reading, the command prompt $represents the project root directory django_app/, mysql $represents the project root directory django_app/mysql/, please pay attention to the current working directory.
Then migrate the data:
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
...
Applying sessions.0001_initial... OK
Copy the code
The preparation is done.
Build projects with Docker
I met Docker
The whole life cycle of Docker consists of three parts: image + container + repository.
The container is instantiated from the image, which is a bit like the object-oriented concept: the image is the class, and the container is the object after the class is instantiated.
An image is a read-only template that contains the data needed to run the container. An image can contain a full Linux operating environment, with only Python or other programs installed that the user needs.
A container is an instance created by an image, similar to a virtual machine, in which specific applications can run. Containers are isolated from each other.
The repository concept is similar to Git and Github, and is easy to understand if you’ve ever used them. The default repository used by Docker is the Docker Hub public repository maintained by the official, from which the operation of uploading and pulling is similar to Git.
That’s all you need to know for now. Let’s do it in practice.
Hello-world
To verify that Docker is properly installed, run the following command:
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
...
latest: Pulling from library/hello-world
1b930d010525: Pull complete
...
Hello from Docker!
This message shows that your installation appears to be working correctly.
...
Copy the code
If all goes well, the terminal will print out the welcome statement shown above. The docker run hello-world directive says: Build a container with an image named hello-world and run it. If the hello-world image is not available locally, Docker will automatically search for and download the image with the same name from the repository.
We can use Docker images to view local images:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest fce289e99eb9 9 months ago 1.84kB
Copy the code
The table lists the image name, version, ID, creation time, and size.
You can also view existing containers locally:
$ docker ps -a
CONTAINER ID IMAGE .. CREATED ..
38cb03a96dca hello-world .. 2 minutes ago ..
Copy the code
There are also some basic instructions that are very useful:
Docker rmI [images ID] # delete the image of this ID docker container stop [container ID] # stop the container of this ID docker container start [container Rm [container ID] # delete container with docker IDCopy the code
Since images are generated frequently during tests, you will definitely use the above commands to view and remove useless images and containers.
Now that you’ve done your little trial run, build your Django container.
Dockerfile
Docker allows images to be built from a configuration file in text format, with the default name Dockerfile. So create a new file Dockerfile in the project root directory and say:
#Pull a Linux environment with Python 3.7 from the repositoryThe FROM python: 3.7
#Set the Python environment variables
ENV PYTHONUNBUFFERED 1
#Create a code folder and set it as a working directory
RUN mkdir /code
WORKDIR /code
#Update the PIP
RUN pip install pip -U
#Copy requirements.txt to the container's code directory
ADD requirements.txt /code/
#Install the library
RUN pip install -r requirements.txt
#Copy the current directory to the container's code directory
ADD . /code/
Copy the code
The key to understanding these Docker instructions is to keep in mind that the environment inside the container is completely different from the outside world (host). In other words, figure out which operations are for the host and which are for the container.
The FROM Python :3.7 directive pulls a Linux operating system environment (Linux version Debian) that contains Python 3.7 FROM the repository.
The RUN and WORKDIR directives are container-specific and create directories within the container and set them as working directories. Note that the host does not have this directory.
The ADD instruction appears twice. ADD requirements. TXT /code/ means to copy the requirements. TXT file from the current directory of the host (that is, the directory where the Dockerfile resides) into the /code directory of the container. ADD. /code/ means to copy the contents of the current directory to the container /code/ directory. Note the dot in the middle.
The only library your project currently relies on is Django, so create requirements.txt in the project root directory and say:
Django = = 2.2Copy the code
Why install Django when you’ve already installed it? The reason is that it was installed on the host, and Django doesn’t come with the container!
So the current file structure is as follows:
django_app
- Dockerfile
- requirements.txt
- manage.py
- django_app
- db.sqlite3
Copy the code
Docker-compose: docker-compose: docker-compose: docker-compose
Docker-compose
In an online environment, you don’t usually put all the components of a project in the same container; It is better to put each individual function into a separate container for easy reuse. Put your Django code in container A, your Mysql database in container B, and so on.
Therefore, it is possible to run multiple containers on the same server, and it would be too tedious to rely on a command to start each time. Docker-compose is composed to compose multiple containers. The docker-compose command is written to docker-compose. Yml file. Docker-compose will also be used to manage containers.
Docker-compose installation is successful:
$ docker-compose -vDocker-compose version 1.24.1, build 4667896bCopy the code
Create docker-comemess. yml in the project root directory and write:
Version: "3" services: app: restart: always build:. # 'dot' Python3 manage.py runserver 0.0.0.0:8000" volumes: -.:/code ports: - "8000:8000"Copy the code
Let’s break down the implications.
Version represents the docker-comemess. yml version. Currently, the latest version is 3 and there is no need to change it.
We then define a container called app. The following is the configuration of the APP container:
restart
: The container can be restarted at any time except when it is working properly, such as when it encounters a bug, a process crash, a Docker restart, etc.build
: Specifies an includeDockerfileAnd build the container image from this Dockerfile. Pay attention to the“.”Represents the current directory.command
: Commands that need to be executed when the container runs. This is the familiar running development server.volumes
:Volume, this is a very important concept.As mentioned earlier, the container is completely isolated from the host, but sometimes it needs to be connected; Our Django projects, for example, are often updated, and rely on programs like Git to update their code, making it inconvenient to operate in a container. So there is avolume, which defines the mapping between the host and the container:“.”Represents the current directory of the host,“:”Is the delimiter. “/code” indicates the directory in the container. That is, the current directory of the host is connected to the /code directory of the container. When Django code in the current directory of the host is updated, the code in the /code directory of the container is also updated. It’s kind of like punching a hole in the container, in a waypracticalandIsolation,A compromise.
Docker-compose: docker-compose: docker-compose: docker-compose: docker-compose: docker-compose: docker-compose: docker-compose: docker-compose: docker-compose That will be covered in a later chapter.
ports
: defines the port mapping between the host and container. The container is isolated not only from the environment, but also from the ports. However, the Web application cannot communicate with the outside world without using the port. Therefore, the definition is to map port 8000 of the host to port 8000 of the container, that is, to access port 8000 of the host is to access port 8000 of the container, but ensure that the port is not occupied by other programs.
The configuration is written. The directory structure of the project is now as follows:
django_app
- docker-compose.yml
- Dockerfile
- requirements.txt
- manage.py
- django_app
- db.sqlite3
Copy the code
test
Enter the docker-compose up command to start the container service:
$ docker-compose upCreating network "django_app_default" with the default driver Building app Step 1/8: FROM Python :3.7 3.7: Pulling from library/python 4a56a430b2ba: Pull complete ... 6933d3d46042: Pull complete Digest: sha256:0f0e991a97426db345ca7ec59fa911c8ed27ced27c88ae9966b452bcc6438c2f Status: Downloaded newer Image for Python :3.7 ---> 02d2bb146b3b
Step 1/8 : FROM python:3.7
---> 02d2bb146b3b. Step 7/8 : RUN pip install -r requirements.txt ---> Running in 62a60a3003feLooking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting django = = 2.2 (from - r requirements. TXT) (line 1) Downloading https://files.pythonhosted.org/packages/54/85/0bef63668fb170888c1a2970ec897d4528d6072f32dee27653381a332642/Django-2.2-py 3 - none - any. WHL (7.4 MB)... Installing COLLECTED packages: SQLparse, Pytz, Django Successfully installed Django-2.2 pytz-2019.2 SQLparse-0.3.0... Step 8/8 : ADD . /code/ ---> cb23f483ffb6
Successfully built cb23f483ffb6
Successfully tagged django_app_app:latest
WARNING: Image for service app was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
Creating django_app_app_1 ... done
Attaching to django_app_app_1
app_1 | Watching for file changes with StatReloader
app_1 | Performing system checks...
app_1 |
app_1 | System check identified no issues (0 silenced).
app_1 | October 05, 2019 - 15:03:15
app_1 | Django version 2.2, using settings 'django_app.settings'
app_1 | Starting development server at http://0.0.0.0:8000/
app_1 | Quit the server with CONTROL-C.
Copy the code
It can be seen that Docker successfully built the image and container according to the requirements of the configuration file, and started the container.
Open your browser and enter the local IP port 127.0.0.1:8000:
Seeing Django’s little rocket, the project is up and running. Press Ctrl + C to stop the development server.
The container actually exists after you stop the server, it just stops running. Input:
$ docker-compose down
Copy the code
You can delete the container.
If you want to run the container in the background, type:
$ docker-compose up -d
Copy the code
Also, if you need to rebuild the image, type:
$ docker-compose build
Copy the code
Start and stop existing containers:
$ docker-compose start
$ docker-compose stop
Copy the code
That’s easy.
Downloading too slowly?
For reasons known to all, the domestic network environment is very complicated. It is often necessary to pull resources from remote warehouses abroad while building the image, and the unbreakable download speed is a real headache.
The solution is to modify the resource pull link to a domestic mirror source, such as tsinghua mirror source.
Modify Dockerfile as follows:
FROM Python :3.7 ENV PYTHONUNBUFFERED 1
#Add Debian Tsinghua mirror source
RUN echo \
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free\
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free\
deb https://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free\
deb https://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free\
> /etc/apt/sources.list
RUN mkdir /code
WORKDIR /code
#Add PIP Tsinghua image source
RUN pip install pip -U -i https://pypi.tuna.tsinghua.edu.cn/simple
ADD requirements.txt /code/
#Add PIP Tsinghua image source
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
ADD . /code/
Copy the code
Rebuild the image and the download speed will fly.
The content behind the tutorial is using tsinghua source, but in order to facilitate reading, this part of the replacement source code omitted, readers understand.
conclusion
This chapter gives you a taste of the Docker workflow and makes it easy to build a containerized Django project.
The next chapter adds the MySQL database to the container choreography.
- If you have any questions please leave a message on Doucet’s personal website and I will reply as soon as possible.
- Django-docker-tutorial
- Or Email me a private message: [email protected]