Skip to content

镜像

查看所有的镜像

sh
docker images ls

导入镜像

sh
docker load -i image-name.tar

重命名镜像

sh
docker tag 原镜像名:标签 新镜像名:新标签

进入运行中的容器

sh
docker exec -it [containerName] bash

将容器存为镜像

sh
docker commit [containerId] [imageName]

导出镜像

sh
docker save -o image-name.tar [imageName]

导出多个镜像到同一个文件

sh
docker save -o image-name.tar [imageName1] [imageName2]...

容器和主机之间拷贝文件

sh
docker cp <container_id>:/xxx /xxx

删除镜像

sh
docker image rm [imageName]

容器

sh
docker container ls #列出本机运行的容器
docker container ls --all # 列出本机所有容器,包括终止运行的容器
docker container run hello-world  #运行完就停止
docker container run -it ubuntu bash #服务类型(需手动停止)
docker container kill [containID] #手动停止容器
docker container rm [containerID] # 删除容器,终止运行的容器文件,依然会占据硬盘空间。

列出所有容器的 ID

shell
docker ps -a -q #-a 表示列出所有容器(包括停止的),-q 表示只显示容器的 ID。

停止所有容器

shell
docker stop $(docker ps -a -q)

删除所有容器

shell
docker rm $(docker ps -a -q)

删除所有镜像

shell
docker rmi $(docker images -q)

运行命令详解

sh
docker container run
ocker container run -p 8000:3000 -it koa-demo /bin/bash
docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash
docker run -it --name evaluate-ubuntu22-ios-runner -p 6206:6206 -p 8001:8001 59fe2efae52c /bin/bash
#-p参数:容器的 3000 端口映射到本机的 8000 端口。
#-it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。
#--rm参数:容器终止运行后自动删除容器文件。
#koa-demo:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。
#/bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。
# --network host|bridge|none 默认是bridge,即桥接网络,以桥接模式连接到宿主机;host是宿主网络,即与宿主机共用网络;none则表示无网络,容器将无法联网。当容器使用host网络时,容器与宿主共用网络,这样就能在容器中访问宿主机网络,那么容器的localhost就是宿主机的localhost。

启动 ngnix

sh
docker container run --name testnginx --volume "$PWD/html":/usr/share/nginx/html --volume "$PWD/ngnix-config/nginx":/etc/nginx -p 8887:80 -d nginx

# "$PWD/html":/usr/share/nginx/html 把当前工作路径子目录html,映射到容器的网页文件目录/usr/share/nginx/html

docker container cp mynginx:/etc/nginx .
# 把mynginx容器的/etc/nginx拷贝到当前目录。不要漏掉最后那个点。

如何解决 docker 内部访问不了宿主机

在防火墙开启的状态下,docker 容器内部无法访问宿主机服务(能够访问非宿主机的其他局域网计算机的服务),解决方法:

_补充:由于容器内请求的源地址是使用的 docker0 网段的内网地址,宿主机防火墙无法识别来源为非宿主机网段的 docker0 网段的内网地址请求,将其标记为未知来源,于是对请求进行了拦截,可通过添加防火墙来源规则(docker 容器默认内网网段为 172.17.0.0/16):

ip addr show # 查看docker0的转发网络地址和端口
sudo ufw allow from 172.17.0.0/16 #允许所有RFC1918网络(局域网/无线局域网的)访问这个主机

Raspberry,内置的防火墙 ufw 设置和启用

启用

sh
sudo ufw enable
sudo ufw default deny
# 作用:开启了防火墙并随系统启动同时关闭所有外部对本机的访问(本机访问外部正常)。

关闭

sh
sudo ufw disable

查看状态

sh
sudo ufw status

开启/禁用相应端口或服务举例

sh
sudo ufw allow 80 #允许外部访问80端口
sudo ufw delete allow 80 #禁止外部访问80
sudo ufw allow from 192.168.1.1 #允许此IP访问所有的本机端口
sudo ufw deny smtp #禁止外部访问smtp服务
sudo ufw delete allow smtp #删除上面建立的某条规则
ufw deny proto tcp from 10.0.0.0/8 to 192.168.0.1 port #要拒绝所有的流量从TCP的10.0.0.0/8 到端口22的地址192.168.0.1

