文章

本地docker部署某公司前后端项目案例学习

本文章是记录外包某公司项目时,本地docker部署运行环境时出现的问题及解决办法 可供后续项目部署参考

本地docker部署某公司前后端项目案例学习

本地运行某项目后端项目

背景

在windows主机的情况下,编译运行基于Linux运行环境下的golang项目,并且使用穿透脚本将数据进行转发到远程服务端。

使用工具/思路

  • ubuntu:latest镜像创建服务端镜像
  • windows主机创建穿透脚本容器
  • network网络通讯

完整实现思路过程

  • 首先,在本地拉取这个项目,就去看他的README文件,并且首次编译,就出现很多Unix的包,还有一些自定义仓库的包,就觉得不能。并且需要我们使用的脚本,都是使用sh脚本的,因此觉得不能在windows中运行。

  • 就开始有点迷茫,随后尝试去问GPT,看看有什么办法去在windows中运行sh脚本,冒出来是使用git bash的方法,还有各种各样的方法,觉得没有一点头绪。

  • 然后突然就想到当时我们的坦克后端,也同样是运行在linux容器中的,也就有个想法,创建一个ubuntu:latest镜像的容器,让我们的项目运行在上面。就开始干;因为容器之间的通讯其实很简单,因此是印证了能实现容器内部跟我宿主机的容器进行通讯的,所以就更加坚定我的想法。

  • 之后就先在windows下,将这个sh脚本,转化为bat脚本,同样是可以创建容器的。然后就开始创建容器,一开始发现我创建的容器,无法运行,实际上挂载的命令是没错的,就是这个-it的参数,能让我的容器保持一个持续运行的状态。然后想使用-v这个参数,将我主机的项目挂载进到容器中,想实现这个直接编译成可执行文件。

  • 在挂载之后,执行go build的时候,发现此时很多依赖包是需要仓库的授权,或者说是要从私有仓库中拉取的,因此就需要使用git,在容器中去下载这个git的版本,然后从仓库中进行拉取。在拉取的时候,发现我在输入了usernamepassword之后,还是不能成功拉取,是因为在Linux环境下,没有交互式的界面让git去验证我们的权限。因此需要使用到/etc/netrc文件,自动的将这个账号密码都放置到配置文件中,能自动传输到git中,就能解决这个无法拉取的问题

  • 随后能成功拉取了,也成功build。之后就尝试去运行run.sh脚本,但是发现里面无法执行,有个配置文件skillexam_base.properties无法找到,经过询问之后,是他们没有做好这个README的更新,遗漏更新这个run.sh脚本的文件路径,随后读取了新的配置文件之后,报错就消失了 avatar2

  • 随后成功看到项目启动,但是看到这个IP,找不到地址 avatar3

  • 在修改了这个为本地的模式,修改/etc/hosts的配置文件:为127.0.0.1,但是意识到这个IP肯定是无法访问的。因为在容器的内部,与宿主机是互相隔离的。因此就尝试了docker.internal.network这个属性,发现也不行,无法执行。原因是/etc/hosts这个优先级会比docker的优先级高,会首先读取DNS的命令,不会自动读取到docker的任何指令。

  • 第一个想法是:在容器内部,再次创建新的容器,这样他们就能同属一个网络了,就可以使用127.0.0.1了,但是在实现的过程中,一直无法挂载成功docker.sock的套接字,也就是子容器无法守护docker进程,也就无法使用docker指令,一直找不到方法解决

  • 再之后就突然想起,既然我是想解决容器的网络不同的问题,那刚好容器的network就能解决这个容器之间的通讯,我创建一个新的网路,然后将我服务端添加到这个网络中,再将这个穿透脚本的容器,也添加到这个skillexam网络中,之后通过IP地址进行通讯。在/etc/hosts添加上127.20.0.2这个IP,就能成功找到同一个IP的不同端口的容器。

  • 之后就全部都通了;中间经历了一些小插曲,就是直接发送https的网路请求,直接无法经过ssl证书的保证。

  • 至此就成功运行服务端项目

总结

  • 本次非常考验自己在现有的知识上,对于完全不懂得的东西,去学会掌握,运用他。对此,我对整个容器的通讯,还有Linux、windows操作系统又多进了一步。

具体实现如下

本地部署服务端

补充使用dockerFile的形式,就不需要每一次都要进入到容器内部进行重新执行复杂指令了。

  • 进入windows下拉取的项目路径,新增文件transport.bat,然后打开cmd执行

    1
    
    .\transport.bat
    
  • 使用指令创建Linux环境的服务端容器

    1
    
    docker run -it --name=skillexam -p 5739:5739 ubuntu:latest 
    
  • 之后在windows主机的终端中

    1
    2
    3
    4
    5
    6
    7
    8
    
    docker network create skillwork
      
    docker network connect skillexam skillwork
      
    docker network connect 穿透脚本创建的容器名 skillwork
      
    # 查看这个网络下,穿透脚本创建的容器的IP,记住这个IP
    docker inspect network skillwork
    
  • 执行指令进去这个容器内部终端

    1
    
    docker exec -it skillexam bash
    
  • 在容器内部依次执行

    1
    
    apt update
    
    1
    
    apt-get install uchardet libuchardet-dev
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    apt-get install -y libiconv
      
    wget http://ftp.gnu.org/pub/gnu/libiconv/libiconv-1.16.tar.gz
    # 解压
    tar -zxvf libiconv-1.16.tar.gz
    # 进入目录
    cd libiconv-1.16
    # 配置
    ./configure --prefix=/usr/local/libiconv
    # 编译
    make
    # 安装
    make install
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    apt-get install -y nano
    nano ~/.netrc
      
    # 输入 替换成自己的git 的账号与密码
    machine w.gdy.io
    login username
    password password
      
      
    apt install git -y
    # 进入到自己想要放置到的目录
    git clone -b  -
    
    1
    2
    
    # 执行一下,重载容器配置
    source /etc/profile
    
    1
    2
    3
    4
    5
    6
    7
    8
    
    # 这个指令我不确定
    apt install golang 
      
    go env -w GOPROXY=https://goproxy.cn,direct
    go env -w GOPRIVATE=" - "
      
    go build 
    go mod tidy
    
    • 创建一个文件夹后,执行

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      
      touch skillexam-base.properties
          
      nano skillexam-base.properties
          
      # 复制下面代码到文件中
          
          
          
      [default]
      # 由于无法正常上传公司的内容 这样直接屏蔽掉
      ...
      
    • 之后回到项目路径 修改run.sh文件中的N_RCP_ALL_CFG为:

      1
      
      export N_RCP_ALL_CFG=/你刚刚创建的文件夹路径/skillexam_base.properties
      
    1
    2
    3
    4
    
    nano /etc/hosts
      
    #在最后一行添加
    之前查看穿透容器的IP mongo.loc redis.loc fs.loc ucs.loc course.loc
    
    1
    
    ./run.sh
    

注意事项:

  • 操作容器内文件,可以利用vscode的插件:Dev containers,这个插件能直接连接到容器,直接使用vscode去编辑容器内的文件

由于每一次停止这个穿透脚本,就会删除掉这个穿透容器,因此每一次创建这个穿透容器,就要执行一次

1
docker network connect 穿透脚本创建容器名 skillwork
  • 但是不需要重新修改Linux容器中的/etc/hosts的IP地址,因为这个不会根据容器的清除而改变

教培部署前端运行环境

  • 安装对应版本的nodejs版本 去node官网查找对应的tag

    • 1
      
      https://nodejs.org/en/blog/release/v16.15.0
      
  • 之后直接找到对应的tag的连接,使用

    1
    
    wget https://nodejs.org/dist/v16.15.0/node-v16.15.0-linux-x64.tar.xz
    

    去下载这个包 直接二进制

  • 或者是直接使用一个node带有版本的镜像进行创建容器即可

本文由作者按照 CC BY 4.0 进行授权