[PYTHON] I started Docker

I heard that it would be convenient to put all the tools I made into a container, so I decided to start using Docker, which I had been interested in for a long time. This time, I will make a web server made with python flask into a container so that I can manage the web server just by starting and stopping the container.

Click here for the environment used

$ cat /etc/redhat-release 
Red Hat Enterprise Linux release 8.2 (Ootpa)
$ docker --version
Docker version 19.03.12, build 48a66213fe

Docker review

First, let's briefly summarize how to use Docker (how to make a container). There are 4 steps to create a Docker container.

  1. Pull the base image
  2. Create Dockerfile
  3. Build a Docker image
  4. Create and start Docker container from image

Personally, I think the first thing I don't really understand is creating a Dockerfile. So, the first step is to create a simple python script inside the container, and the second step is to improve it to run the flask web server.

Executing a python script inside a container

The first step is to run the next myapp.py inside the container.

myapp.py


print("hello Docker!")

Pull the base image

First, prepare an image that will be the execution environment for python3. Search for python3 series images registered in Docker Hub.

$ sudo docker search python3
NAME                                                                    DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED
rackspacedot/python37                                                                                                   11                                      
sellpy/python3-jupyter-sklearn                                          python3-jupyter-sklearn                         5                                       [OK]
openwhisk/python3action                                                 Apache OpenWhisk runtime for Python 3 Actions   5                                       
sellpy/python3-jupyter-sklearn-java                                     python3-jupyter-sklearn-java                    2                                       [OK]
quoinedev/python3.6-pandas-alpine                                       Python 3.7 on alpine with numpy and pandas i…   2                                       
(Omitted)

This time we will use rackspacedot / python37, which has the most STARS. Let's pull this.

$ sudo docker pull rackspacedot/python37

rackspacedot / python37 is also a Docker image, so you can check it with docker images after pulling.

$ sudo docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
rackspacedot/python37   latest              3d51361ee118        7 weeks ago         1.06GB

If you have this image, you can use python in the container, so if you add other necessary parts (such as script placement) based on this, it's OK.

Create Dockerfile

Then create a file named Dockerfile.

FROM rackspacedot/python37

WORKDIR /usr/local/script
COPY myapp.py .

CMD python myapp.py

To briefly explain,

The files prepared so far are as follows.

$ ls -l
total 8
-rw-r--r--. 1 user developer 146 Sep 11 16:39 Dockerfile
-rw-r--r--. 1 user developer 173 Sep 11 17:04 myapp.py

Start Docker image build container

Now that we have created a Dockerfile, we will build the image → start the container. First, build the image.

$ sudo docker build -t myapp:test .

The -t name: tag sets the name and tag of the image (it can be different from the script name). . Specifies the path of the directory where the Dockerfile is located. If you get Successfully built hash value, the image is generated and you can check it with docker images.

$ sudo docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
myapp                   test                e577339515a7        10 seconds ago      1.06GB
rackspacedot/python37   latest              3d51361ee118        7 weeks ago         1.06GB

Now that the image is created, create and start the container.

$ sudo docker run myapp:test
hello Docker!

I was able to successfully run the python script in the container. The container started here remains, so you can run it again with the same command. You can also see the container created with docker ps -a.

Running a flask server inside a container

Now that you can run python scripts inside the container, let's create a server in flask as the second step. Rewrite myapp.py as follows:

from flask import Flask

app = Flask("myapp")

@app.route("/")
def main():
    return "hello Docker!!"

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=8080)

For the time being, I reduced the number of ! To 2 so that you can see the change. Let's make this usable as a web server in the container.

Docker file fix

Since we are using flask, we need to install flask inside the container. pip is included in rackspacedot / python37by default, so add the part thatpip install` to the Dockerfile when building the image.

FROM rackspacedot/python37

RUN pip install flask

RUN useradd docker
USER docker

WORKDIR /usr/local/script
COPY myapp.py .

CMD python myapp.py

To explain the added amount,

Start Docker image build container

Since the file was rewritten, rebuild the image → start the container. First of all, from rebuilding.

$ sudo docker build -t myapp .

Since we omitted the tag this time, the tag latest is automatically assigned. Let's check with docker images.

$ sudo docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             SIZE
myapp                   latest              6c747be5d597        3 seconds ago       1.06GB
myapp                   test                e577339515a7        50 minutes ago      1.06GB
rackspacedot/python37   latest              3d51361ee118        7 weeks ago         1.06GB

Now let's start the container. Since it is a web server, I am adding options.

$ sudo docker run -d -p 8080:8080 myapp

Although it is a port number, it is written as -p reception port number: number on the container side. The receiving port number can be any number, but the number on the container side should be the number specified in myapp.py in the container (8080 in this case).

If it starts without any problem, you can check the running container with docker ps.

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
00d1ab6fc24a        myapp               "/bin/sh -c 'python …"   3 seconds ago       Up 2 seconds        0.0.0.0:8080->8080/tcp   thirsty_mccarthy

Let's actually access it.

$ curl http://localhost:8080
hello Docker!!

Sounds good. This completes the containerization of the web server. If you want to stop the container

$ sudo docker stop thirsty_mccarthy

If you want to restart after stopping

$ sudo docker start thirsty_mccarthy

For thirsty_mccarthy, specify the container name (the one displayed in NAME when docker ps is executed). If you start it with docker start, it will automatically run on the port you specified during docker run. Also, if you make it into a container, you can run it in another environment immediately by building the image → starting the container, which is very convenient.

That's all for this time. If Docker Compose can execute multiple containers with a single command, the range will expand further, so I think I will study this as well.

Recommended Posts

I started Docker
I started python
I started to analyze
I started PYNQ (2) -Overlay self-made-
I started, but it doesn't start!
Getting started on Docker Apache Hadoop
I checked the contents of docker volume
Docker installation
I tried to get started with Hy
I created an Anaconda environment using Docker!
Django + Docker
I researched Docker, so I will summarize it
started python
I started Node.js in a virtual environment
What I did before installing Docker for Windows
I started machine learning with Python Data preprocessing