Docker #infrastructure
What?
- Virtualize the Application Layer (Layer 7) (opens in a new tab)
- create, deploy, run app in isolated containers, containers can be deployed on cloud infrastructure
- Not a Cloud Computing Platform or Service docker is used to facilitate cloud computing (opens in a new tab)
- package software
- 代码和所有依赖项打包到单个容器中来简化构建、部署和扩展应用程序的过程
- Options
- docker in docker
- Docker Desktop Application
- docker outside docker
- docker extension in VSCode Dev Containers (container configuration) (opens in a new tab)
- docker in docker
- Docker Desktop
- uses a Virtual Machine Monitor(VMM)/Hypervisor Layer 虚拟机监控程序 (opens in a new tab) with a lightweight Linux distro
What Concepts?
- CORE
- Dockerfile (builds image) (opens in a new tab) .devcontainer/devcontainer.json (container configuration) (opens in a new tab)
- blueprint/code for building a docker image ⇒ run app as container
- Docker Image (run containers) #immutable(read-only) #layers #templates (opens in a new tab)
- Docker Registries (get images) (opens in a new tab)
- Docker Repository - collection of related Docker Images with same name but different versions
- Docker Hub (opens in a new tab) is a Public Docker Registry, can host private/public repositories for app
- a centralized resource for working with Docker and its components
[registry hostname]/repository[:tag]
(e.g.[docker.io/]nginx:alpine
ornginx[:latest]
)
- login
docker login --username=xinyun2016
docker login [OPTIONS][SERVER]
⇒docker login -u xinyun2016
- or login to a private Docker registry (e.g. AWS ECR, Nexus Server )
docker login -u AWS https://ecr.ap-southeast-2.amazonaws.com
- logout
docker logout [SERVER]
⇒docker logout
- Docker Hub (opens in a new tab) is a Public Docker Registry, can host private/public repositories for app
- Image Tags (Image Versioning )
- a label applied to a Docker Image in a Repository
docker pull node:buster ## node with tag buster docker pull node:8 ## might be intel based image => but actually arm based
- Docker Container (running process) #instanceOfImage (opens in a new tab)
- 1 image ⇒ can run multiple containers
- app inside container runs in Isolated Docker Network
- allows run same app ⇒ on same port multiple times
- need to expose the container port to the host (the machine the container runs on)
- Port Binding - bind the container’s port to the host’s port to make the service available to the outside world
- Dockerfile (builds image) (opens in a new tab) .devcontainer/devcontainer.json (container configuration) (opens in a new tab)
- Docker Compose #multiple #containers #single-host (opens in a new tab)
- docker-compose.yml (docker-compose.yaml) #multiple #dependency (opens in a new tab)
- can use but don't have to have Dockerfile (builds image) (opens in a new tab)
- [
docker-compose
start containers in docker-compose.yml (docker-compose.yaml) #multiple #dependency (opens in a new tab) ](https://www.notion.so/docker-compose-start-containers-in-eef96440c95f474abdb5bf5cb291eb6f (opens in a new tab))
- Docker Volumes (Persist data in Docker) #multipleContainers (opens in a new tab)
- Docker SWARM mode #orchestration #multi-host (opens in a new tab)
- "bridge": containers share the same port, each with a different IP, and expose a host port, making them visible externally. (https://docs.docker.com/network/ (opens in a new tab))
- Dev Containers (container configuration) (opens in a new tab) ⇒ .devcontainer/devcontainer.json (container configuration) (opens in a new tab)
- uses one of
What are Docker CLI? (Docker Commands)
-
Check image/container status
docker images
list all Docker Image (run containers) #immutable(read-only) #layers #templates (opens in a new tab) #imagedocker images [OPTIONS] [REPOSITORY[:TAG]]
⇒ list all imagesdocker image ls
ordocker images
docker ps
list running containers (opens in a new tab) #container (container port, container id)- every container has a unique id ⇒ also linked to an image
docker ps # lists all containers (running) docker ps -a # lists all containers (stoped and running) # -a or --all lists all containers (stoped and running) sudo docker ps -a
-
Main process
-
docker pull
- pull image #image (can skip asrun
alsopull
)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
docker create [OPTIONS] IMAGE [COMMAND] [ARG…]
⇒docker create --name nginx -p 8080:80 nginx
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 inserver.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 containerdocker 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 containerdocker rm -f nginx
➖ remove a running container
-
Create a Docker IMAGE
docker build
🟢 build docker image with Dockerfile (builds image) (opens in a new tab) (run Docker) Dev Containers (container configuration) (opens in a new tab)- ready repo ⇒ deploy to server ⇒ we want to deploy our app as a Docker Container
- image ⇒ run ⇒ container
- Syntax
docker build [OPTIONS] PATH
-t
/--tag
setsname:tag
oruserName/imageName:versionNumber
.
path to the Dockerfile (builds image) (opens in a new tab) (in this case.
)
- Build New Image => with
./Dockerfile
=> with name "demo2"docker build -t angular-app:1.0 .
docker build -t fireship/demoapp:1.0 .
## name and path to the docker file (in this case .)docker build -t demo2.
- Create a container from the image
docker run -d -p 3000:3000 node-app:1.0
- Create container on
localhost:3000
(opens in a new tab) indetached
mode withnode-app:1.0
image
- Create container on
docker run --name demo2 -e WELCOME_STRING="COMP90024" -p 8081:80 -d demo2
- Create container “
demo2
” onlocalhost:8081
(opens in a new tab) indetached
mode withdemo2
image with environment variableWELCOME_STRING=”COMP90024”
- Create container “
-
docker-compose
start containers in docker-compose.yml (docker-compose.yaml) #multiple #dependency (opens in a new tab)- Check no containers running
- [
docker ps
list running containers (opens in a new tab) #container (container port, container id)](https://www.notion.so/docker-ps-list-running-containers-container-container-port-container-id-636418c411d6498084194b7a254e715f (opens in a new tab))
- [
- 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 containersdocker compose down
❌ remove the container
- Check no containers running
-
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
- (optional) tag an image
-
-
🐞 debugging
-
docker log
s - see app log in the container #debuggingdocker 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 purposedocker 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
-
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
-
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
-
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
-
./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?
- Create a Dockerfile (builds image) (opens in a new tab)
- Build Docker Image (run containers) #immutable(read-only) #layers #templates (opens in a new tab)
- [
docker build
🟢 build docker image with Dockerfile (builds image) (opens in a new tab) (run Docker) Dev Containers (container configuration) (opens in a new tab) ](https://www.notion.so/docker-build-build-docker-image-with-run-Docker-f73b4d0d074349d3bd639ab6962473af (opens in a new tab))
- [
- Run Docker Container (running process) #instanceOfImage (opens in a new tab)
-
With Existing NextJS
-
existing NexJS project
-
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"]
-
build the docker image
docker build -t my-nextjs-app
this create a docker image named “my-nextjs-app”
-
Run the Docker container
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
-
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
- Docker run will warn
- Apple Silicon -
“Architecture”: “arm64"
- Intel -
- 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