一、安装 Docker

        翻阅 Docker 官网文档说明:

        以 Ubuntu 为例:

        查看依赖:

# 查看 cpu 架构
uname -a

# 查看操作系统版本
cat /etc/*release*

1、卸载旧的 docker(没安装过的忽略)

for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done

        卸载 Docker 时,存储在 /var/lib/docker/ 中的镜像、容器、卷和网络不会不会被自动删除。如果希望全新安装并清理所有现有数据,执行以下步骤。

        卸载 Docker Engine、CLI、containerd 和 Docker Compose 软件包:

sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras

        删除所有镜像、容器和卷:

sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

        删除源列表和密钥:

sudo rm /etc/apt/sources.list.d/docker.list
sudo rm /etc/apt/keyrings/docker.asc

2、配置 docker 下载源

        添加 Docker 官方 GPG 密钥:

sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

        配置 Docker 的下载仓库:

echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

3、安装 Docker 包

        安装最新版:

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

# 安装 docker-compose 包,可能一键部署项目的时候用得到
# 指定路径【推荐】
sudo curl -L https://gitee.com/fustack/docker-compose/releases/download/v2.24.1/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
# 设置权限
sudo chmod +x /usr/local/bin/docker-compose

# 删除
sudo rm /usr/local/bin/docker-compose

# 查看docker-compose版本
docker-compose -v

4、启动 docker

// 启动 docker
sudo systemctl start docker

// 停止 docker
sudo systemctl stop docker

// 重启 docker
sudo systemctl restart docker

// 设置开启时自动启动
sudo systemctl enable docker

// 查看 docker 服务状态
sudo systemctl status docker

// 查看 docker 版本
docker -v

        查看一下版本、配置开机自动启动、启动,然后查看一下 docker 状态。

5、配置镜像加速

        镜像下载默认是从国外仓库 Docker Hub 下载的速度比较慢,我们需要配置镜像加速(在本地 Docker Hub 仓库服务器之间设立国内的缓存节点服务器)。

        查找可用镜像源:https://github.com/dongyubin/DockerHub

sudo mkdir -p /etc/docker # 创建文件夹
sudo tee /etc/docker/daemon.json <<EOF # 创建文件
{ # 镜像加速仓库配置
  "registry-mirrors": [
    "https://docker.1panel.live",
    "https://docker.1ms.run",
    "https://dytt.online",
    "https://docker-0.unsee.tech",
    "https://lispy.org",
    "https://docker.xiaogenban1993.com",
    "https://666860.xyz",
    "https://hub.rat.dev",
    "https://docker.m.daocloud.io",
    "https://demo.52013120.xyz",
    "https://proxy.vvvv.ee",
    "https://registry.cyou"
  ]
}
EOF
sudo systemctl daemon-reload # 加载配置
sudo systemctl restart docker # 重启 docker

二、案例1:部署 mysql

1、创建并运行容器

        可以去 Docker Hub 官网搜索:

docker run -d \ # 创建并后台运行一个容器
--name mysql \ # 容器名
-p 3307:3306 \ # 在服务器上端口号: 在容器上的端口号
-e MYSQL_ROOT_PASSWORD=123456 \ # 配置 root 用户密码
-e TZ=Asia/Shanghai \ # 校准时区
mysql:tag # 从仓库下载的镜像名,tag 镜像是版本号,如果不写就默认下载学新的版本

docker run -d \
--name mysql \
-p 3307:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e TZ=Asia/Shanghai \
mysql

        为什么要配置云服务器和容器端口的映射:我们从外面访问云服务器上容器里的 mysql,是无法直接访问容器的 IP(像是内网),只能先访问云服务器,然后云服务器在与其本地运行的容器进行连接,外部就能够与容器间接通信了。这也让容器之间互不影响,完全隔离于服务器。

        过程:守护进程监听到 run 命令,检查本地有没有对应镜像,没有就从镜像仓库下载到本地仓库。之后创建新的容器都可以从本地获取。

2、概念总结

        docker 是啥:下载镜像、创建并运行容器,实现快速部署。

        镜像是啥:把依赖、配置、系统函数库一起打包。相当于qq安装好后的文件,直接把文件打包,因为包含有系统函数库,所以镜像是可以跨平台的。

        容器是啥:为每个镜像进程的环境用容器隔离起来。

三、常用命令

        主要是参考 Docker docs 文档:docker | Docker Docs

        不知道详细参数怎么使用的,可以用 --help 看说明,如 docker run --help:

        一张图学懂最常用的 docker 命令:

// 查看正在运行的容器
docker ps

// 查看所有容器(包括已停止的)
docker ps -a

// 还可以格式化容器详情
docker ps --format 'table {{.ID}}\t{{.Names}}\t{{.Ports}}\t{{.Status}}'

// 停止容器
docker stop 容器名/容器ID

// 启动已停止的容器
docker start 容器名/容器ID

// 删除已停止的容器
docker rm [-f 强制删除运行中的容器] 容器名/容器ID

// 查看镜像
docker image

// 删除本地镜像
docker rmi <镜像ID或镜像名:标签>

// 进入运行的容器,然后正常使用
docker exec -it <容器名或容器ID> bash

// 退出容器
exit

四、数据挂载

1、案例2:利用 Nginx 容器部署静态资源

        我们需要修改 nginx 中的 index.html 文件,因此需要进入 docker 容器,但是发现像 vi、ls 等操作系统命令根本无法使用,这是因为镜像只包含了使用 nginx 必备系统函数等,vi、ls 并不是 nginx 必备的,所以我们不能在 docker 容器中直接修改。

        数据卷登场,本地路径映射到虚拟数据卷,数据卷再映射到容器路径,其中一个路径文件发生改变,另一个路径文件内容也会改变。

2、数据卷常见命令

        数据卷常见命令,不用记,直接 docker volume --help 查询:

# 创建数据卷
docker volume create

# 查看所有数据卷
docker volume ls

# 删除指定数据卷
docker volume rm

# 查看某个数据卷的详情
docker volume inspect

# 清除数据卷
docker volume prune

        实际上,在 docker run 时,会自动为容器创建一个数据卷(名字是很长的随机字符串,建议指定);我们可以指定数据卷名:-v 数据卷名:容器内目录

        docker volume inspect 可以查看到数据卷映射到本地的路径,当容器删了这个数据卷路径还会保留,便于持久化:

        docker inspect 可以查看本地路径和容器路径:

3、本地修改容器中的文件

        先重新创建、运行一个 nginx 容器,记得指定数据卷:

# :ro 设置容器内只读,防止容器内进程意外修改网页文件
docker run --name nginx \
-v nginx:/usr/share/nginx/html:ro \
-p 80:80 \
-d nginx

        本地进入这里面修改:

4、案例3:mysql 容器的数据挂载

        基于宿主机目录实现MySQL数据目录、配置文件、初始化脚本的挂载。需要查看 Docker Hub 官方文档:mysql - Official Image | Docker Hub

        这个时候映射的文件太多,我们指定数据卷,需要到它生成的目录下把配置文件、sql 脚本放进去,不方便,我们更希望放到我们自己指定的路径:- v 本地目录:容器目录

docker run -d \
--name mysql \
-p 3307:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e TZ=Asia/Shanghai \
-v /root/mysql/data:/var/lib/mysql \
-v /root/mysql/init:/docker-entrypoint-initdb.d \
-v /root/mysql/conf:/etc/mysql/conf.d \
mysql

        在执行命令之前,先把配置文件放到 conf、把 sql 脚本放到 init 文件,这样就能做到数据迁移(为了更新 mysql 版本)。

五、自定义镜像 Dockerfile

1、概念

        我们把自己的应用程序打包成镜像,就需要用 dockerfile 脚本。部署一个程序的过程:准备一个 Linux 环境、安装 jre、redis、mq 等并配置环境变量、复制应用程序的 jar 包,编写脚本运行 jar 包。这每个环节都分为一层打包成单独的文件,便于复用(因为很多应用程序都可以复用一套 Linux 环境和 jre 等)。

        dockerfile 就是指令的集合,参考官方文档:Dockerfile reference | Docker Docs

但是我们只需要了解常见的,因为基础的镜像别人也做好了,我们直接使用就行,不用那么复杂。

  • FROM:指定基础镜像
  • ENV:设置环境变量,可在后面指令使用
  • COPY:拷贝本地文件到镜像的指定目录
  • RUN:执行Linux的shell命令,一般是安装过程的命令
  • EXPOSE:指定容器运行时监听的端口,是给镜像使用者看的
  • ENTRYPOINT:镜像中应用的启动命令,容器运行时调用

        示例:

# 指定基础镜像(操作系统环境)
FROM ubuntu:16.04
# 配置环境变量,JDK的安装目录、容器内时区
ENV JAVA_DIR=/usr/local
# 拷贝本地 jdk 和 java 项目的包到 容器内的路径
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /app/app.jar
# 安装JDK 把容器内路径下的 jdk 解压到另一个路径
RUN cd $JAVA_DIR \ && tar -xf ./jdk8.tar.gz \ && mv ./jdk1.8.0_144 ./java8
# 配置环境变量
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 入口,java项目的启动命令
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

        因为 jdk 又有打包好的镜像,所有可以缩减为:

# 基础镜像
FROM openjdk:11.0-jre-buster
# 拷贝jar包
COPY docker-demo.jar /app/app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app/app.jar"]

  2、案例4:将 demo 程序打包成镜像

        Dockerfile:

# 基础镜像
FROM openjdk:11.0-jre-buster

# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

# 拷贝jar包
COPY docker-demo.jar /app.jar 

# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

        准备 jar、dockerfile 到服务器上:

        构建镜像:

# -t 给镜像起名(需要小写) 镜像名:tag
# . 表示执行当前目录下的 Dockerfile(如果不是这个名字,要指定文件名)
docker build -t my-image:1.0 .

        创建并运行容器:

六、网络

        看一下 mysql、nginx 两个容器在容器内的 IP:

        看一下服务器上的网卡,有一个 docker0 的虚拟网卡,它是连接各个容器的网桥,各个容器有同一个网关地址:172.17.0.1/16,只要是以 172.17 开头的 ip 都在一个局域网内。

        因此,nginx 和 mysql 两个容器是能够互相通信的。但是局域网内的 ip 是随机分配的,某个容器不会固定 ip,每次重启都有可能变。因此我们需要自定义网络(以容器名加入网络,容器名可以固定不变):docker network | Docker Docs

  • docker network create:创建一个网络
  • docker network ls:查看所有网络
  • docker network rm:删除指定网络
  • docker network prune:清除未使用的网络
  • docker network connect:使指定容器连接加入某网络
  • docker network disconnect:使指定容器连接离开某网络
  • docker network inspect:查看网络详细信息

        我们创建一个自定义网络,并让 mysql、nginx 容器连上它:

# 创建网络
docker network create my-network

# 让 mysql 加入网络(先创建容器,再加入自定义网络,会先加入 docker0 默认网卡)
docker network connect my-network mysql

# 也可以在创建时就加入自定义网络(创建容器时就加入,不会加入 docker0 默认网卡)
docker run --network my-network

        

七、项目部署

1、部署 Java 应用

        Dockerfile:

# 基础镜像
FROM openjdk:11.0-jre-buster
# 设定时区
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷贝jar包
COPY hm-service.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]

        放到Linux服务器里打包成镜像:

        创建并运行应用程序的容器,并加入自定义网络:

2、部署前端

        nginx 需要对前端目录进行代理,那么需要编写配置文件。静态资源在nginx容器内的地址:

        所以配置文件需要指明路径:


worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/json;

    sendfile        on;
    
    keepalive_timeout  65;

    server {
		# 用户静态资源,通过 18080 端口访问
        listen       18080;
		# 所有以 / 开头的请求都回到这个目录下获取静态资源
        location / {
            root /usr/share/nginx/html/hmall-portal;
        }

		# 错误状态码,会自动返回默认 html 路径下的 /50x.html 页面
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
		# 前端页面发来的,所有以 /api 开头的请求,都会被重写(去掉/api),然后访问 hall-app 容器的 8080 端口
        location /api {
            rewrite /api/(.*)  /$1 break;
            proxy_pass http://hall-app:8080;
        }
    }
    server {
        listen       18081;
        # 指定前端项目所在的位置
        location / {
            root /usr/share/nginx/html/hmall-admin;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        location /api {
            rewrite /api/(.*)  /$1 break;
            proxy_pass http://hall-app:8080;
        }
    }
}

        然后重新创建 nginx 容器,需要挂在 config、html 的路径:

         把文件放到 nginx 容器映射到的本地目录:

        创建并运行容器:

docker run -d \
--name nginx \
-p 18080:18080 \
-p 18081:18081 \
-v /root/nginx/html:/usr/share/nginx/html \
-v /root/nginx/nginx.conf:/etc/nginx/nginx.conf \
--network my-network \ # 需要跟后端 jar 包在同一个网络
nginx

        访问网页:部署成功,4000 端口对应的 18080,我这里是设置了 xshell 的隧道,就不用打开防火墙,仅 xshell 远程连接的本地能访问。

3、DockerCompose

        我们发现,部署一个项目需要挨个创建并运行多个容器,包括前端、后端、mysql、各种中间件....,这个流程非常繁琐,并且容易出错(比如忘记把容器连接到同一个网络,忘记配置映射等)。如果每一次都手动执行这个流程,耗费精力还容易出错。所以我们需要 DockerCompose,只需要写一次 yml 文件,然后按照 DockerCompose 的配置放置 Dockerfile 等文件到服务器指定目录,后续就能一键部署和删除,非常方便。

        DockerCompose 的编写只不过把 docker 的命令,比如 docker run、docker build 改成它的语法即可。

        把上面的分别部署,改为 docker-compose.yml:

version: "3.8" # Docker Compose 的语法版本

services: # 服务定义
  mysql:
    image: mysql # 镜像名
    container_name: mysql # 容器名
    ports:
      - "3306:3306" # 端口映射
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_PASSWORD: 123
    volumes:
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
      - "./mysql/init:/docker-entrypoint-initdb.d"
    networks:
      - hm-net
  hmall: # 如果不指定镜像名称,默认 项目名称_hmall(compose 命令参数里的 -p,默认 root)
    build: 
      context: . # 当前目录下
      dockerfile: Dockerfile # 的 Dockerfile 文件
    container_name: hmall
    ports:
      - "8080:8080"
    networks:
      - hm-net
    depends_on: # hmall 需要连接 mysql,会先创建 mysql 容器,再创建该容器
      - mysql
  nginx:
    image: nginx
    container_name: nginx
    ports:
      - "18080:18080"
      - "18081:18081"
    volumes:
      - "./nginx/nginx.conf:/etc/nginx/nginx.conf"
      - "./nginx/html:/usr/share/nginx/html"
    depends_on:
      - hmall # 前端静态资源的代理 nginx 需要访问后端
    networks:
      - hm-net
networks: # 网络配置
  hm-net:
    name: hmall # 定义一个名为 hm-net 的自定义网络,显示名称为 hmall

        docker compose 的命令:

八、综合练习-部署自己的项目

        把我的 “公司年会抽奖系统” 是用 DockerCompose 一键部署。该系统需要:

  • 后端应用(前端静态资源包含在里面,没有进行前后端分离)容器:需要自己制作镜像,编写 Dockerfile;项目发布版配置里面要把 mysql、redis、rabbitmq 的连接 ip 改成容器名;还有注意 docker run 的时候需要映射容器内的 logs(程序生成的日志)、pic(用户上传的奖品图片)文件路径。
  • mysql 容器:注意 mysql 用户要新创建一个,它的权限只能操作该系统的数据库、密码要与后端代码配置文件里的匹配。还有 init 放 sql 脚本,运行容器时就创建数据库;config 数据库配置数据库的编码。
  • redis 容器
  • rabbitmq 容器:还需要安装可用管理平台。
  • 最后把这些 docker 命令改写成 DockerCompose。

(1)mysql

  • 导出原有的数据库结构+数据,到指定 init 目录下(运行容器时会自动执行):
# 创建目录
mkdir -f /root/mysql/init

# 把 lottery_system 数据库导出.sql
# 这里省略了 -uroot -p,因为本地 root 是 auth_socket 认证方式,可以免密登录
mysqldump lottery_system > /root/mysql/init/lottery_system.sql
  • 编写 init-user.sql 脚本,创建一个业务用户,只有该数据库的权限,放到本地 init 文件中:
-- 创建专用业务用户
CREATE USER 'lottery-system'@'%' IDENTIFIED BY '密码';
-- 赋予数据库操作权限
GRANT ALL PRIVILEGES ON lottery_system.* TO 'lottery-system'@'%';
-- 刷新
FLUSH PRIVILEGES;
  • 编写配置文件,后缀为 .cnf:
[client]
default_character_set=utf8mb4
[mysql]
default_character_set=utf8mb4
[mysqld]
character_set_server=utf8mb4
collation_server=utf8mb4_unicode_ci
  • DockerCompose:
services:
  mysql:
    image: mysql
    container_name: mysql
    ports:
      - "3306:3306"
    environment:
      TZ: Asia/Shanghai
      MYSQL_ROOT_HOST: "localhost"     # 关键:只创建 root@'localhost'
      MYSQL_ROOT_PASSWORD: "密码"
    volumes:
      - "./mysql/conf:/etc/mysql/conf.d"
      - "./mysql/data:/var/lib/mysql"
      - "./mysql/init:/docker-entrypoint-initdb.d"
    networks:
      - app-net
    restart: unless-stopped

networks:
  app-net:
    name: app-network

(2)redis

  redis:
    image: redis
    container_name: redis
    ports:
      - "6379:6379"
    volumes:
      - ./redis/conf:/usr/local/etc/redis
      - ./redis/data:/data
    environment:
      TZ: Asia/Shanghai
    networks:
      - app-net
    restart: unless-stopped

(3)rabbitmq

  rabbitmq:
    image: rabbitmq:3-management  # 带管理界面的版本
    container_name: rabbitmq
    hostname: lottery-rabbit  # 显式指定主机名(固定节点名,避免数据目录变化:每次重启容器,主机名都是随机的,所以每次数据卷路径都不一样,因此需要指定主机名)
    ports:
      - "5672:5672"     # 消息通信端口
      - "15672:15672"   # 管理界面端口
    environment:
      TZ: Asia/Shanghai
      RABBITMQ_DEFAULT_USER: "lottery_admin"    # 自定义用户名(guest 只能访问 / 虚拟主机)
      RABBITMQ_DEFAULT_PASS: "admin" # 自定义密码
      RABBITMQ_DEFAULT_VHOST: "lottery_vhost" # 自定义虚拟主机,相当于不同数据库
    volumes:
      - ./rabbitmq/data:/var/lib/rabbitmq
      - ./rabbitmq/conf:/etc/rabbitmq
    networks:
      - app-net
    restart: unless-stopped

(4)应用程序

  app:
    build: 
      context: .
      dockerfile: Dockerfile
    container_name: lottery-app
    ports:
      - "8080:8080"
    volumes:
    - ./lottery-app/logs:/app/logs  # 容器内日志目录映射到宿主机
    - ./lottery-app/picture:/app/picture # 用户上传的奖品图片文件
    networks:
      - app-net
    depends_on:
      - mysql
      - redis
      - rabbitmq
    restart: unless-stopped

        Dockerfile:

FROM openjdk:17-jdk-alpine

# 时区变量
ENV TZ=Asia/Shanghai
# Java 以无头模式运行,避免显示设备依赖(与安装字体一起使用)
ENV JAVA_OPTS="-Djava.awt.headless=true"

WORKDIR /app

# 安装时区数据、fontconfig 和 ttf 字体(解决 SunFontManager 初始化失败的问题)
RUN apk add --no-cache \
    tzdata \
    fontconfig \
    ttf-dejavu \
  && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \
  && echo $TZ > /etc/timezone

# 复制应用 jar
COPY lottery-system-0.0.1-SNAPSHOT.jar ./lottery-system.jar

# 使用 shell 形式以展开 JAVA_OPTS
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar /app/lottery-system.jar"]

        当前的目录(需要创建项目的 lottery-app 目录,然后把 picture 放进去,容器运行的时候图片才会在容器挂载的目录里):

        一键部署:最好指定哪个项目 -p,不然可能查不出来;查日志的时候注意不是容器名,而是服务名。

# 启动  -p 项目命名  -f 指定 dockercompose 文件路径  -d 后台运行
docker compose -p lottery -f docker-compose.yml up -d

# 查看运行中的容器
docker compose -p lottery ps

# 查看【服务 SERVICE】的日志
docker compose -p lottery logs app

# 删除
docker compose -p lottery down

九、Docker 可视化管理面板 Portainer

1、安装

# 拉取 portainer 镜像
docker pull portainer/portainer

# 创建数据卷
docker volume create portainer_data

# 运行镜像并把数据挂载到数据卷
docker run -d -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer

2、访问 Portainer 管理页面

        在 xshell 设置云服务器上管理页面端口号 9000 与本地的隧道,只能从本地访问(也可以开启防火墙用公网IP访问,但没有隧道安全):

十、Windows 使用 docker

1、配置临时代理

        wsl、ubuntu 发行版下载太慢了,配置代理:

# 配置
$ENV:HTTP_PROXY = "http://192.168.43.68:7890"
$ENV:HTTPS_PROXY = "http://192.168.43.68:7890"

# 验证是否生效
Invoke-WebRequest -Uri "https://www.github.com" -UseBasicParsing

        生效:

2、搭建 linux 虚拟环境

        docker 是依赖 linux 环境运行的,所以得安装。两种选择:下载 wsl2 轻量级 linux 环境内核,或者下载完整的 hyper-v linux 虚拟环境。我选择  wsl2,但是得有 windows 10/windows 11 及以上的操作系统。

        开启 wsl:win+R,输入 optionalfeatures:

        然后提示重启,win 图标上邮件“终端管理员”

        安装 wsl:wsl 安装完了可能会自动给你安装 ubuntu,clr+c 取消就行。

wsl --install

        安装 ubuntu 发行版:

# 查询可安装的 linux 发行版
wsl --list --online

# 安装 ubuntu 发行版
wsl --install -d Ubuntu-24.04

        设置用户、密码,这个用户会被授予 sudo 权限:

        启动 ubuntu:

# 可以查看当前安装的所有发行版
wsl --list --verbose

# 启动
wsl -d Ubuntu-24.04

        /mnt 目录下就是 c 和 d 盘:

3、安装 docker

        参考第一章节。

4、配置 windows

        解决阻止终端退出后,wsl 自动关停,这样电脑启动后没有打开终端也能自动启动 linux 虚拟环境:win+R:shell:startup,创建文本文件。

wsl.vbs

# 把以下内容复制进去
set ws=wscript.CreateObject("wscript.shell")
ws.run "wsl -d Ubuntu-24.04", 0

        限制 wsl 内存:资源管理器 》地址栏输入 %USERPROFILE%,进入文件夹编辑,添加以下配置:

.wslconfig

# Settings apply across all Linux distros running on WSL 2
[wsl2]

# 内存限制,可以使用 GB 或 MB 单位
memory=4GB 

# 线程数
processors=2

# swap
swap=8GB

5、把 wsl 迁移到 D 盘

# 查看 wsl 状态
wsl -l -v

# 停止 wsl
wsl --shutdown

# 将虚拟环境导出到指定目录下备份
wsl --export Ubuntu-24.04 D:\Application\WSL\Ubuntu\Ubuntu.tar

# 注销原虚拟环境
wsl --unregister Ubuntu-24.04

# 将备份导入 WSL
wsl --import Ubuntu-24.04 D:\Application\WSL D:\Application\WSL\Ubuntu\Ubuntu.tar

# 恢复 Ubuntu 的默认用户
Ubuntu2404 config --default-user user

6、安装 docker desktop 集成管理

        它会自动帮你在 wsl 的发行版里导入与 docker 有关的工具,然后也有管理面板的功能。

        说明文档,里面有下载链接:WSL | Docker Docs

        我想安装到 D 盘,以管理员身份运行 cmd,转到安装包目录,执行:

start /w "" "Docker Desktop Installer.exe" install -accept-license --installation-dir="D:\Application\Docker" --wsl-default-data-root="D:\Application\Docker\data" --windows-containers-default-data-root="D:\\Application\\Docker"

        测试:

docker --version

        WSL 2 的 Ubuntu 中启动一个服务,WSL 2 会自动将该端口映射到 Windows 本机的相同端口。

        配置一下国内镜像源:

    更多推荐