Skip to content

Instantly share code, notes, and snippets.

@jendiamond
Last active May 18, 2019 02:52
Show Gist options
  • Save jendiamond/82717d7922650b77b98c98cd416a3da4 to your computer and use it in GitHub Desktop.
Save jendiamond/82717d7922650b77b98c98cd416a3da4 to your computer and use it in GitHub Desktop.

Docker Images - The Dockerfile

Introduction to the Dockerfile | Working with Instructions | Environment Variables | Build Arguments | Working with Non-privileged User | Order of Execution | Using the Volume Instruction | Entrypoint vs. Command | Using .dockerignore


Introduction to the Dockerfile

Building images using a Dockerfile.

What is the Dockerfile?

Dockerfiles are instructions. They contains all of the commands used to build an image.

  • Docker images consist of read-only layers.
  • Each represents a Dockerfile instruction.
  • Layers are stacked.
  • Each layer is a result of the changes from the previous layer.
  • Images are built using the docker image build command.

Dockerfile Layers

Dockerfile:  
FROM ubuntu:15.04  
COPY . /app  
RUN make /app  
CMD python /app/app.py
  • FROM creates a layer from the ubuntu:15.04 Docker image.
  • COPY adds files from your Docker client’s current directory.
  • RUN builds your application with make.
  • CMD specifies what command to run within the container.

Best Practices

General guidelines:

  • Keep containers as ephemeral as possible.
  • Follow Principle 6 of the 12 Factor App.
  • Avoid including unnecessary files.
  • Use .dockerignore.
  • Use multi-stage builds.
  • Don’t install unnecessary packages.
  • Decouple applications.
  • Minimize the number of layers.
  • Sort multi-line arguments.
  • Leverage build cache.

Working with Instructions

FROM: Initializes a new build stage and sets the Base Image

RUN: Will execute any commands in a new layer

CMD: Provides a default for an executing container. There can only be one CMD instruction in a Dockerfile

LABEL: Adds metadata to an image

EXPOSE: Informs Docker that the container listens on the specified network ports at runtime

ENV: Sets the environment variable to the value

ADD: Copies new files, directories or remote file URLs from and adds them to the filesystem of the image at the path .

COPY: Copies new files or directories from and adds them to the filesystem of the container at the path .

ENTRYPOINT: Allows for configuring a container that will run as an executable

VOLUME: Creates a mount point with the specified name and marks it as holding externally mounted volumes from native host or other containers

USER: Sets the user name (or UID) and optionally the user group (or GID) to use when running the image and for any RUN, CMD, and ENTRYPOINT instructions that follow it in the Dockerfile

WORKDIR: Sets the working directory for any RUN, CMD, ENTRYPOINT, COPY, and ADD instructions that follow it in the Dockerfile

ARG: Defines a variable that users can pass at build-time to the builder with the docker build command, using the --build-arg = flag

ONBUILD: Adds a trigger instruction to the image that will be executed at a later time, when the image is used as the base for another build

HEALTHCHECK: Tells Docker how to test a container to check that it is still working

SHELL: Allows the default shell used for the shell form of commands to be overridden

To set up the environment:

sudo yum install git -y
mkdir docker_images
cd docker_images
mkdir weather-app
cd weather-app
git clone https://github.com/linuxacademy/content-weather-app.git src

Create the Dockerfile:

vi Dockerfile

Dockerfile contents:

# Create an image for the weather-app
FROM node
LABEL org.label-schema.version=v1.1
RUN mkdir -p /var/node
ADD src/ /var/node/
WORKDIR /var/node
RUN npm install
EXPOSE 3000
CMD ./bin/www

Build the weather-app image:

docker image build -t linuxacademy/weather-app:v1 .

List the images:

docker image ls

Create the weather-app container:

docker container run -d --name weather-app1 -p 8081:3000 linuxacademy/weather-app:v1

List all running containers:

docker container ls

Environment Variables


Build Arguments


Working with Non-privileged User


Order of Execution


Using the Volume Instruction


Entrypoint vs. Command


Using .dockerignore





Commands to run from your host machine

Run these commands from the ursus directory of your host system – not inside the container $ ursus\🦖


docker-compose down

  • Stop the containers if they're running

docker-compose up

  • Start the containers if they're not running

docker-compose run web bash

  • Connect to a web container to run ruby commands:

Note that this does not connect to the container that is running your web server.
Instead, it creates a new container based on the same image.
This is the docker philosophy of keeping things isolated – contained, if you will.


docker-compose run web [command]

  • Run a single command in a container

    e.g. docker-compose run web rake db:setup


docker-compose down --volumes (or just docker-compose down -v)

  • Wipe out everything and start over

The --volumes bit tells docker to destroy all your data volumes. This includes your Fedora, Solr, and mysql data, so make sure you only do this if that's what you want!


docker-compose logs [container]

  • See the output from a single container
    • e.g. docker-compose logs web

Create a container and attach to it:

docker container run –it busybox

Create a container and run it in the background:

docker container run –d nginx

Create a container that you name and run it in the background:

docker container run –d –name myContainer busybox


Exposing and Publishing Container Ports

Building on what we've already learned, this lesson will focus on exposing ports on a container, as well as how to publish them.

Exposing:

Expose a port or a range of ports

This does not publish the port
Use --expose [PORT]
docker container run --expose 1234 [IMAGE]

Publishing:

Maps a container's port to a host`s port

-p or --publish publishes a container's port(s) to the host
-P, or --publish-all publishes all exposed ports to random ports
docker container run -p [HOST_PORT]:[CONTAINER_PORT] [IMAGE]
docker container run -p [HOST_PORT]:[CONTAINER_PORT]/tcp -p [HOST_PORT]:[CONTAINER_PORT]/udp [IMAGE]
docker container run -P

