dockerfile与compose入门学习

作者Gitee地址 https://gitee.com/thciweicloud/loafblog
作者项目 面包博客,一个微服务架构的前后端分离博客系统。前后端使用Vue+SpringCloud,鉴权登录使用JWT,使用ElasticSearch作为博客检索引擎,使用ELK进行日志收集,GithubActions完成持续集成和交付

Dockerfile

Dockerfile用于编写镜像

  • 基础指令
#打包 寻找Dockerfile文件按规则构建镜像
#推荐专门创建一个dockerfile文件夹或者dockerignore
docker build -t ourmysql8:01 .     # .指定当前目录寻找Dockerfile

(以下指令前提)vim Dockerfile  
#FROM
FROM mysql:8.0

#RUN 表示提前运行一些指令
RUN yum install -y vim 
(json书写格式) RUN ["yum","install","-y","vim"]

#EXPOSE 
EXPOSE 5672 #指定暴露端口
EXPOSE 15672

#WORKDIR
WORKDIR /data #指定进入容器后默认的目录位置

#COPY
COPY aa.txt /data/bb   #将文件拷贝到容器指定位置,日后jar包、war包部署可用

#ADD
ADD aa.txt /data/bb #将文件拷贝到容器指定位置
ADD  https://dlcdn.apache.org/tomcat/tomcat-8/v8.5.72/bin/apache-tomcat-8.5.72.tar.gz     /data/bb  #指定url下载到指定目录,而COPY不可以
ADD apache-tomcat-8.5.72.tar.gz /data/bb #将文件自动解压到容器内部

(ADD apache-tomcat-8.5.72.tar.gz /data/bb
RUN mv apache-tomcat-8.5.72 tomcat) #解压到容器内并且重命名

#VOLUME 
#定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。在run启动容器时 -v可以指定宿主机文件到容器内部的挂载,如果忘记则遵从VOLUME配置
VOLUME /data/bb/tomcat/webapps #容器内位置

#ENV
ENV BASE_DIR /data/bb #定义环境变量
ADD bb.txt $BASE_DIR  

#ENTRYPOINT
#可以有多个,建议用于书写固定的命令
ENTRYPOINT ls $BASE_DIR/bb #容器启动时默认运行什么命令
ENTRYPOINT tail -f bb.txt

#CMD
#只能有一个,写多个会被覆盖掉,建议用于书写灵活的参数
CMD ls $BASE_DIR/bb
docker run ourmysql8:01 ls /data/bb/tomcat/ #CMD与ENTRYPOINT的区别,CMD可以被指令覆盖,此时不再查看CMD指定的ls位置


  • 引申jar包使用
#ENTRYPOINT与CMD配合使用 !!一定要以json形式!!
ENTRYPOINT ["ls"]
CMD ["/data/bb"]
docker run xx /data/bb/webapps 展示出webapps的内容
引申jar包启动:
ENTRYPOINT ["java","-jar"]
CMD ["sms.jar"]
  • Dockfile构建SpringBoot项目
mkdir demo
#将jar包拷贝到demo文件夹中

创建Dockerfile

FROM openkjdk:8-jre  #jar包需要基于jdk环境,所以在dockerhub中寻找jdk镜像
WORKDIR /app
ADD demo-0.0.1-SNAPSHOT.jar app.jar
EXPOSE 8081 
ENTRYPOINT ["java","-jar"]
CMD ["app.jar"]                          

打包镜像

docker build -t demo:01 .

启动容器

docker run -d  -p 8081:8081 demo:01

使用docker日志观察 jar包运行情况

docker logs -f 容器id

这里分享一个寻找 jdk/jre的小技巧

dockerhub中输入java来打开openjdk,否则出现的是付费版本,在tag搜索时输入 8- 更方便找到你要的jdk/jre

插件安装,如果你的idea版本比较老,可以在插件商店安装docker插件,新版自带忽略,这样我们就可以直接在项目中编写Dockerfile和远程连接调试了,项目中编写好Dockerfile直接拖入服务器

远程连接服务器:Tools<<Deployment<<Browse RemoteHost

Docker Compose

Docker Compose用于对容器集群的编排

项目( Project): 有多个服务共同组成一个完整业务单元 定义 docker- compose.yml文件中

服务( service):一个服务对应一个应用容器在一个项目中可以存在多个服务

