docker的使用
1 查看下载的镜像:docker images
2 查看正在运行的容器:docker ps
查看所有容器:docker ps -a
3 下载jdk:
docker pull openjdk:8-jdk-alpine
4 删除镜像/容器:
docker rmi imageID
docker rm contentID
docker rm -f 强制删除
5 运行镜像
docker run -i imagesID: -i表示运行
docker run -di imagesID :-di 表示后台运行
6 容器后台运行后进入容器内
docker exec -it contentID /bin/bash
exit 退出容器
7 停止/启动/重启容器
docker start/stop/restart ID
dockerFile:
什么是dockerfile: 写明如何生成镜像的文件
dockerfile里的关键词:FROM 包含的基础镜像,下面包含maven和jdk17; WORKDIR :切换到哪个目录,COPY: 复制上下文的哪些内容,ARG :参数, RUN:运行后面的命令,构建镜像时执行. ENTRYPOINT:镜像构建完成后, 执行docker run 运行容器时执行
如何通过dockerfile生成镜像呢? 用docker build 命令
docker build --build-arg MODULE=saga-service -t saga-service:1.0.0 . //最后这个 . 表示构建上下文的路径(上传哪些文件),
-
-f参数 = 指定 Dockerfile 的位置(如果不写,默认在上下文路径下找Dockerfile)
dockerfile文件:
FROM maven:3.9-eclipse-temurin-17 AS builder WORKDIR /build # 复制整个工程(多模块,common-api 是公共依赖必须一起进来) COPY . . # 只打包指定模块;-am 同时构建它依赖的模块(common-api) ARG MODULE RUN mvn -B clean package -pl ${MODULE} -am -DskipTests # ---------- 阶段 2:运行(只留 JRE,镜像小、攻击面小) ---------- FROM eclipse-temurin:17-jre AS runtime WORKDIR /app # 从构建阶段取出 Spring Boot 打出的 fat jar ARG MODULE COPY --from=builder /build/${MODULE}/target/*.jar app.jar # 时区 ENV TZ=Asia/Shanghai # 实际端口由各模块 application.yml / SERVER_PORT 环境变量决定,这里仅文档用途 EXPOSE 8080 ENTRYPOINT ["java", "-jar", "/app/app.jar"]
上面的dockerfile有两个from,每个FROM代表一个阶段,第一个阶段打jar包需要maven,jdk17,这些都打进镜像,第二个阶段从第一个阶段的结果获取jar包,加上jre,再打镜像,这样可以减少镜像包的大小(省去maven和jdk)
docker compose:Docker 编排
作用:用一个 yaml 文件,把「一堆互相关联的容器」一起编排、一起启动/停止,如果不用docker compose,需要用docker run 命令启动每个服务,比如 mysql+nacos+seata+redis+nignx+java,需要执行六条docker run,用docker compose 只需要把他们写进一个文件中,执行这个文件就可以同时启动/停止所有容器.
dockercompose文件:
version: "3.8" services: # ---------- 基础设施 ---------- mysql: //每个service代表一个容器 image: mysql:8.0 //拉官方 MySQL 8 镜像 container_name: seata-mysql //容器名 environment: //环境变量,相当于 docker run -e MYSQL_ROOT_PASSWORD: root TZ: Asia/Shanghai ports: - "3306:3306" volumes: # 首次启动自动执行 init.sql / tcc-upgrade.sql / saga-init.sql 建库建表 - ./sql:/docker-entrypoint-initdb.d:ro //把宿主机项目里的 ./sql 目录挂到容器内 /docker-entrypoint-initdb.d 这个特殊目录。MySQL 镜像第一次启动时会自动执行这个目录里的 .sql 文件(建库建表脚本就是这么自动跑进去的)。结尾 :ro = 只读。 - mysql-data:/var/lib/mysql //把容器里存数据的目录挂到一个命名卷 mysql-data。好处:容器删了,数据还在(数据持久化),这里的mysql-data不是本机目录,是命名卷(由 Docker 统一管理的一块「持久化存储空间」,你给它起个名字,容器用它来存数据。) healthcheck: //健康检查 test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-proot"] interval: 10s timeout: 5s retries: 10 nacos: image: nacos/nacos-server:v2.2.3 container_name: seata-nacos environment: MODE: standalone NACOS_AUTH_ENABLE: "false"
JAVA_OPT_EXT: "-XX:-UseContainerSupport" # 修复 JDK8 在 cgroup v2 下的 NPE
ports: - "8848:8848" # 主端口 - "9848:9848" # 2.x gRPC 端口,Dubbo 3 需要 seata-server: image: seataio/seata-server:1.7.1 container_name: seata-server environment: SEATA_PORT: 8091 STORE_MODE: file # 示例用 file 模式,生产建议 db/nacos 模式 SEATA_IP: seata-server ports: - "8091:8091" - "7091:7091" # ---------- 业务服务:AT 模式 ---------- order-service: build: //如何build镜像 context: . //build.context 指定「在哪个目录找 Dockerfile」,默认文件名就是 Dockerfile,如果 Dockerfile 不叫这个名字怎么办,dockerfile: Dockerfile.prod # ← 显式告诉它 Dockerfile 叫这个名 args: { MODULE: order-service } image: ${REGISTRY:-harbor.example.com/seata-demo}/order-service:${IMAGE_TAG:-1.0.0} //镜像名 container_name: order-service ports: - "8081:8081" environment: //这些环境变量是在覆盖 application.yml 里的配置,不用改代码就能让服务连对地址,这些地址写的是 mysql、nacos、seata-server 这些服务名,不是 localhost、不是 IP。因为容器里 localhost 指的是「自己这个容器」,根本连不到别的容器。compose 自动建了一个内部网络,让所有容器能用服务名当域名互相访问 SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/seata_order?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: root DUBBO_REGISTRY_ADDRESS: nacos://nacos:8848 SEATA_SERVICE_GROUPLIST_DEFAULT: seata-server:8091 REMOTE_NOTIFYURL: http://notify-service:8084 depends_on: mysql: { condition: service_healthy } - nacos - seata-server storage-service: build: context: . args: { MODULE: storage-service } image: ${REGISTRY:-harbor.example.com/seata-demo}/storage-service:${IMAGE_TAG:-1.0.0} container_name: storage-service ports: - "20881:20881" # Dubbo provider 端口 environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/seata_storage?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: root DUBBO_REGISTRY_ADDRESS: nacos://nacos:8848 SEATA_SERVICE_GROUPLIST_DEFAULT: seata-server:8091 depends_on: mysql: { condition: service_healthy } - nacos - seata-server account-service: build: context: . args: { MODULE: account-service } image: ${REGISTRY:-harbor.example.com/seata-demo}/account-service:${IMAGE_TAG:-1.0.0} container_name: account-service ports: - "20882:20882" # Dubbo provider 端口 environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/seata_account?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: root DUBBO_REGISTRY_ADDRESS: nacos://nacos:8848 SEATA_SERVICE_GROUPLIST_DEFAULT: seata-server:8091 depends_on: mysql: { condition: service_healthy } - nacos - seata-server notify-service: build: context: . args: { MODULE: notify-service } image: ${REGISTRY:-harbor.example.com/seata-demo}/notify-service:${IMAGE_TAG:-1.0.0} container_name: notify-service # 无需对外暴露 HTTP 端口,order-service 通过容器网络 notify-service:8084 访问 # ---------- 业务服务:SAGA 模式 ---------- saga-service: build: context: . args: { MODULE: saga-service } image: ${REGISTRY:-harbor.example.com/seata-demo}/saga-service:${IMAGE_TAG:-1.0.0} container_name: saga-service ports: - "8087:8087" environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/seata_saga?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai SPRING_DATASOURCE_USERNAME: root SPRING_DATASOURCE_PASSWORD: root SEATA_SERVICE_GROUPLIST_DEFAULT: seata-server:8091 depends_on: mysql: { condition: service_healthy } - seata-server volumes: mysql-data:
nacos是用java写的,用容器启动时老的jdk8和linux系统有兼容问题,解决办法: -XX:-UseContainerSupport 关掉容器感知,或升级到修复该缺陷的 JDK 版本
docker compose 命令来执行compose文件: 默认找当前目录下的docker-compose.yml文件,如果要指定文件名,就用 -f参数
docker compose up -d : image 指定的镜像本地已存在则直接用现成的,不 build,image 本地不存在(且配了 build) 则用 build 从源码现打一个
docker compose up -d --build :无论有没有镜像,强制重新 build
-
up:启动(或重启)docker-compose.yml中定义的所有服务容器。如果容器不存在则创建,如果已停止则启动,如果已运行则保持运行(除非配置或镜像有变化)。 -
-d(detach 的缩写):后台运行。启动后,终端不会粘在日志输出上,而是直接返回命令行提示符,让你继续执行其他操作(所有日志会保存在后台)。 -
--build:强制重建镜像。即使本地已存在同名镜像,它也会根据Dockerfile和构建上下文重新构建一次,然后再用这个新镜像启动容器。
浙公网安备 33010602011771号