🖋️ Summary Notes #blog
Docker

Docker #infrastructure

What?

What Concepts?

What are Docker CLI? (Docker Commands)

  • Check image/container status

  • Main process

    • docker pull - pull image #image (can skip as run also pull)

      docker pull NAME[:TAG]
      docker pull nginx
      docker pull nginx:1.23
      docker pull node:buster            ## node with tag buster
      docker pull node:8                 ## might be intel based image => but actually arm based
    • Run a Docker CONTAINER

      • Create & Start Container

        1. docker create [OPTIONS] IMAGE [COMMAND] [ARG…]docker create --name nginx -p 8080:80 nginx
        2. docker start [OPTIONS] CONTAINER [CONTAINER…]docker start nginx
      • docker run 🟢 Run & Pull Image ⇒ show log (create new container everything, don't re-use previous container)

        • Port Forwarding

          • --name container name

          • -e set an environment variable in the container

          • -p/--publish map host port => container port (expose the port )

            • -p {LOCAL_HOST_POST}:{CONTAINER_PORT}
              • LOCAL_HOST_POST: check in server.js
          • -d detached mode => run in background

            • runs in the bg & doesn't attach to the terminal)
            • if not have ⇒ quit terminal ⇒ container stops
          • --restart always

            • define restart policy => always (is container stop => restart)
          • e.g.

            • docker run --name nginx -p 8080:80 -d nginx
            docker run nginx                       ## docker run {name}:{tag} creates a container from image and starts it
            docker run --name web-app -d -p 9000:80 nginx:1.23    # expose container to local network localhost:9000
             
            ## this wont work b/c EXPOSE 8080 by default is not accessible to the outside world
            # docker run b909406d737c ## create a running process called a container => terminal will say app listening on localhost 8080
             
            ## Need refactor the command with p flag => implement port forwarding from the docker machine to our local machine
            docker run -p 5000:8080 b909406d737c ## map local machine 5000 => to a port on the docker container 8080
            ## app will run on localhost:5000
             
            docker ps     ## check the container port => list running containers
            docker ps -a  ## list all containers
            docker log {CONTAINER_ID/NAME}
          • other use case

    • Modify existing Docker CONTAINER

      • docker stop 🛑 stop the container
        docker ps
        docker stop ea491e4t0fd7 # docker stop {CONTAINER_ID/NAME} stop one or more running containers
          # stop multiple with [space] in between the {CONTAINER_ID/NAME}
      • docker start 🟢 start the stopped container (running container ⇒ keep running)
        docker ps -a # show all stopped and running container
        docker start {CONTAINER_ID/NAME}
      • docker restart restart a container (running container ⇒ stop & restart)
      • docker rm ➖ remove a non-running container
        • docker rm -f nginx ➖ remove a running container
    • Create a Docker IMAGE

    • docker-compose start containers in docker-compose.yml (docker-compose.yaml) #multiple #dependency (opens in a new tab)

      1. Check no containers running
      2. Start the containers with docker-compose.yml (docker-compose.yaml) #multiple #dependency (opens in a new tab)
        • docker compose up -d for docker v2
          • -d detached mode
          • -f filename
          • e.g.
            • docker compose -f compose.yaml up start all the containers in compose.yaml
            • docker-compose up -d for docker v1 (will be end of life)
      • docker compose stop 🛑 stop the containers
      • docker compose down ❌ remove the container
    • Pushing a Docker Image

      • (optional) tag an image docker tag <SOURCE_IMAGE> <TARGET_IMAGE>docker tag nginx xinyun2016/comp90024:nginx
      • push an image docker push <NAME[:TAG]>docker push xinyun2016/comp90024:nginx
  • 🐞 debugging

    • docker logs - see app log in the container #debugging

      docker ps               # show the container id
      docker logs ea491e4t0fd7 # docker logs {CONTAINER_ID/NAME} view logs from service running inside the container (chich are present at the time of execution)
    • docker exec -ti ⚠️ not recommended, mainly for debug or testing purpose

      docker exec -ti w /usr/share/nginx/html/ nginx sh
      sed -i 's/nginx!/nginx inDocker!/g' index.html    ## replace text
    • docker volume - manage volume

      • ls - list all volumes

      • rm VOLUME_NAME - remove volume

      • Manage data in Docker

        1. Create a volume

          • docker volume create --name htdocs
            • have this volume we can mount it somewhere in our container when we run it
            • multiple containers can mount this volume simultaneously and access the same set of files
            • the file stick around after all containers shut down
        2. Start a Container (Named Volume)

          ## start a container "nginx-volume" with a VOLUME attached
          docker run --name nginx-volume -p 8080:80 -v htdocs:/usr/share/nginx/html -d nginx
          ## NAMED VOLUME
          ## docker run             Create & Start      new container
          ## --name nginx-volume    CONTAINER NAME      "nginx-volume"
          ## -p 8080:80             maps                hostPort 8080 => containerPort 80
          ##                        localhost:8080      running inside the container
          ## -v htdocs:/usr/share/nginx/html
          ##                        DOCKER VOLUME       "htdocs" volume's file accessible by web server inside the container
          ##                        mounts to container "/usr/share/nginx/html" web server's document root
          ## -d nginx               DOCKER IMAGE        "nginx" DOCKER IMAGE
          ##                        -d run container in detached mode (in background) wont output any logs or information to the console
          ## last line is the id of container
        3. Start a Container (Bind Mount)

          ## start a container "nginx-bind" with BIND MOUNT attached
          docker run --name nginx-bind -p 8081:80 -v $(pwd)/htdocs:/usr/share/nginx/html -d nginx
          ## BIND MOUNT
          ## docker run             Create & Start      new container
          ## --name nginx-bind      CONTAINER NAME      "nginx-bind"
          ## -p 8081:80             maps                hostPort 8081 => containerPort 80
          ##                        localhost:8081      running inside the container
          ## -v $(pwd)/htdocs:/usr/share/nginx/html
          ##                        mounts local "htdocs"  => container dir "/usr/share/ngine/html"
          ##                        local dir accessiable by web server inside container
          ## -d nginx               DOCKER IMAGE        "nginx" DOCKER IMAGE
          ##                        -d run container in detached mode (in background) wont output any logs or information to the console
        4. ./list-volume-mount.sh

           
          ./list-volume-mount.sh
          docker exec -ti nginx-volume sh -c "ls -ltr /usr/share/nginx/html"
          docker exec -ti nginx-bind sh -c "ls -ltr /usr/share/nginx/html"
          ## docker exec             run cmd in the running container
          ## -ti nginx-volume        run cmd in interactive mode with a TTY shell => container "nginx-volume"
          ## sh                      starts a new shell session
          ## -c "ls -ltr /usr/share/nginx/html"
          ##                         cmd to run inside the shell session
          ## -ltr                    long format + sorted by modification time + reverse order
           
          ## named volumn => have content of the container (index.html)
          ## bind mount   => directory was empty
          ## named volume => contents can be populated by a container
          ## bind mount   => simply mount it
          cp index.html htdocs/      ## copy to BIND MOUNT
  • docker network

    ## create docker network
    docker network create mongo-network
     
    ## start mongodb
    docker run -d \
    --name mongodb \                          # container name
    -p 27017:27017 \                          # port
    -e MONGO_INITDB_ROOT_USEANAME=admin \     # environment variables
    -e MONGO_INITDB_ROOT_PASSWORD=password \
    -net mongo-network \
    mongo                                     # image
     
    ## start mongo-express
    docker run -d \
    --name mongo-express \
    -p 8080:8080 \
    -e ME_CONFIG_MONGODB_ADMINUSERNAME=admin \
    -e ME_CONFIG_MONGODB_ADMINPASSWORD=password \
    -e ME_CONFIG_MONGODB_SERVER=mongodb \
    -net mongo-network \
    mongo-express

Why?

Why do I use it?

  • Reproducible Environment
  • Quickly launch multiple instances of an application and load balance between them.
  • more than just a virtual env, isolated environment for all dependencies, multiple services, easy deployment, same environment for collaborators, python version, etc…

How?

How to install?

How to Dockerize Existing Repo in GitHub With Dev Container?

  1. Create a Dockerfile (builds image) (opens in a new tab)
  2. Build Docker Image (run containers) #immutable(read-only) #layers #templates (opens in a new tab)
  3. Run Docker Container (running process) #instanceOfImage (opens in a new tab)
    1. Run a Docker CONTAINER (opens in a new tab)
  • With Existing NextJS

    1. existing NexJS project

    2. create Dockerfile

      # use official node runtime as parent image
      FROM node:14
       
      # set working dir to /app
      WORKDIR /app
       
      # copy current directory contents into container at /app
      COPY . /app
       
      # install dependencies
      RUN npm install
       
      # Build the nextjs project
      RUN npm run install
       
      # Expose the port that app will run one
      EXPOSE 3000
       
      # start the app
      CMD ["npm", "start"]
       
    3. build the docker image

      1. docker build -t my-nextjs-app this create a docker image named “my-nextjs-app”
    4. Run the Docker container

      1. docker run -p 3000:3000 my-nextjs-app this start the container and map port 3000 on the host to port 3000 in the container
    5. app now running in the docker container and accessible at http://localhost:3000

How to ignore node_modules?

How to debugging? ⇒ use docker app

How to clear all images, containers, and volumes in Docker?

# remove containers, images, volumes
docker rm -f $(docker ps -aq)
docker rmi -f $(docker images -aq)
docker volume rm $(docker volume ls -q)

How to Check the Architecture of Docker Image?

docker pull node:buster            ## node with tag buster
docker pull node:8                 ## might be intel based image => but actually arm based
ls
cat /etc/os-release
  • docker image inspect node:buster | grep Arch
    • Intel -“Architecture”: “amd64"
      • Docker run will warn
        • WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested
    • Apple Silicon -“Architecture”: “arm64"
  • In docker, desktop ⇒ container will show a AMD 64 tag need to the image name
  • Docker Desktop => Setting => Settings => Resources => Disk Image location /Users/alicezhang/Library/Containers/com.docker.docker/Data/vms/0/data