docker-compose的service服务概念是抽象出来的,不真实存在此文件,其囊括了众多的服务,在使用层面可以比作我们创建了一个hello文件夹,其中创建了docker-compose.yml,我们在这个项目文件夹中执行docker-compose up

简单案例

curl -L https://github.com/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
#如果curl not found,建议直接去github下载官方编译好的版本上传到服务器

mv docker-compose-Linux-x86_64 docker-compose #改名
mv docker-compose  /usr/local/bin/     # /usr/local/bin/ 是存放环境变量的位置
chmod +x /usr/local/bin/docker-compose #赋权限

#检测是否安装成功
docker-compose -v

编写一个简单的 docker-compose.yml

version: "3.0"

services:
  tomcat: 
    image: demo:01
    ports:
      - "8081:8081"
  tomcat01:
    image: demo:01
    ports:
      - "8082:8082"

在当前文件夹启动

docker-compose up

Docker-Compose模板

volume

数据卷挂载

version: "3.0"

services:
  tomcat: 
    image: demo:01
    ports:
      - "8081:8081"
    volumes: #完成宿主机与容器中目录数据卷共享
      - tomcatwebapps:/usr/local/tomacat/webapps

volumes: #声明上面服务所使用的自动创建的卷名
  tomcatwebapps: #声明指令的卷名  compose自动创建该卷名但是会在之前加入项目名 如 hello_tomcatwebapps
    external:    #使用自定义卷名 true
      false

自定义卷名消除前缀需要提前创建名称

docker  volume create tomcatwebapps

查看一下数据卷挂载

#docker volume ls 展示数据卷
-------------------- 
local     f3a4a8b8db61caaef47ae695c5758344ba98d0e0838767a91ec0c097c4f311bd
local     hello_tomcatwebapps
--------------------
# docker inspect hello_tomcatwebapps 查看数据卷信息

-------------------- 
[
    {
    
    
        "CreatedAt": "2021-11-09T15:18:53+08:00",
        "Driver": "local",
        "Labels": {
    
    
            "com.docker.compose.project": "hello",
            "com.docker.compose.version": "1.25.4",
            "com.docker.compose.volume": "tomcatwebapps"
        },
        "Mountpoint": "/www/server/docker/volumes/hello_tomcatwebapps/_data",
        "Name": "hello_tomcatwebapps",
        "Options": null,
        "Scope": "local"
    }
]
-------------------
#cd /www/server/docker/volumes/hello_tomcatwebapps/_data

你可以发现自动创建的卷名加了hello的前缀,hello正是其所处文件夹的名称,印证了docker-compose以 项目 作为抽象层的概念,服务组成了一个项目

network

网桥指定

指定tomcat01和02在同一网桥

version: "3.0"

services:
  tomcat01:
    container_name: tomcat01 #相当于run的 --name
    image: demo:01
    ports:
      - "8081:8081"
    volumes: #完成宿主机与容器中目录数据卷共享
      - tomcatwebapps01:/usr/local/tomacat/webapps
    networks: #代表当前服务使用那个网络桥
      - hello
  tomcat02:
    container_name: tomcat02
    image: demo:01
    ports:
      - "8082:8082"
    volumes:
      - tomcatwebapps02:/usr/local/tomcat/webapps
    networks:
      - hello

volumes: #声明上面服务所使用的自动创建的卷名
  tomcatwebapps01: #声明指令的卷名  compose自动创建该卷名但是会在之前加入项目名 如 hello_tomcatwebapps
    external: #使用自定义卷名 true
      false
  tomcatwebapps02:
    external:
      false

networks: #定义服务到桥
  hello: #定义上面的服务用到的网桥名称

自定义网桥名需要提前创建名称

docker network create bridge hello
网桥叫做hello
#查询网络 docker network ls
--------------------------------
NETWORK ID     NAME            DRIVER    SCOPE
55a776d42a54   bridge          bridge    local
6ad1e3f86688   hello_default   bridge    local
6e8150907bbd   hello_hello     bridge    local
---------------------------------
两个tomcat处在同一网桥
#docker ps
---------------------------------
5ac6699bbb32   demo:01   "java -jar app.jar"   9 seconds ago    Up 7 seconds   8081/tcp, 0.0.0.0:8082->8082/tcp, :::8082->8082/tcp   tomcat02
5817bcade528   demo:01   "java -jar app.jar"   15 minutes ago   Up 7 seconds   0.0.0.0:8081->8081/tcp, :::8081->8081/tcp             tomcat01
--------------------------------

