Freeman: Essential Docker for ASP.NET Core MVC
Quick Reference
-
docker images- list images -
docker build- create a custom image from a base image via a Dockerfile -
docker rmi- delete an image -
docker ps -a- list containers -
docker run- creates and runs the specified image as a container (downloads it if not found and it can) -
docker create- creates the container from the image
Chapter 1 Understanding Docker
Consistency Problem
- Differences in environment cause the application to behave differently e.g. no reverse proxy in development
- Differences in dependencies on version of dev tools e.g. .NET version
- Differences in the way the solution is deployed
- Ensuring all servers for an application are configured consistently
With Docker
- Development image - differs only by containing compiler and debugger
- Production image - omits dev tools and has compiled version of classes
Responsiveness Problem
- ASP.NET applications historically struggle to provision the right amount of capacity to deal with their workload
With Docker
- The container provides a lightweight wrapper around the application. The application can be scaled horizontally by adding further containers when required.
Containers v VMs
- Containers only isolate applications but otherwise still depend on the underlying machine - linux containers can only run on linux VMs, windows on windows
- A single server can run more containers than VMs - fewer resources are spent on low level OS tasks
Limitations
- Containers work best for MVC applications which are stateless - any state data needs to be stored in such a way that it is accessible from each container (another container running redis?)
- If an application can’t be scaled via duplication the benefits of using containers diminishes
- Linux has mature support for Docker, but only Windows Server 2016 and Windows 10 (pre release versions only) support Docker
- .NET Core and ASP.NET Core both work on Linux and Linux containers are recommended
Other containerisation options
- Open Container Initiative aims to standardise the use of containers
- Main Docker competitor is
rktproduced by CoreOS
Chapter 2 Essential Docker Quick Reference
Images
The Docker image used to deploy ASP.NET Core applications does not contain the .NET Core compiler so the application must be compiled with all dependencies. Within the project folder of the application run to publish the output artefacts to a folder called dist.
dotnet publish --framework netcoreapp1.1 --configuration Release --output dist
Use docker build to build the image from a Docker file e.g. docker build . -t apress/exampleapp -f Dockerfile where . indicates the current directory as the working directory; -t is the name of the image; -f specifies the Docker file
| Command | Description |
|---|---|
docker build |
This command processes a Docker file and creates an image. |
docker images |
This command lists the images that are available on the local system. The -q argument returns a list of unique IDs that can be used with the docker rmi command to remove all images. |
docker pull |
This command downloads an image from a repository (often don’t need to run explicitly) |
docker push |
This command publishes an image to a repository. You may have to authenticate with the repository using the docker login command. |
docker tag |
This command is used to associate an (alternative) name with an image. |
docker rmi |
This command removes images from the local system (specifying the image ID). The -f argument can be used to remove images for which containers exist. To remove all images use docker rmi -f $(docker images -q) to pump all images IDs to the rmi command. |
docker inspect |
Displays details about the image |
Useful prebuilt images include images containing: ASP.NET Core runtime; .NET Core runtime; .NET Core SDK (for development); MySQL; HAProxy, useful as a load balancer / configured to respond to containers starting and stopping
Docker files contain a series of commands including:
- FROM - specify base image;
- WORKDIR - change the working dir for subsequent commands;
- COPY - add files to become part of the container’s file system;
- RUN - execute command e.g download dependencies
- EXPOSE - expose a port from the container
- ENV - create environment vars
- VOLUME -
- ENTRYPOINT - the application to be run
Containers
Containers are created from an image and used to execute an application in isolation.
- Create using
docker createand start usingdocker start- or create and start usingdocker rune.g.docker run -p 4000:80 --name exampleApp4000 apress/exampleapp. - Arguments passed in allow containers from the same image to be configured differently
--envor-efor environment vars;--publishor-pto map a port;--networkto join a container to a software defined network;--rmto remove a container when it stops--volumeor-vto define a directory on the host available on the container’s filesystem
Other useful commands include:
docker psto list containersdocker logsto inspect the logsdocker execto execute a command inside the container
Volumes
Volumes allow data files to be stored outside of a container, which means they are not deleted when the container is deleted or updated.
- Volumes are created using
docker volume createand assigned a name e.g.docker volume create --name productdata - The name is applied in the
docker createcommand e.g.docker run --name mysql -v productdata:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=mysecret -e bind-address=0.0.0.0 mysql:8.0.0
Software-Defined Networks
Software-defined networks are used to connect containers together, using networks that are created and managed using Docker.
- Create using
docker network create backend - Join a container to a network using the
--networkparameter of thedocker createcommand or thedocker network connectcommand - Use
lsandrmto list and remove networks
Compose
Docker Compose is used to describe complex applications that require multiple containers, volumes, and software-defined networks, using the YAML format.
- Compose files are processed using the
docker-compose buildcommand e.g.docker-compose -f docker-compose.yml build - Use
docker-compose upto create the containers, networks and volumes specified
Other useful commands include:
docker-compose stopto stop containers created from services in a compose filedocker-compose downto stop and delete containers, networks and volumesdocker-compose scaleto scale the number of containers runningdocker-compose psto list the containers created
Swarm
A Docker swarm is a cluster of servers that run containers. Worker nodes run the containers and manager nodes distribute the containers between nodes.
docker swarm initfrom a manager nodedocker swarm joinfrom a worker node (using details output in previous command)- Compose files can be used to define the services in a swarm
- Use
docker stack deployto deploy such an application e.g.docker stack deploy --compose-file docker-compose-swarm.yml exampleapp(whereexampleappgets used a s prefix to the names)
Chapter 4 Docker Images and Containers
docker logsto see the last set of logs from a container (whether still running or stopped)docker logs -fto see continuous outputdocker cp host-file exampleApp3000:/app/to copy files into a container (use with caution)docker diffto see differences between a container and the image it was created from (A=added; C=changed; D=deleted)docker exec exampleApp3000 [command]to execute a command in a containerdocker exec -it exampleApp3000 /bin/bashto start an interactive shell (Bash is included in aspnetcore images)apt update && apt install vimto install packages
Creating Images from Modified Containers
Either run an existing container, or run a dynamic container from an image using:
docker run -it microsoft/dotnet:2.1-aspnetcore-runtime /bin/bash to create a container, start it and enter an interactive shell
Make any changes and exit. After exiting run docker ps -a to see the container. The name will be randomly generated for the container in this last case. See https://github.com/moby/moby/blob/master/pkg/namesgenerator/names-generator.go
Create a new image from the container using docker commit:
docker commit hungry_torvalds infuerno/dotnet:2.1-aspnetcore-runtime
Publishing Images
docker login -u username -p passworddocker push username/image:versiondocker logout
Chapter 5 Docker Volumes and Networks
-
Volumes - allow important data to exist outside of the container, allow changing or upgrading containers without loosing data
-
Networks - IP docker networks for container communication on a single server (between servers only IF a cluster is used)
-
docker volume create --name testdata- create a new volume -
docker run --name vtest2 -v testdata:/data infuerno/vtest- create a container which maps the volumetestdatato/data