Writing a Docker file

Docker files build ontop of other docker files.

E.g you might have a 'Dockerfile' in which the first line reads FROM python:2.7-slim.

It's important to understand that "python:2.7-slim" simply refers to another Dockerfile, usually on docker hub. Go there and you will find the link to the python 2.7-slim Dockerfile on github. When you build a container with a FROM keyword, it will run that docker file first, then add the 'layers' which you define after.

What the above means is, first docker will read and build the Dockerfile pointed to in the FROM python:2.7-slim`.

Built in words Dockerfiles understand:

  • ADD
  • Copy
  • ENV
  • EXPOSE
  • FROM
  • LABEL
  • STOPSIGNAL
  • USE
  • VOLUME
  • WORKDIR
  • ONBUILD

Workdir

Example:

WORKDIR /app

Sets the directory of the command before its ran. Can be absolute or relative path.
Heads up: This sets the directory of the new container and not your localhost.

Where does the '/app' directory come from!?
The WORKDIR docs state

If the WORKDIR doesn’t exist, it will be created even if it’s not used in any subsequent Dockerfile instruction. src

ADD

ADD . /app

Copies the currenty directory contents (on your localhost directory) into the folder specified in the container (/app).

EXPOSE

Example:

EXPOSE 80

Means at the container level expose port 80. Note this doesn't mean you're stuck on port 80. This can be overridden when running the container, by telling docker at run time which port mappings you want to choose. e.g. "I'd like my containers port 80 to be mapped to port 4000 in the real world please". Read 'Building a Docker container' then docker run -p 4000:80 friendlyhello makes sense.

Building a Docker container

Example:

sudo docker build -t friendlyhello .

Heads up: Note the . which tells docker where to find the Dockerfile it's being asked to build (. == current directory).

-t is important because this tags the container with an easy name. Without this, docker quickly gets confusing with many containers running with random hashes (85cd744d745a) for their name otherwise.

View your dockers images
docker images

List running containers

$ sudo docker container ls

CONTAINER ID        IMAGE                COMMAND             CREATED             
STATUS              PORTS                  NAMES
c67e4af5e03b        friendlyhello        "python app.py"     58 seconds ago      
Up 57 seconds       0.0.0.0:4000->80/tcp   sleepy_agnesi
1ee3bcc5a419        laradock_workspace   "/sbin/my_init"     2 weeks ago         
Up 12 hours         0.0.0.0:2222->22/tcp   laradock_workspace_1

Heads up: Note the "4000->80/tcp" this means your host os (docker service) is taking requests on port 4000, and mapping these to port 80 on the 'friendlyhello' container.

What is docker compose?

Docker compose allows you to group containers, and scale them. There's some crossover here with docker swarm.

It comes after defining your Dockerfile(s) (as above) and then writing writing a docker-compose.yml file to group multiple Dockerfiles together in some way. E.g. a database, some caching service (like Redis) and a node app middle ware (whatever your stack needs).