#进入容器curl 请求连接8082
docker exec -it 5ac /bin/bash
root@5ac6699bbb32:/app# curl http://tomcat02:8082

env_file

environment直接配置环境变量如密码等不够安全,所以可以使用env_file来指定环境配置文件

- MYSQL_ROOT_PASSWORD=root

在这里mysql需要配置用户名密码,我们可以把内容转移到mysql.env文件中

version: "3.0"
services:
  tomcat01:
    container_name: tomcat01 #相当于run的 --name
    image: demo:01
    ports:
      - "8081:8081"
    volumes: #完成宿主机与容器中目录数据卷共享
      - tomcatwebapps01:/usr/local/tomacat/webapps
    networks: #代表当前服务使用那个网络桥
      - hello

  mysql:
    image: mysql:8.0
    container_name: mysql
    ports:
      - "3307:3306"
    volumes:
      - mysqldata:/var/lib/mysql
      - mysqlconf:/etc/mysql
#    environment:
#      - MYSQL_ROOT_PASSWORD=root
    env_file: #用来将environment环境中配置放入指定配置文件
      - mysql.env
    networks:
      - hello


volumes: #声明上面服务所使用的自动创建的卷名
  tomcatwebapps01: #声明指令的卷名  compose自动创建该卷名但是会在之前加入项目名 如 hello_tomcatwebapps
    external: #使用自定义卷名 true
      false
  mysqldata:
  mysqlconf:

depends_on

容器编排,指定启动顺序

version: "3.0"
services:
  tomcat01:
    container_name: tomcat01 #相当于run的 --name
    image: demo:01
    ports:
      - "8081:8081"
    volumes: #完成宿主机与容器中目录数据卷共享
      - tomcatwebapps01:/usr/local/tomacat/webapps
    networks: #代表当前服务使用那个网络桥
      - hello
    depends_on: #容器启动顺序
      - mysql
      - tomcat02
  tomcat02:
    container_name: tomcat02
    image: demo:01
    ports:
      - "8082:8082"
    volumes:
      - tomcatwebapps02:/usr/local/tomcat/webapps
    networks:
      - hello

  mysql:
    image: mysql:8.0
    container_name: mysql
    ports:
      - "3307:3306"

healthcheck

心跳检测

version: "3.0"
services:
  tomcat01:
    container_name: tomcat01 #相当于run的 --name
    image: demo:01
    ports:
      - "8081:8081"
    volumes: #完成宿主机与容器中目录数据卷共享
      - tomcatwebapps01:/usr/local/tomacat/webapps
    networks: #代表当前服务使用那个网络桥
      - hello
    healthcheck: #心跳检测
      test: ["CMD","curl","-f","http://localhost"]
      interval: 1m30s
      timeout: 10s
      retries: 3

sysctls

非必须

用来修改容器中系统内部参数

承接在services tomcat01:sysctls: #用来修改容器中系统内部参数 并不是必须 有些服务启动受容器内操作系统参数限可能会无法启动必须过修改容器中参数才能启动
  - net.core.simaxconn=1024
  - net.ipv4.tcp_syncookies=0

ulimits

非必须

用来修改容器中系统内部进程数限制

ulimits: #用来修改容器中系统内部进程数限制 日后使用可根据当前容器运行服务要求进行修改
  nproc: 65535
  nofile:
    soft: 20000
    hard: 40000

Compose模板中build指令

用来将指定dockerfile打包成对应镜像,然后运行该镜像

正常dockerfile先打包镜像,compose再编排镜像,build省略中间步骤

services:

  demo:
    build: #启动服务先将bui1d命令中指定 dockerfile打包成镜像,再运行该镜像
      context: demo #指定上下文目录 dockerfile所在目录
      dockerfile: Dockerfile
    container_name: demo
    ports:
      - "8083:8083"
    networks:
      - hello
    depends_on:
      - tomcat01

Compose常用指令

没有特别说明,这些指令的对象是项目,而上述模板指令针对的则是内部

-f

 #当compose文件名称与目录名不同,需要指定compose文件
 docker-compose -f demo-compose.yml up

–verbose

展示调试信息

up(重要)

-d

#后台启动
docker-compose up -d 

down

#用来关闭所有compose中的服务,并移除自己创建的网桥,volume数据卷不移除
docker-compose down
也可以使用 docker-compose exec -it 服务id(yml文件指定的名称) bash   exit停掉容器

ps

