美文网首页
java基础-day67-Docker02

java基础-day67-Docker02

作者: 触手不可及 | 来源:发表于2021-07-27 08:58 被阅读0次

    七、Docker应用


    7.1 Docker安装Tomcat

    运行Tomcat容器,为部署SSM工程做准备

    # 运行Tomcat容器
    [root@localhost ~]# docker run -d -p 8080:8080 --name mytomcat b8dfe9ade316
    

    7.2 Docker安装MySQL

    运行MySQL容器,为部署SSM工程做准备

    # 拉取MySql镜像
    [root@localhost ~]# docker pull daocloud.io/library/mysql:5.7.4
    
    # 运行MySql容器
    [root@localhost ~]# docker run -d -p 3306:3306 --name mysql -e MYSQL_ROOT_PASSWORD=root daocloud.io/library/mysql:5.7.4
    

    7.3 部署SSM工程

    • 修改SSM工程环境,设置为Linux中Docker容器的信息
    • 通过Maven的package重新打成war包
    • 将Windows下的war包复制到Linux中
    • 通过docker命令将宿主机的war包复制到容器内部
    • 测试访问SSM工程

    八、数据卷【重点


    为了部署SSM的工程,需要使用到cp的命令将宿主机内的ssm.war文件复制到容器内部。

    数据卷:将宿主机的一个目录映射到容器的一个目录中。

    可以在宿主机中操作目录中的内容,那么容器内部映射的文件,也会跟着一起改变。

    8.1 创建数据卷

    创建数据卷之后,默认会存放在一个目录下 /var/lib/docker/volumes/数据卷名称/_data

    docker volume create 数据卷名称
    
    #创建一个名为tomcat的数据卷
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# docker volume create tomcat
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# cd /var/lib/docker/volumes
    

    8.2 查看数据卷详情

    查看数据卷的详细信息,可以查询到存放路径,创建时间等等

    docker volume inspect 数据卷名称
    
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# docker volume inspect tomcat
    

    8.3 查看全部数据卷

    查看全部数据卷信息

    docker volume ls
    
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# docker volume ls
    

    8.4 删除数据卷

    删除指定数据卷

    docker volume rm 数据卷名称
    
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# docker volume rm tomcat
    

    8.5 容器映射数据卷

    映射有两种方式:

    • 第一种:通过数据卷名称映射,如果数据卷不存在。Docker会帮你自动创建,会将容器内部自带的文件,存储在默认的存放路径中。
    • 第二种:通过路径映射数据卷,直接指定一个路径作为数据卷的存放位置。但是这个路径下是空的。
    # 第一种:通过数据卷名称映射
    docker run -v 数据卷名称:容器内部的路径 镜像id
    
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# docker volume create mytomcat_volume
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# docker run -d -p 8080:8080 --name mytomcat -v mytomcat_volume:/usr/local/tomcat/webapps b8
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# cd /var/lib/docker/volumes
    [root@iz8vbdmrir2n6xqzrbd93hz volumes]# ls
    3fdc377f615693578180d1e7433d30e42baa53058eb55ebf86b6c4d0ed27d87a  metadata.db mytomcat_volume
    [root@iz8vbdmrir2n6xqzrbd93hz volumes]# cd mytomcat_volume/
    [root@iz8vbdmrir2n6xqzrbd93hz mytomcat_volume]# ls
    _data
    [root@iz8vbdmrir2n6xqzrbd93hz mytomcat_volume]# cd _data/
    [root@iz8vbdmrir2n6xqzrbd93hz _data]# ls
    docs  examples  host-manager  manager  ROOT
    
    
    # 第二种:通过路径映射数据卷
    docker run -v 路径:容器内部的路径 镜像id
    
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# docker run -d -p 8080:8080 --name mytomcat -v /opt/yangl:/usr/local/tomcat/webapps b8
    f70074ae145572c85c00afa5be9c2abb938906238be1c958b51d02806975f8de
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# cd opt
    -bash: cd: opt: No such file or directory
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# cd /opt/yangl
    [root@iz8vbdmrir2n6xqzrbd93hz yangl]# ls
    [root@iz8vbdmrir2n6xqzrbd93hz yangl]# mkdir ROOT
    [root@iz8vbdmrir2n6xqzrbd93hz yangl]# cd ROOT/
    [root@iz8vbdmrir2n6xqzrbd93hz ROOT]# vim index.html
    
    

    九、Dockerfile自定义镜像【重点


    我们可以从中央仓库下载一个镜像,也可以自己手动去制作一个镜像,需要通过Dockerfile去指定自定义镜像的信息

    9.1 Dockerfile

    创建自定义镜像就需要创建一个Dockerfile,如下为Dockerfile的语言

    from: 指定当前自定义镜像依赖的环境
    copy: 将相对路径下的内容复制到自定义镜像中
    workdir: 声明镜像的默认工作目录
    run: 执行的命令,可以编写多个
    cmd: 需要执行的命令(在workdir下执行的,cmd可以写多个,只以最后一个为准)
    
    # 制作SSM容器镜像,video-web.war要放在Dockerfile的同级目录下
    # 右键创建文件,命名为:Dockerfile 该文件无后缀,然后在文件添加如下内容
    from daocloud.io/library/tomcat:8.5.15-jre8
    copy video-web.war /usr/local/tomcat/webapps
    
    # 在root目录下创建一个目录,然后把Dockerfile文件和video-web.war都拷贝过来
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# mkdir myssm
    [root@iz8vbdmrir2n6xqzrbd93hz ~]# cd myssm
    [root@iz8vbdmrir2n6xqzrbd93hz myssm]# ls
    Dockerfile  video-web.war
    
    

    9.2 通过Dockerfile制作镜像

    编写完Dockerfile后需要通过命令将其制作为镜像,并且要在Dockerfile的当前目录下,之后即可在镜像中查看到指定的镜像信息,注意最后的 .

    docker build -t 镜像名称[:tag] .
    
    [root@iz8vbdmrir2n6xqzrbd93hz myssm]# docker build -t tomcat-video:1.0 .
    Sending build context to Docker daemon   18.4MB
    Step 1/2 : from daocloud.io/library/tomcat:8.5.15-jre8
     ---> b8dfe9ade316
    Step 2/2 : copy video-web.war /usr/local/tomcat/webapps
     ---> cb8ea4a83137
    Successfully built cb8ea4a83137
    Successfully tagged tomcat-video:1.0
    
    [root@iz8vbdmrir2n6xqzrbd93hz myssm]# docker images
    REPOSITORY                   TAG                 IMAGE ID            CREATED              SIZE
    tomcat-video                 1.0                 cb8ea4a83137        About a minute ago   352MB
    hello-world                  latest              bf756fb1ae65        7 months ago         13.3kB
    daocloud.io/library/tomcat   8.5.15-jre8         b8dfe9ade316        3 years ago          334MB
    daocloud.io/library/mysql    5.7.4               aa5364eb3d85        5 years ago          252MB
    
    [root@iz8vbdmrir2n6xqzrbd93hz myssm]# docker run -d -p 8081:8080 --name tomcat-video-ssm cb8
    c5faa261b5b01d77467ce7e3ac6a7310aac6f21aabfdc9f002b5790381f96c52
    
    
    

    十. Docker-Compose【重点


    之前运行一个镜像,需要添加大量的参数,可以通过Docker-Compose编写这些参数。而且Docker-Compose可以帮助我们批量的管理容器。这些信息只需要通过一个docker-compose.yml文件去维护即可。

    10.1 下载并安装Docker-Compose

    10.1.1 下载Docker-Compose

    去github官网搜索docker-compose,下载1.24.1版本的Docker-Compose

    下载路径:https://github.com/docker/compose/releases/tag/1.24.1

    10.1.2 设置权限

    需要将docker-compose-Linux-x86_64文件拷贝到/usr/local 目录下,然后设置docker-compose-Linux-x86_64文件的权限

    [root@iz8vbdmrir2n6xqzrbd93hz ~]# cd /usr/local
    [root@iz8vbdmrir2n6xqzrbd93hz local]# ls
    aegis  bin  docker-compose-Linux-x86_64  etc  games  include  lib  lib64  libexec  sbin  share  src
    [root@iz8vbdmrir2n6xqzrbd93hz local]# chmod 777 docker-compose-Linux-x86_64 
    
    
    10.1.3 配置环境变量

    方便后期操作,配置一个环境变量,查看之前配置jdk的环境文件

    [root@iz8vbdmrir2n6xqzrbd93hz local]# vim /etc/profile
    # 添加内容:export PATH=/usr/local:$PATH
    [root@iz8vbdmrir2n6xqzrbd93hz local]# source /etc/profile
    # source /etc/profile加载成功后,在任意目录下执行:docker-compose-Linux-x86_64 会出现以下信息
    [root@iz8vbdmrir2n6xqzrbd93hz local]# docker-compose-Linux-x86_64 
    
    测试效果
    image.png

    10.2 Docker-Compose管理MySQL和Tomcat容器

    yml文件以key: value方式来指定配置信息

    多个配置信息以换行+缩进的方式来区分

    在docker-compose.yml文件中,不要使用制表符

    version: '3.1'
    services:
      mysql:           # 服务的名称
        restart: always   # 代表只要docker启动,那么这个容器就跟着一起启动
        image: daocloud.io/library/mysql:5.7.4  # 指定镜像路径
        container_name: mysql  # 指定容器名称
        ports:
          - 3306:3306   #  指定端口号的映射
        environment:
          MYSQL_ROOT_PASSWORD: root   # 指定MySQL的ROOT用户登录密码
          TZ: Asia/Shanghai        # 指定时区
        volumes:
         - /opt/docker_mysql_tomcat/mysql_data:/var/lib/mysql   # 映射数据卷
      tomcat:
        restart: always
        image: daocloud.io/library/tomcat:8.5.15-jre8
        container_name: tomcat
        ports:
          - 8080:8080
        environment:
          TZ: Asia/Shanghai
        volumes:
          - /opt/docker_mysql_tomcat/tomcat_webapps:/usr/local/tomcat/webapps
          - /opt/docker_mysql_tomcat/tomcat_logs:/usr/local/tomcat/logs
    

    10.3 使用docker-compose命令管理容器

    在使用docker-compose的命令时 ,默认会在当前目录下找docker-compose.yml文件,由于docker-compose.yml文件的volumes指定的地址是 /opt/docker_mysql_tomcat,所以我们首先需要在opt目录下创建docker_mysql_tomcat目录,然后进入该目录创建docker-compose.yml文件,并粘贴以上写好的内容

    [root@iz8vbdmrir2n6xqzrbd93hz ~]# cd /opt
    [root@iz8vbdmrir2n6xqzrbd93hz opt]# ls
    containerd  yangl
    [root@iz8vbdmrir2n6xqzrbd93hz opt]# mkdir docker_mysql_tomcat
    [root@iz8vbdmrir2n6xqzrbd93hz opt]# ls
    containerd  docker_mysql_tomcat  yangl
    [root@iz8vbdmrir2n6xqzrbd93hz opt]# cd docker_mysql_tomcat/
    [root@iz8vbdmrir2n6xqzrbd93hz docker_mysql_tomcat]# vim docker-compose.yml 
    
    # 停止之前的所有的容器并删除
    [root@iz8vbdmrir2n6xqzrbd93hz docker_mysql_tomcat]# docker stop $(docker ps -qa)
    0274ca45914b
    f70074ae1455
    2db5a3fe0a92
    425b6e8e1806
    [root@iz8vbdmrir2n6xqzrbd93hz docker_mysql_tomcat]# docker rm $(docker ps -qa)
    0274ca45914b
    f70074ae1455
    2db5a3fe0a92
    425b6e8e1806
    [root@iz8vbdmrir2n6xqzrbd93hz docker_mysql_tomcat]# docker ps -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    
    # 使用docker-compose命令
    # 1. 基于docker-compose.yml启动管理的容器
    [root@iz8vbdmrir2n6xqzrbd93hz docker_mysql_tomcat]# docker-compose-Linux-x86_64 up -d
    Creating network "docker_mysql_tomcat_default" with the default driver
    Creating mysql  ... done
    Creating tomcat ... done
    
    # 2. 查看由docker-compose管理的容器
    [root@iz8vbdmrir2n6xqzrbd93hz docker_mysql_tomcat]# docker-compose-Linux-x86_64 ps
     Name               Command               State           Ports         
    ------------------------------------------------------------------------
    mysql    /entrypoint.sh mysqld --da ...   Up      0.0.0.0:3306->3306/tcp
    tomcat   catalina.sh run                  Up      0.0.0.0:8080->8080/tcp
    [root@iz8vbdmrir2n6xqzrbd93hz docker_mysql_tomcat]# 
    
    # 3. 查看日志
    [root@iz8vbdmrir2n6xqzrbd93hz docker_mysql_tomcat]# docker-compose-Linux-x86_64 logs -f
    
    # 4. 关闭并删除容器
    [root@iz8vbdmrir2n6xqzrbd93hz docker_mysql_tomcat]# docker-compose-Linux-x86_64 down
    Stopping tomcat ... done
    Stopping mysql  ... done
    Removing tomcat ... done
    Removing mysql  ... done
    Removing network docker_mysql_tomcat_default
    
    # 5. 开启|关闭|重启已经存在的由docker-compose维护的容器
    docker-compose-Linux-x86_64 start|stop|restart
    
    

    10.4 docker-compose配合Dockerfile使用

    使用docker-compose.yml文件以及Dockerfile文件在生成自定义镜像的同时启动当前镜像,并且由docker-compose去管理容器

    10.4.1 为了方便操作,在盘符下创建docker_ssm文件夹,在该目录下创建Dockerfile文件以及拷贝video-web.war

    编写Dockerfile文件

    from daocloud.io/library/tomcat:8.5.15-jre8
    copy video-web.war /usr/local/tomcat/webapps
    
    10.4.2 在docker_ssm目录下创建docker-compose文件夹,在docker-compose目录下创建docker-compose.yml

    编写docker-compose.yml文件

    # yml文件
    version: '3.1'
    services:
      video:  # mysql数据库的名称
        restart: always
        build:            # 构建自定义镜像
          context: ../      # 指定dockerfile文件的所在路径
          dockerfile: Dockerfile   # 指定Dockerfile文件名称
        image: video-ssm:1.0.1
        container_name: video-ssm
        ports:
          - 8081:8080
        environment:
          TZ: Asia/Shanghai
    
    10.4.3 把docker_ssm目录拷贝到虚拟机上的opt目录下,然后测试

    步骤如下:

    [root@iz8vbdmrir2n6xqzrbd93hz opt]# ls
    containerd  docker_mysql_tomcat  docker_ssm  yangl
    [root@iz8vbdmrir2n6xqzrbd93hz opt]# cd docker_ssm/
    [root@iz8vbdmrir2n6xqzrbd93hz docker_ssm]# ls
    docker-compose  Dockerfile  video-web.war
    [root@iz8vbdmrir2n6xqzrbd93hz docker_ssm]# cd docker-compose/
    [root@iz8vbdmrir2n6xqzrbd93hz docker-compose]# ls
    docker-compose.yml
    
    # 可以直接启动基于docker-compose.yml以及Dockerfile文件构建的自定义镜像
    [root@iz8vbdmrir2n6xqzrbd93hz docker-compose]# docker-compose-Linux-x86_64 up -d
    Building video
    Step 1/2 : from daocloud.io/library/tomcat:8.5.15-jre8
     ---> b8dfe9ade316
    Step 2/2 : copy video-web.war /usr/local/tomcat/webapps
     ---> 557e0830e974
    Successfully built 557e0830e974
    Successfully tagged video-ssm:1.0.1
    WARNING: Image for service video was built because it did not already exist. To rebuild this image you must use `docker-compose build` or `docker-compose up --build`.
    Creating video-ssm ... done
    # 出现以上内容后,可使用浏览器访问进行测试(注意:提前在mysql创建对应名字的数据库并导入数据)
    
    

    WARNING: Image for service video was built because it did not already exist. To rebuild this image you must use docker-compose build or docker-compose up --build.

    以上警告表示内容如下:

    # 如果自定义镜像不存在,会帮助我们构建出自定义镜像,如果自定义镜像已经存在,会直接运行这个自定义镜像
    # 重新构建的话。
    # 重新构建自定义镜像
    docker-compose build
    # 运行当前内容,并重新构建
    docker-compose up -d --build
    

    十一. Docker CI、CD


    11.1 CI、CD引言

    项目部署

    • 将项目通过maven进行编译打包
    • 将文件上传到指定的服务器中
    • 将war包放到tomcat的目录中
    • 通过Dockerfile将Tomcat和war包转成一个镜像,由DockerCompose去运行容器

    项目更新后,需要将上述流程再次的从头到尾的执行一次,如果每次更新一次都执行一次上述操作,很费时,费力。我们就可以通过CI、CD帮助我们实现持续集成,持续交付和部署。

    11.2 CI介绍

    CI(continuous intergration)持续集成

    持续集成:编写代码时,完成了一个功能后,立即提交代码到Git仓库中,将项目重新的构建并且测试。

    • 快速发现错误。
    • 防止代码偏离主分支。

    11.3 搭建Gitlab服务器

    实现CI,需要使用到Gitlab远程仓库,先通过Docker搭建Gitlab

    11.3.1 准备工作
    • 创建一个全新的虚拟机,并且至少指定4G的运行内存,4G运行内存是Gitlab推荐的内存大小。
    • 并且安装Docker以及Docker-Compose
    11.3.2 修改ssh的22端口

    将ssh的默认22端口,修改为60022端口,因为Gitlab需要占用22端口

    vi /etc/ssh/sshd_config
      PORT 22 -> 60022
    systemctl restart sshd
    
    11.3.3 编写docker-compose.yml

    docker-compose.yml文件去安装gitlab(下载和运行的时间比较长的)

    version: '3.1'
    services:
     gitlab:
      image: 'twang2218/gitlab-ce-zh:11.1.4'
      container_name: "gitlab"
      restart: always
      privileged: true
      hostname: 'gitlab'
      environment:
       TZ: 'Asia/Shanghai'
       GITLAB_OMNIBUS_CONFIG: |
        external_url 'http://192.168.199.110'
        gitlab_rails['time_zone'] = 'Asia/Shanghai'
        gitlab_rails['smtp_enable'] = true
        gitlab_rails['gitlab_shell_ssh_port'] = 22
      ports:
       - '80:80'
       - '443:443'
       - '22:22'
      volumes:
       - /opt/docker_gitlab/config:/etc/gitlab
       - /opt/docker_gitlab/data:/var/opt/gitlab
       - /opt/docker_gitlab/logs:/var/log/gitlab
    

    11.4 搭建GitlabRunner

    查看资料中的gitlab-runner文件即可安装

    11.5 整合项目入门测试

    11.5.1 创建项目

    创建maven工程,添加web.xml文件,编写html页面

    11.5.2 编写.gitlab-ci.yml

    编写.gitlab-ci.yml文件

    stages:
      - test
    
    test:
      stage: test
      script:
        - echo first test ci   # 输入的命令
    
    11.5.3 将maven工程推送到gitlab中

    执行git命令推送到Gitlab

    git push origin master
    
    11.5.4 查看效果

    可以在gitlab中查看到gitlab-ci.yml编写的内容

    效果图
    image.png

    11.6 完善项目配置

    添加Dockerfile以及docker-compose.yml, 并修改.gitlab-ci.yml文件

    11.6.1 创建Dockerfile
    # Dockerfile
    FROM daocloud.io/library/tomcat:8.5.15-jre8
    COPY testci.war /usr/local/tomcat/webapps
    
    11.6.2 创建docker-compose.yml
    # docker-compose.yml
    version: "3.1"
    services:
      testci:
        build: docker
        restart: always
        container_name: testci
        ports:
          - 8080:8080
    
    11.6.3 修改.gitlab-ci.yml
    # ci.yml
    stages:
      - test
    
    test:
      stage: test
      script:
        - echo first test ci
        - /usr/local/maven/apache-maven-3.6.3/bin/mvn package
        - cp target/testci-1.0-SNAPSHOT.war docker/testci.war
        - docker-compose down
        - docker-compose up -d --build
        - docker rmi $(docker images -qf dangling=true)
    
    11.6.4 测试
    测试效果
    image.png

    11.7 CD介绍

    CD(持续交付,持续部署)

    持续交付:将代码交付给专业的测试团队去测试

    持续部署:可以直接将指定好tag的代码直接部署到生产环境中

    CICD图
    image.png

    11.8 安装Jenkins

    11.8.1 编写docker-compose.yml

    官网:https://www.jenkins.io/

    version: "3.1"
    services:
      jenkins:
       image: jenkins/jenkins
       restart: always
       container_name: jenkins
       ports:
         - 8888:8080
         - 50000:50000
       volumes:
         - ./data:/var/jenkins_home
    
    11.8.2 运行并访问Jenkins

    第一次运行时,会因为data目录没有权限,导致启动失败

    chmod 777 data
    

    访问http://192.168.199.109:8888

    访问速度奇慢无比。。。。。
    

    访问成功后,需要输入密码,可在日志中查看

    image.png

    手动指定插件安装:指定下面两个插件即可

    publish ssh.

    git param.

    image.png

    安装成功后,需要指定上用户名和密码,登陆成功

    image.png

    11.9 配置Jenkins的目标服务器

    执行过程为代码提交到Gitlab,Jenkins会从Gitlab中拉取代码,并在Jenkins中打包并发布到目标服务器中。

    11.9.1 点击左侧的系统设置
    左侧导航
    image.png
    11.9.2 选中中间区域的系统设置
    系统设置
    image.png
    11.9.3 搜索Publish over SSH
    Publish over SSH
    image.png
    11.9.4 点击上图新增
    新增SSH连接
    image.png

    11.10 配置GitLab免密码登录

    链接Gitlab需要使用密码,我们可以通过SSH的方式,免密码登陆Gitlab拉取代码,避免每次都输入密码。

    11.10.1登录Jenkins容器内部
    docker exec -it jenkins bash
    
    11.10.2 输入生成SSH秘钥命令
    ssh-keygen -t rsa -C "邮箱(随便写)"
    
    11.10.3将秘钥复制到GitLab的SSH中
    配置密钥
    image.png

    11.11 配置JDK和Maven

    我们需要再Jenkins中将代码打包,需要依赖JDK和Maven的环境

    11.11.1 复制软件到data目录下
    效果
    image.png
    11.11.2 在监控界面中配置JDK和Maven
    配置环境变量
    image.png
    11.11.3 手动拉取gitlab项目

    使用SSH无密码连接时,第一次连接需要手动确定

    手动拉取一次
    image.png

    11.12 创建maven任务

    实现通过Jenkins的Maven任务,自动去Gitlab拉取代码,并在本地打包,发布到目标服务器上

    11.12.1 创建maven工程,推送到GitLab中

    随便创建一个即可……

    11.12.2 Jenkins的监控页面中创建maven任务
    指定GitLab地址
    image.png
    指定maven打包方式
    image.png
    11.12.3 执行maven任务
    立即构建,并查看日志
    image.png
    控制台查看日志信息
    image.png
    11.12.4 最终效果
    打包成功
    image.png

    11.13 实现持续交付持续部署

    实现根据tag标签,实现持续交付和持续部署

    11.13.1 安装Persistent Parameter的插件
    安装插件
    image.png
    11.13.2 重新指定构建项目的方式
    根据标签构建项目
    image.png
    自定义构建
    image.png
    11.13.3 构建项目成功后,需要将内容发布到目标服务器
    发布服务器后执行的命令
    image.png
    11.13.4 添加程序代码
    # Dockerfile 文件
    FROM daocloud.io/library/tomcat:8.5.15-jre8
    COPY testcd-1.0-SNAPSHOT.war /usr/local/tomcat/webapps
    
    # docker-compose.yml文件
    version: "3.1"
    services:
      testcd:
        build: docker
        restart: always
        container_name: testcd
        ports:
          - 8081:8080
    
    11.13.5 测试
    根据标签修改发布版本
    image.png

    相关文章

      网友评论

          本文标题:java基础-day67-Docker02

          本文链接:https://www.haomeiwen.com/subject/cqinmltx.html