Docker Compose

yml
version: '3.7'

services:
  evaluate:
    container_name: my-image-runner
    image: my-image
    # network_mode: "host"
    extra_hosts:
      - 'host.docker.mysql:192.168.x.xxx'
    environment:
      - BYWL_MYSQL_USER=xxx
      - BYWL_MYSQL_PASSWORD=xxx
    volumes:
      - C:\Users\xxjw\Downloads\projectHome:/code/projectHome
      - C:\Users\xxjw\Downloads\web_dist\dist:/web/dist
    ports:
      - '6206:6206'
      - '8001:8001'
    command: /usr/local/bin/startup.sh
    #stdin_open: true  # 保持标准输入打开
    #tty: true         # 为容器分配一个伪终端
yml
services:
  web:
    image: nginx
    volumes:
      - /home/deploy_home/nginx-conf:/etc/nginx
    ports:
      - '80:80'
    network_mode: 'host'

  backend:
    image: fastapi:v2.5
    volumes:
      - /home/deploy_home/backend:/Backend
    environment:
      - SQL_HOST=192.168.x.xxx
      - SQL_PORT=5237
    ports:
      - '8000:8000'
yml
services:
  web:
    image: nginx-with-perl
    volumes:
      - D:\ProjectDeploy\x73_deploy\nginx-conf:/etc/nginx
    ports:
      - '7208:80'
    environment:
      - BACKEND_PORT=8000
    networks:
      - user_network

  db:
    image: mysqlx73:v1.0
    environment:
      MYSQL_ROOT_PASSWORD: '123456'
      MYSQL_CHARSET: 'utf8mb4'
      MYSQL_COLLATION: 'utf8mb4_unicode_ci'
    ports:
      - '3307:3306'
    networks:
      - user_network

  backend:
    image: backend:x73
    volumes:
      - D:\ProjectDeploy\x73_deploy\x73_backend:/x73_backend
    environment:
      MYSQL_HOST: 'db' # 使用服务名作为主机名
      MYSQL_USERNAME: 'root'
      MYSQL_PASSWORD: '123456'
      MYSQL_DB: 'xxx'
      MYSQL_PORT: '3306'
      DOCKER_BASE_URL: 'tcp://192.168.2.73:2376'
      REGISTRY_HOST: '192.168.2.73:5000'
      GM_HOST: 'http://192.168.2.73:8000'
    ports:
      - '10088:8000'
    networks:
      - user_network

networks:
  user_network:
    driver: bridge

start.sh

sh
#!/bin/bash
service nginx start
service mysql start
service redis-server start
cd /code/server_assess-feat-hand-over
python3 main_async.py &
ASYNC_PID=$!
python3 main.py &
MAIN_PID=$!

cleanup() {
    echo "Stopping Python services..."
    kill $ASYNC_PID $MAIN_PID
    wait $ASYNC_PID $MAIN_PID
    echo "All services stopped."
}

trap cleanup SIGTERM SIGINT

wait $ASYNC_PID $MAIN_PID

启动 docker-compose

shell
docker-compose up
#后台运行
docker-compose up -d

#启动后又容器生成,下次可以通过 docker-compose start 启动,通过stop停止

停止 docker-compose

shell
docker-compose kill

两个容器网络互访

yml
version: '3.8'

services:
  service1:
    image: your_image_1
    networks:
      - mynetwork
    ports:
      - '8080:8080'

  service2:
    image: your_image_2
    networks:
      - mynetwork
    ports:
      - '9090:9090'

networks:
  mynetwork:
    driver: bridge

docker compose service 访问另外一个 service

yml
version: '3'

services:
  service1:
    image: your_image1
    networks:
      - custom_network

  service2:
    image: your_image2
    networks:
      - custom_network

networks:
  custom_network:
    driver: bridge

在这个配置中,service1 可以通过 service2 的名称进行访问,如 http://service2