Lists all port mappings or a specific mapping for a container:

docker container port [Container_NAME]


Executing Container Commands

In this lesson we'll see three different ways to execute commands on containers.

Executing a command:

  • Dockerfile
  • During a Docker run
  • Using the exec command

Commands can be:

  • One and done Commands
  • Long running Commands

Start a container with a command:

docker container run [IMAGE] [CMD]

Execute a command on a container:

docker container exec -it [NAME] [CMD]

Example:

docker container run -d -p 8080:80 nginx
docker container ps
docker container exec -it [NAME] /bin/bash
docker container exec -it [NAME] ls /usr/share/nginx/html/

Container Logging

In this lesson, you will learn how to view the logs of a container to get vital output of your application. You will also learn about some of the logging best practices of containerized applications.

Create a container using the weather-app image.

docker container run --name weather-app -d -p 80:3000 linuxacademycontent/weather-app

Show information logged by a running container:

docker container logs [NAME]

Show information logged by all containers participating in a service:

docker service logs [SERVICE]

Logs need to be output to STDOUT and STDERR.

Nginx Example:

RUN ln -sf /dev/stdout /var/log/nginx/access.log \
    && ln -sf /dev/stderr /var/log/nginx/error.log

Debug a failed container deploy:

docker container run -d --name ghost_blog \
-e database__client=mysql \
-e database__connection__host=mysql \
-e database__connection__user=root \
-e database__connection__password=P4sSw0rd0! \
-e database__connection__database=ghost \
-p 8080:2368 \
ghost:1-alpine


docker-compose restart web

  • Restart the rails server

Editing files

  1. This tutorial assumes that you run the examples within your container from the ./hyrax_demo directory
  2. The entire /hyrax_demo directory in your container is mounted from the same directory on your host machine (laptop), so you can use your favorite editor or IDE to edit files easily at path-you-started-from-on-your-host-system/hyrax_demo
  3. Inside the guest machine, you can also use common Linux editors like vim and nano to edit files.

Commands to run inside a container

Unless otherwise noted, these should be run inside your web container – e.g., in a shell you opened with docker-compose run web bash.


rails console or rails c

  • Start a Rails console

Run your Rails commands from inside the root

rails db:migrate

  • Enter the console
  • Run any outstanding / new database migrations

    1. Type
  • Reset your development repository to a completely empty state

    rails db:drop
    rails db:migrate
    rails console
    # inside the rails console from the irb> prompt
    require 'active_fedora/cleaner'
    ActiveFedora::Cleaner.clean!
    exit
    # back at your bash # prompt 
    rails hyrax:default_admin_set:create

Get a list of all of the Docker commands: docker -h

Management command were introduced in Docker engine v1.13

Management Commands:

builder Manage builds
config Manage Docker configs
container Manage containers
engine Manage the docker engine
image Manage images
network Manage networks
node Manage Swarm nodes
plugin Manage plugins
secret Manage Docker secrets
service Manage services
stack Manage Docker stacks
swarm Manage Swarm
system Manage Docker
trust Manage trust on Docker images
volume Manage volumes

docker image and:

build Build an image from a dockerfile
history Show the history of an image
import Import the contents from a tarball to create a filesystem image
inspect Display detailed information on one or more images
load Load an image from a tar file or STDIN
ls List images
prune Remove unused images
pull Pull an image or a repository from a registry
push Push an image or a repository to a registry
rm Remove one or more images
save Save one or more images to a tar file (streamed to STDOUT by default)
tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE

docker container and:

attach Attach local standard input, output, and error streams to a running container
commit Create a new image from a container's changes
cp Copy files/folders between a container and the local filesystem
create Create a new container
diff Inspect changes to files or directories on a container's filesystem
exec Run a command in a running container
export Export a container's filesystem as a tar archive
inspect Display detailed information on one or more containers
kill Kill one or more running containers
logs Fetch the logs of a container
ls List containers
pause Pause all processes within one or more containers
port List port mappings or a specific mapping for the container
prune Remove all stopped containers
rename Rename a container
restart Restart one or more containers
rm Remove one or more containers
run Run a command in a new container
start Start one or more stopped containers
stats Display a live stream of container(s) resource usage statistics
stop Stop one or more running containers
top Display the running processes of a container
unpause Unpause all processes within one or more containers
update Update configuration of one or more containers
wait Block until one or more containers stop, then print their exit codes

docker container run:

--help Print usage
--rm Automatically remove the container when it exits
-d, --detach Run container in background and print container ID
-i, --interactive Keep STDIN open even if not attached
--name string Assign a name to the container
-p, --publish list Publish a container's port(s) to the host
-t, --tty Allocate a pseudo-TTY
-v, --volume list Mount a volume (the bind type of mount)
--mount mount Attach a filesystem mount to the container
--network string Connect a container to a network (default "default")


Volume Commands

Volumes are the preferred method of maintaining persistent data in Docker. In this lesson, we will begin learning how to use the volume subcommand to list, create, and remove volumes.

Volume Basics

List all Docker volume commands:

docker volume -h
create: Create a volume.
inspect: Display detailed information on one or more volumes.
ls: List volumes.
prune: Remove all unused local volumes.
rm: Remove one or more volumes.

List all volumes on a host:

docker volume ls

Create two new volumes:

docker volume create test-volume1
docker volume create test-volume2

Get the flags available when creating a volume:

docker volume create -h

Inspecting a volume:

docker volume inspect test-volume1

Deleting a volume:

docker volume rm test-volume

Removing all unused volumes:

docker volume prune

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment