IntelliJ IDEA 使用 Docker 远程部署

前言


通常,部署流程主要为下面几个步骤:

  • 提交代码 ( SVN 或者 Git ) 。

  • 构建服务器 上拉取代码进行构建打包。

  • 将软件包发送到 部署服务器,或者打包后上传到仓库,由 部署服务器 进行下载。

  • 部署服务器 停止现有服务,使用新的软件包进行启动。

上面的步骤很是繁琐,而且全程需要人工盯着以进行后续步骤,如果需要经常部署的话无疑是很浪费时间的。有人会说可以用 Jenkins 这样的 CI 工具啊,这也是一种方法,但不是本文的目标。

项目 Docker 化改造


既然要用 Docker 进行部署,那就要对现有项目做一些简单的改造,如果项目结构之前已经比较规范了,那么改造起来也会比较简单。

先在项目 根目录 ( 也可以放在一个 docker 文件夹下统一维护 ) 下添加几个文件:

文件 说明
Dockerfile 镜像配置文件,用于配置程序运行时依赖的环境,比如 JavaTomcat
.dockerignore 使用 Docker 构建镜像的时候会将 上下文目录 中的文件复制到 Docker Engine 中,如果每次都要复制一遍 源码构建中间产物 就会很浪费时间,.dockerignore 的作用就是用于忽略指定的文件,加快镜像构建速度。
docker-compose.yml 用于多个服务的编排。项目如果依赖了 数据库缓存消息队列 等,可以在这里配置依赖关系,还可以进行动态 扩缩容
.env docker-compose.yml 中可以使用 环境变量 进行参数化配置,一些默认的 环境变量 可以保存在这个文件中,实际构建时可以配置 环境变量 对其进行覆盖。

之后将项目中一些 写死配置 改为通过 环境变量 读取,这样就可以通过 docker-compose.yml 导入 环境变量 ,在不同环境下 ( 开发测试线上 等 ) 不用改文件就可以部署了。具体配置参考下面的测试项目。

准备工作


  • 安装 IntelliJ IDEA ( 目前最新版本是 2019.1 ) 。

  • 安装 Docker Desktop for Windows

    不推荐安装 Docker Desktop for Windows ,本文只是用于测试。
    最好在其他的 Linux 主机上运行 Docker

  • 下载最新版的 Docker Compose - docker-compose-Windows-x86_64.exe

    Docker Desktop for Windows 已经集成了 Docker Compose ,一般不需要单独下载。

  • 下载 测试项目

  • 先阅读完本文。

使用方法


  • 打开测试项目 JetBrains-Docker-Example/Springboot-Example

  • 设置 Project JDK

  • 导入 pom.xml ( 右键 Add as Maven Project 或者直接拖拽到 Maven 工具栏 中 ) 。

  • 添加 Docker Daemon

    File -> Settings -> Build, Execution, Deployment -> Docker -> Add -> 输入 Docker Daemon 的 URL

    Docker Daemon 的配置参考 这里

    添加 Docker Daemon

    注意:如果要启用 TLS 安全连接,协议名需要填写 https 而不是命令行中使用的 tcp

  • Add Run Configuration -> New -> Docker -> Docker-compose

    添加 Run Configuration
  • 修改配置。

    配置 Run Configuration

    当然,也可以直接打开 docker-compose.yml ,点击左侧显示的 三角形按钮 自动生成运行配置。

    通过 docker-compose.yml 运行
  • 运行配置,可以看到容器已经启动了,访问看下效果:127.0.0.1:3000

    docker 部署

    通过 Docker 插件 还可以可视化查看 容器日志环境变量端口映射数据卷 等配置信息,并且可以动态 修改配置进入容器 ,比起 敲命令 方便的不要太多。

    docker 插件

上面的步骤就是 Docker 插件 的常规用法,已经实现了 一键部署 效果,只是需要自己配置 Run Configuration

下面看下另一种使用方式:

  • 打开另一个测试项目 JetBrains-Docker-Example/Node-Example

  • 先使用命令 npm install 安装依赖。

    最好先在命令行执行再打开 IDEA ,不然可能把 IDEA 卡死。

  • 打开 package.json ,部署命令已经在 Docker 写好了,点击命令左侧显示的 三角形按钮 直接执行就行了。

    通过 package.json 运行

    如果需要部署到其他 远程 Docker Daemon ,可以修改 环境变量 DOCKER_HOST

  • 访问看下效果:127.0.0.1:8000

这种方式也是 一键式 的,也比较适合在命令行中执行。

