Posts Docker Primer
Post
Cancel

Docker Primer

Docker

3 basic concepts of Docker

Containers

A container is what we eventually want to run and host in Docker.From a conceptual point of view, a container runs inside the Docker host isolated from the other containers and even the host OS. It cannot see the other containers, physical storage, or get incoming connections unless you explicitly state that it can. It contains everything it needs to run: OS, packages, runtimes, files, environment variables, standard input, and output.

Images

Any container that runs is created from an image. An image describes everything that is needed to create a container; it is a template for containers. You may create as many containers as needed from a single image.

Registery

Images are stored in a registry. Its can be viewed as a repository for images like GitHub.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ docker run alpine printenv # run alpine container with print env command
$ docker ps    # show running containers
$ docker ps -a. #  show all containers
$ docker log #id    # logs of container
$ docker inspect #id # inspect container
 
$ docker stop #id    # stop running container
$ docker run #id 	# to run the container again
$ doker rm #id 			# remover a container

$ docker container prune -f  # rm all stoped container: equivalent of running rm on each container
$ docker container ls  # same as ps
$ docker network ls

Networking with containers

By default, a container runs in isolation, and as such, it doesn’t listen for incoming connections on the machine where it is running. You must explicitly open a port on the host machine and map it to a port on the container.

1
$ docker run -d -p 8085:80 nginx

Create a network between container

This will allow you to connect to other conatiner in network by container name, whereas by default(bridge) you need to use contaier IP address($ docker network inspect bridge)

1
2
3
4
5
6
7
8
9
10
# 1) Create new network
$ docker network create <network-name>       # this will create bridge
# List Docker’s networks:
$ docker network ls
# 2) Connect containers to network
$ docker network connect <network-name> <container-name>
# 3) Ping container by name
$ docker exec -ti <container-name-A> ping <container-name-B> 
# remove network when done
$ docker network rm alpine-net

Container which binds directly to port 80 on the Docker host.From a networking point of view, this is the same level of isolation as if the process were running directly on the Docker host and not in a container.

1
$ docker run --rm -d --network host --name my_nginx nginx

Volumes and containers

When a container writes files, it writes them inside of the container. Which means that when the container dies ( removed ) it loses all of its data. A rule of thumb for the sake of simplicity is to ensure that containers are stateles. Sometimes you want to store files in a place where they are persisted; this is done using volumes.

1
2
3
$ docker run -v /your/dir:/var/lib/mysql -d mysql:5.7
#To mount the file system as read-only, use ro flag. 
$ docker run -it -v <absolute_path>:<folder path or new folder name>:ro date_project:1.0

It will ensure that any data written to the /var/lib/mysql directory inside the container is actually written to the /your/dir directory on the host system. This ensures that the data is not lost when the container is restarted.

Miscellaneous

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
$ docker pull \<images-name>:<version> # pulls image from Docker registry
$ docker run \<images-name>:\<version> # runs container from mentioned image
$ docker ps # shows all running containers
$ docker ps -a: #shows all available containers
$ docker exec# executes a command in a running container
$ docker run -it <container name> <command to execute>
$ docker exec -it <container id/name> bash # execute bash in container
$ docker attach <container id/name>  # attach  
$ docker network inspect bridge # this will show brige details with ip


docker commit -m "<commit message>" <container_id/name> <new_image_name>:<version>
Next, you should push your image to your Docker Hub account so that anybody can access it.

#Steps to push:

$Docker login

# Docker Container

# run in detatch mode
$docker run -d -v <path_to_code_directory>:/code -p 5000:5000 flask_app:1.0

# to interact with the detached containers.
$docker exec -it <container_id> bash
$ docker logs

# SET env variables
$docker run --name mysql -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=backend -e MYSQL_USER=testuser -e MYSQL_PASSWORD=admin123 mysql/mysql-server:5.7

# linking container DEPRICATED
$docker run --link "mysql:backenddb" -p 5000:5000 flask_app:1.0




Sample Docker files

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FROM node:10-alpine

# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app

# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install

WORKDIR /usr/src/app

# Bundle app source
COPY . /usr/src/app/

EXPOSE 80

CMD ["npm", "start"]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM python:3.7-stretch

# Install modules
RUN pip install Flask

# Needed by the Flask module
ENV FLASK_APP=server.py

# Copy source files into the image
COPY templates ./templates
COPY server.py .

EXPOSE 5000

CMD ["flask", "run", "--host=0.0.0.0"]
This post is licensed under CC BY 4.0 by the author.