Docker

Posted on June 2, 2022
Tags: devops

1 Basics

1.1 image

Command Shortcut Defined
docker image ls docker images ls images
docker image rm <image> docker rmi <image> removes image
docker image pull <image> docker pull <image> pull image from docker registry

1.2 container

Command Shortcut Defined
docker container ls -a docker ps -a list all containers (-a includes stopped)
docker container run <image> docker run <image> runs container from an image
docker container rm <containerID or name> docker rm <containerID or name> removes container
docker container stop <containerID or name> docker stop <containerID or name> stop container

Docker containers don’t remove themselves when they terminate, they enter a stopped state.

1.2.1 Run detached container and removing containers

docker container run -d --name bleh nginx
#>d89war8wf0489fwa08498w0atr48q0g8949a439w0

docker container ls -a
 #>CONTAINER ID   IMAGE   COMMAND                  CREATED             STATUS         PORTS     NAMES
 #>d89war8wf048   nginx  "nginx -g 'daemon of…"   35 seconds ago      Up 34 seconds   80/tcp    bleh

#docker container kill d89war 
docker container stop d89war 
docker container rm d89war
#docker container stop "bleh"
#docker container rm "bleh"

<containerID> = d89war8wf048
--name bleh means we can refer to “bleh” instead of “d89war8wf048”

docker container kill d89war is faster than docker container stop d89war

1.2.2 Prune

docker container prune #removes stopped containers
docker image prune

1.2.3 pause/unpause container

docker pause c3d288
docker unpause c3d288

1.2.4 container flags

Command Defined
docker run -d ubuntu detach running container from current terminal
docker run -it ubuntu -i lets you write commands to container, -t run terminal inside container
docker run ubuntu –rm –rm Removes container instead of stopped state on termination
docker run –name Bleh ubuntu we can refer to “Bleh” instead of <containerID or name>
docker logs -f Bleh Outputs the log of “Bleh”

1.2.5 –name for containers , -t for naming images

docker container run -d -it --name looperA ubuntu sh -c 'while true; do date; sleep 1; done'
docker logs -f looperA

1.2.6 logs

docker logs -f looperA

2 Terminal

2.1 attach current terminal to container

docker attach c3d288
#hit Ctrl-C to terminate the container looperA
docker attach --no-stdin c3d288
#will not terminate container if hit Ctrl-C
  • If attach results in a hanging terminal with no output, it means there is no bash terminal running inside the container and you must execute one, by following instructions in next section

2.2 execute terminal inside container

docker exec -it c3d288 bash 
  #>root@d89war8wf048 we are now in as bash inside the container
  exit #this won't stop the container, let's us exit terminal

2.3 Dockerfile docker build => outputs image

# Start from the alpine image
FROM alpine:3.13

# Use /usr/src/app as our workdir. The following instructions will be executed in this location.
WORKDIR /usr/src/app

#Set the environment variable LC_ALL
ENV LC_ALL=C.UTF-8 

# Copy the hello.sh file from this location to /usr/src/app/ creating /usr/src/app/hello.sh.
COPY hello.sh .

# Execute a command with `/bin/sh -c` prefix.
RUN touch additional.txt

# When running docker run the command will be ./hello.sh
CMD ./hello.sh

#CMD ["/somebinary"]
docker build . -t bleh
# REPOSITORY   TAG        IMAGE ID       CREATED          SIZE
# bleh         latest     b396ac3611b3   21 seconds ago   5.61MB

docker build . -t bleh:v2 add the :v2 to give it a v2 TAG.

  • Best practice(cache): Use commands that change less at the top and
    change more at the bottom of the Dockerfile file.

Keywords List: RUN CMD ADD COPY ENTRYPOINT WORKDIR ENV

2.3.1 WORKDIR

  • WORKDIR sets the execution directory of commands:
    • RUN CMD ADD COPY ENTRYPOINT
    • CMD is executed when we call “docker run $some_command”
      • All other commands are ran before during build time

RUN is our internal image build terminal which runs before CMD.
CMD is that single command we run when we start our new image as a container. Therefore only one CMD will run, rest is overidden.

2.3.2 CMD

