Running pre-made images is very useful and can save you a lot of time, but at some point you will want to create your own images.
The training/webapp
image is limited in that it can only say "Hello World" or "Hello Your Name", let’s see if we can expand on the original image to display a value stored in a Postgres database.
1. What do we need to change?
Here is an overview of what we need to change (detailed instructions below):
-
Expand the original image
-
Install Python dependencies in the container to enable connections to a Postgres database
-
Replace the original Python application with our new version that uses the database
-
-
Setup a docker network so that the
webserver
can get its data from thedatabase
container -
Run a database with data
-
Run a Postgres database image
-
Add our data to the running database
-
-
Run the newly built image
-
Display the data from the database on the webpage
-
The following sections will discuss all these steps one-by-one.
2. Understanding the Dockerfile used to build the image
In order to build a Docker image yourself you need a Dockerfile. In this case we will supply you with the Dockerfile necessary to create the image. But you will have to run the build process yourself to make the image available to your Docker daemon.
-
Download the workshop zip file and unzip it on your local harddisk
-
Look at the Dockerfile in the
docker-images/webserver
folder.[a] FROM training/webapp [b] ENV DEBIAN_FRONTEND=noninteractive [c] RUN apt-get -y update && apt-get -y install libpq-dev python-dev [c] RUN pip install pygresql [d] ADD app.py /opt/webapp/app.py
Each line in the Dockerfile is explained below:
-
We use the
training/webapp
image as a base-image -
We set the DEBIAN_FRONTEND environment variable to make sure that the next command runs in noninteractive mode
-
We run 2 commands inside the container to install python and pygresql (a library that lets python code talk to PostgreSQL)
-
We overwrite the existing
app.py
file with our newapp.py
file that will check the database.
3. Building the new image
We now have to instruct Docker to use the Dockerfile and build it. Additionally, we assign the tag webserver
to the new image.
Make sure your working directory is docker-images/
|
docker build -t webserver webserver/
Read the documentation of the build command: docker build --help
|
The command should exit output similar to:
Successfully built 98ac0aa0d27d Successfully tagged webserver:latest
4. Setup a docker network
If we want docker containers to be able to reach each other, we need to setup a docker container network. A Docker network automatically allows Docker containers to reach each other by container name, as long as they are part of the same network. This works via the DNS server on the Docker daemon. To create a docker network called "training" we need to run the following command:
docker network create training
5. Starting the new image
Before we start a container with the webserver
image we first need to start a Postgres database that will store our data for us.
Luckily, we can use an off-the-shelf image provided by Postgres.
docker run --rm --network training --name database -e POSTGRES_PASSWORD=myPassword -d postgres
6. Add data to the database
Before we can get data from the database, we first need to put the data in of course. For that, we need a database client to connect to the Postgres database. Luckily, the Postgres image also contains a client! We can start another container from the Postgres image, but instead of the database, we’ll start the client. From there we can connect to the previously started database container so we can add some data to the database to display on the webpage.
docker run -it --rm --network training postgres psql -h database -U postgres
This starts a new instance of the postgres
image in interactive mode (-it
), removes it after stopping the container (--rm
), makes it part of the training
-network and executes psql -h database -U postgres
inside the container in order to connect to the running database container.
CREATE DATABASE mydata; \c mydata CREATE TABLE kv (key varchar(100) PRIMARY KEY, value varchar(100)); INSERT INTO kv VALUES ('provider','Now getting data from Postgres!'); SELECT * FROM kv; -- Check that the data is really there \q
7. Run the newly built webserver image
docker run -it --rm --network training --name webserver -p 5000:5000 webserver
In foreground mode (the default when -d is not specified), docker run can start the process in the container and attach the console to the process’s standard input, output, and standard error. It can even pretend to be a TTY (this is what most command line executables expect) and pass along signals.
For interactive processes (like a shell), you must use -i -t together in order to allocate a tty for the container process. -i -t is often written -it.
|
Error on Windows:
On Windows/GIT Bash/Cygwin you may get the following error the input device is not a TTY. the input device is not a TTY. If you are using mintty, try prefixing the command with 'winpty' .
Run the command again with winpty in front of it. Refer to this page for details.
|