#用来展示当前compose项目中运行的服务
docker-compose ps

[root@]# docker-compose ps
   Name                Command              State     Ports
-----------------------------------------------------------
hello_demo   java -jar app.jar             Exit 143        
mysql        docker-entrypoint.sh mysqld   Exit 0          
tomcat01     java -jar app.jar             Exit 143        
tomcat02     java -jar app.jar             Exit 143   

restart

#重启服务,不写服务id默认重启所有
docker-compose restart

rm

#用来删除项目服务
docker-compose rm -fv 服务id    -v会强制删除数据卷

stop

#关闭服务 但不会关闭网络
docker-compose 服务id

top

#用来compose内部进程
docker-compose top 

pause

#暂停服务
docker-compose pause 服务id
#docker-compose ps 可以看到state为Paused

logs

#查看服务日志,不写id默认全部
docker-compose logs 服务id

Docker可视化工具

Portainer

端口9000,可以查看容器、资源统计(图表)、日志等等

#安装
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer 

同样可以让Portainer伴随docker-compose启动,需要声明数据卷

version: "3.0"

services:
  tomcat02:
    container_name: tomcat02
    image: demo:01
    ports:
      - "8082:8082"
    volumes:
      - tomcatwebapps02:/usr/local/tomcat/webapps
    networks:
      - hello

  portainer:
    image: portainer/portainer
    container_name: portainer
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    ports:
      - "8000:8000"
      - "9000:9000"
#需要声明数据卷
volumes: #声明上面服务所使用的自动创建的卷名
  portainer_data:

ComposeDemo

version: "3.0"

services:

  demo:
    build: #启动服务先将bui1d命令中指定 dockerfile打包成镜像,再运行该镜像
      context: demo #指定上下文目录 dockerfile所在目录
      dockerfile: Dockerfile
    container_name: hello_demo
    ports:
      - "8083:8083"
    networks:
      - hello
    depends_on:
      - tomcat01

  tomcat01:
    container_name: tomcat01 #相当于run的 --name
    image: demo:01
    ports:
      - "8081:8081"
    volumes: #完成宿主机与容器中目录数据卷共享
      - tomcatwebapps01:/usr/local/tomacat/webapps
    networks: #代表当前服务使用那个网络桥
      - hello
    depends_on:
      - mysql
      - tomcat02
    healthcheck:
      test: [ "CMD","curl","-f","http://localhost" ]
      interval: 1m30s
      timeout: 10s
      retries: 3
        #sysctls: #用来修改容器中系统内部参数 并不是必须 有些服务启动受容器内操作系统参数限可能会无法启动必须过修改容器中参数才能启动
        #- net.core.simaxconn=1024
        #- net.ipv4.tcp_syncookies=0
        #ulimits: #用来修改容器中系统内部进程数限制 日后使用可根据当前容器运行服务要求进行修改
        #nproc: 65535
        # nofile:
      #soft: 20000
      #hard: 40000
  tomcat02:
    container_name: tomcat02
    image: demo:01
    ports:
      - "8082:8082"
    volumes:
      - tomcatwebapps02:/usr/local/tomcat/webapps
    networks:
      - hello

  mysql:
    image: mysql:8.0
    container_name: mysql
    ports:
      - "3307:3306"
    volumes:
      - mysqldata:/var/lib/mysql
      - mysqlconf:/etc/mysql
    #    environment:
    #      - MYSQL_ROOT_PASSWORD=root
    env_file: #用来将environment环境中配置放入指定配置文件
      - mysql.env
    networks:
      - hello

  #  redis:
  #    image: redis:5.0.10
  #    container_name: redis
  #    volumes:
  #      - redisdata:/data
  #    command: "redis-server --appendonly yes"
  portainer:
    image: portainer/portainer
    container_name: portainer
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - portainer_data:/data
    ports:
      - "8000:8000"
      - "9000:9000"

volumes: #声明上面服务所使用的自动创建的卷名
  tomcatwebapps01: #声明指令的卷名  compose自动创建该卷名但是会在之前加入项目名 如 hello_tomcatwebapps
    external: #使用自定义卷名 true
      false
  tomcatwebapps02:
    external:
      false
  mysqldata:
  mysqlconf:
  portainer_data:
  
  
#  redisdata:
networks: #定义服务到桥
  hello: #定义上面的服务用到的网桥名称

Guess you like

Origin blog.csdn.net/thciwei/article/details/121683443