The 2 blocks below are equal.

docker run blehImage:latest $somecommand
FROM blehImage:latest
CMD $somecommand 

2.3.3 ENTRYPOINT

Entrypoint is the main binary ran when you call
docker run <containerID or name> args

default ENTRYPOINT ["/bin/sh"]

Example

  • Create an image called “youtubeDL”
  • ENTRYPOINT ["/usr/local/bin/youtube-dl"] in Dockerfile
  • docker run youtubeDL http://imgur.com/asf =>
    Executing /usr/local/bin/youtube-dl http://imgur.com/asf inside the container

2.3.4 docker run <containerID> sh -c ‘echo hi’

Summary: Use brackets to supply arguments to binary executables

we use sh -c because it allows us to run shell with $PATH and Environment vars.

We can have our Dockerfile use sh -c by unbracketing the ENTRYPOINT or CMD

  1. Both w/o Bracket
  • ENTRYPOINT /bin/ping -c 3
  • CMD localhost
    • /bin/sh -c ‘/bin/ping -c 3’ /bin/sh -c localhost
  1. Entrypoint w/ Bracket
  • ENTRYPOINT [“/bin/ping”,”-c”,”3”]
  • CMD localhost
    • /bin/ping -c 3 /bin/sh -c localhost
  1. CMD w/ Bracket
  • ENTRYPOINT /bin/ping -c 3
  • CMD [“localhost”]
    • /bin/sh -c ‘/bin/ping -c 3’ localhost
  1. Both w/ Bracket
  • ENTRYPOINT [“/bin/ping”,”-c”,”3”]
  • CMD [“localhost”]
    • /bin/ping -c 3 localhost

2.3.4.1 Examples

CMD ["/code-server","--accept-server-license-terms"]
RUN ["ls","/lib"]

2.3.5 Copy files from local to container

touch bleh.txt
docker cp ./bleh.txt \<containerID or name\>:/usr/src/app/

2.3.6 docker diff - Check what our container did

docker diff \<containerID or name\>
    # C /usr
    # C /usr/src
    # C /usr/src/app
    # A /usr/src/app/bleh.txt
    # C /root
    # A /root/.ash_history

A = Added
C = Changed
D = Deleted


2.3.7 -v Volume for shared access

Allow your local machine and container to access the same resource

docker run -v "$(pwd)/localdir:/remotedir" ubuntu 

-v <localpath>:<remotepath>

2.4 Ports and Network

Expose port: tell container to listen to a certain port(doesn’t do much but helps for documentation) EXPOSE <port> in Dockerfile

Publish port: map local port to container port
-p <local-port>:<remote-container-port>

docker run -p 3000:5000 ubuntu

We go to http://localhost:3000 to access the site.

3 Memory limit

docker run --memory="256m" nginx 
docker run --cpus=".5" nginx

4 Neat trick

In your Dockerfile put this as your CMD to keep your container running so you can investigate it

CMD sh -c 'while true; do date; sleep 1; done'
CMD ["sh","-c", "while true; do date; sleep 1; done"] #alternatively

5 Mistakes

Double check your Dockerfile with vim because even using vscode on a linux-server, there will be some strange inputs

RUN mv /tmp/lib /lib #BAD 
#copied lib folder INTO a lib folder, results in /lib/lib
RUN mv /tmp/lib/* /lib #BAD
#surprisingly doesnt work because docker run `sh -c` which is shell and does NOT have wildcards * 
RUN cp -r /tmp/lib/ /lib #GOOD

Scenario: We want to add our library files

#no permission
RUN chmod 777 /lib #BAD

6 Docker-Compose

File Structure

version: "3.9"
services:
     myFront:
          image: frontend:v1
          ports: 
              - "3200:5000"
          build: ./example-frontend
     myBack:
          image: backend:v1
          ports: 
              - "3300:8080"
          build: ./example-backend
docker-compose build 
docker-compose up

line 6 build “Dockerfile” in current dir “.”
and create image named “ads/wrga:latest” (line 5)

docker-compose environment vs Dockerfile ENV.
ENV is used on build time.
environment is used on runtime or docker run $...