Docker Desktop for Windows 的坑


  • 依赖于 Hyper-V 虚拟机,但是 Hyper-V 的兼容性不太好,容易出一些莫名其妙的问题,所以 不推荐安装

  • 使用它 ( 2.0.0.3 (31259) ) 自带的 docker-compose ( 1.23.2 ) 在执行某些镜像构建操作的时候可能会出现下面的错误:

    Building api
    [18576] Failed to execute script docker-compose
    Traceback (most recent call last):
      File "docker-compose", line 6, in <module>
      File "compose\cli\main.py", line 71, in main
      File "compose\cli\main.py", line 127, in perform_command
      File "compose\cli\main.py", line 1080, in up
      File "compose\cli\main.py", line 1076, in up
      File "compose\project.py", line 475, in up
      File "compose\service.py", line 342, in ensure_image_exists
      File "compose\service.py", line 1082, in build
      File "site-packages\docker\api\build.py", line 150, in build
    UnicodeDecodeError: 'gbk' codec can't decode byte 0x80 in position 10: illegal multibyte sequence
    

    查看 源码 发现是因为 .dockerignore 文件中包含了中文导致乱码, 1.19.0 及之前的版本没有这个问题。( 同样的版本,Linux 下没有这个问题 )

  • Windows 下使用旧版 docker-compose ( 比如 1.19.0 ) 部署到 远程 Linux Docker Daemon 时,如果使用了 数据卷 会出现下面的错误:

    Creating api ... 
    Creating api ... error
    ERROR: for api  Cannot create container for service api: create \etc\localtime: "\\etc\\localtime" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path
    
    ERROR: for api  Cannot create container for service api: create \etc\localtime: "\\etc\\localtime" includes invalid characters for a local volume name, only "[a-zA-Z0-9][a-zA-Z0-9_.-]" are allowed. If you intended to pass a host directory, use absolute path
    Encountered errors while bringing up the project.
    

    使用 docker-compose config 命令可以看到 数据卷 源路径被改成了 Windows 下的 反斜杠 类型的路径格式 \etc\localtime

    services:
      api:
        build:
          context: D:\github\test\JetBrains-Docker-Example\Springboot-Example
        command: java -jar -Djava.security.egd=file:/dev/./urandom -server -XX:+DisableExplicitGC
          -Xms256m -Xmx256m -Dspring.profiles.active=docker /app.jar
        container_name: api
        hostname: api
        ports:
        - 3000:8080/tcp
        privileged: false
        restart: always
        volumes:
        - \etc\localtime:/etc/localtime:rw
    version: '3.0'
    

    通过阅读 源码 找到了方法:使用 docker-compose内置环境变量 - COMPOSE_CONVERT_WINDOWS_PATHS=1

其他方案


上面提到了 Docker Desktop for Windows 的一些问题,所以我不推荐去安装它,单独下载 docker-compose 就好了。考虑到 WindowsLinux 之间交互可能会存在的问题,我还有一种方案:

  • 安装 WSL

  • WSL 中安装 Docker,但是只具备 客户端 功能而无法运行 Docker Daemon

    2019-07-12 追加: 目前 WSL 已经能够运行 Docker Daemon 了,参考我另一篇 文章

  • WSL 中安装 docker-compose

  • Windows 下编写脚本 docker-compose.bat

    @echo off
    
    echo current dir: %cd%
    
    :: 使用延迟变量
    setlocal enabledelayedexpansion
    
    :: 遍历所有参数,如果是 compose 文件则转换路径格式
    :: 使用 wslpath 将 Windows 路径转为 wsl 中的路径
    for %%i in ( %* ) do (
        :: 当前参数
        set arg=%%i
        :: 使用下面这种方式中文路径不会乱码
        if !last_arg!==-f if !arg! neq -f  set "arg=`wslpath '!arg!'`"
        :: 追加到新的参数列表中
        set "args=!args! !arg!"
        :: 作为上一个参数保存
        set last_arg=%%i
    )
    
    :: IDEA 部署到指定 Docker Daemon 的时候会设置下面的环境变量
    
    :: 设置环境变量 DOCKER_HOST 来指定 Docker Daemon 的 URL
    if defined DOCKER_HOST set "envs=export DOCKER_HOST=%DOCKER_HOST%;"
    
    :: 设置环境变量 DOCKER_TLS_VERIFY 和 DOCKER_CERT_PATH 指定 TLS 配置
    :: DOCKER_CERT_PATH 为空时,wslpath 命令的结果是 '.',要做处理
    if defined DOCKER_CERT_PATH set "envs=%envs%export DOCKER_CERT_PATH=`wslpath '%DOCKER_CERT_PATH%'`;"
    set "envs=%envs%export DOCKER_TLS_VERIFY=%DOCKER_TLS_VERIFY%;"
    
    :: 通过 WSL 调用 docker-compose
    :: 如果 bash -c 命令参数中包含$则要转义,否则在解析 bash -c 命令的时候就会对 shell 变量进行替换
    :: 注意:.env 文件需要在当前命令的执行目录下
    bash -c "%envs%env|grep DOCKER;set -x;docker-compose %args%;"
    

    IDEA 通过设置 环境变量 : DOCKER_HOSTDOCKER_TLS_VERIFYDOCKER_CERT_PATH 起到连接 远程 Docker Daemon 的目的。

  • 修改 Docker Compose可执行程序 为上面的脚本。

    修改 docker 可执行程序

结语


上面其实只是介绍一个很简单但又实用的功能,更多的是分享我在使用过程中遇到的一些问题,尤其是在写这篇文章的时候才发现自己之前有些认知是错误的,也是一种收获。


转载请注明出处:https://www.jianshu.com/p/410ea6e0b13a

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 157,298评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,701评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,078评论 0 237
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,687评论 0 202
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,018评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,410评论 1 211
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,729评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,412评论 0 194
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,124评论 1 239
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,379评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,903评论 1 257
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,268评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,894评论 3 233
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,014评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,770评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,435评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,312评论 2 260