Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IntelliJ IDEA 使用 Docker 远程部署 #32

Open
anyesu opened this issue Sep 28, 2019 · 0 comments
Open

IntelliJ IDEA 使用 Docker 远程部署 #32

anyesu opened this issue Sep 28, 2019 · 0 comments

Comments

@anyesu
Copy link
Owner

anyesu commented Sep 28, 2019

前言


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

  • 提交代码 ( 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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant