您的位置:首页 > 运维架构 > Docker

新手的我在使用docker制作tomcat镜像时遇到环境变量问题

2017-08-17 17:31 916 查看
先说一下我的操作流程。

作为一个linux小白+docker小白,我瑟瑟发抖的跟着百度上的教程一步一步的开始搞,步骤如下:

首先下载jdk和tomcat的压缩包(
.tar.gz文件),到本机的/root/software下。


1.拉取一个centos的镜像

    docker pull centos:
7.2
.
1511


2.把镜像容器化,run起来,并以交互模式进入容器内,同时把本地目录/root/software挂载到容器内的/mnt/software下,为了把jdk和tomcat的安装包搞到容器内,毕竟现在容器里面是空的,只有一个centos。端口映射顺便弄一下,后面要测试一下tomcat。

    docker run -i -t  -p 8080:8080 -v /root/software/:/mnt/software/ {镜像的id} /bin/bash

3.安装jdk,就是把压缩包解开,然后配置环境变量

  解压

    tar -zxf /mnt/software/jdk1.
7
.0_79.tar.gz -C .


    mv jdk1.
7
[code].0_79/ /opt/jdk/
[/code]

  配置环境变量


    编辑~/.bashrc文件


     vi
~/.bashrc


    在最后添加


       export JAVA_HOME=/opt/jdk
       export PATH=$PATH:$JAVA_HOME

    然后让环境变量在当前的shell生效

    source ~/.bashrc


4.解压tomcat程序包

    tar -zxf /mnt/software/apache-tomcat-
7.0
.
67
.tar.gz -C .


    mv apache-tomcat-
7.0
[code].
67
/ /opt/tomcat/
[/code]

5.启动tomcat


    sh /opt/tomcat/bin/startup.sh

    然后打开浏览器访问一下localhost的8080端口,ok没问题。

6. 退出容器,然后把容器提交成镜像

    exit

    commit -t tomcat_image  {容器id}

7.启动新镜像,在run命令中添加command,直接运行tomcat

   docker run -p 8080:8080 -it tomcat_image    /opt/tomcat/bin/startup.sh

   报错,没有JAVA_HOME环境变量!

8.换一种启动方式

   docker run -p 8080:8080 -it tomcat_image /bin/bash

   启动成功,进入到容器后,执行

   sh /opt/tomcat/bin/startup.sh

   打开浏览器测试一下,tomcat启动成功

   那么问题来了,为什么第7失败,而8却成功了,而且我总不能像8一样,每次进容器开启tomcat吧,太扯淡了。在7中,是什么问题,导致了我在.bashrc里配置的环境变量失效了,在Linux系统中,我一直都是这样配置环境变量,并且在之前的centos容器里也成功了,为什么提交了镜像,再启动就不行了呢。主要问题就处在了run命令的command上。

   .bashrc文件只会在交互模式的bash下,也就是/bin/bash -i,才会被调用。而docker的run命令的command默认是 /bin/bash -c 

   所以步骤7中的

/opt/tomcat/bin/startup.sh

相当于在启动容器时执行

/bin/bash -c  /opt/tomcat/bin/startup.sh

在这个过程中:

/bin/bash -c 这条命令会产生一个shell,假设该shell为shell_1,“~/.bashrc”不会被调用,不会在“shell_1”中产生JAVA_HOME等环境变量。

然后“shell_1”执行
/opt/tomcat/bin/startup.sh 这条命令,会在“shell_1”下产生一个子shell——shell_2。shell_2执行startup.sh中的代码,窗口被shell_2所拥有,你会看到tomcat的启动信息,但shell_2中依旧没JAVA_HOME等变量,所以就报错了。

  总之,原因是docker的command默认用bash -c,而.bashrc需要在bash -i中,才能生效。通过编辑~/.bashrc文件设置环境变量的容器,要多留心一下,以防踩雷。步骤7的简单解决方法就是在startup.sh中加一个

source  ~/.bashrc

下面贴上一些相关帖子的链接:

https://linuxacademy.com/community/posts/show/topic/14073-docker-entry-point-and-bashrc-file
https://stackoverflow.com/questions/37284667/how-to-bashrc-for-root-in-docker
http://dockone.io/question/958
https://my.oschina.net/huangyong/blog/372491?fromerr=kHrZPM01
    很多教学帖子都是在容器内部进行操作,然后把容器commit成镜像,这种方式是不可取的。
  官方墙裂要求使用dockerfile来构建镜像,其中ENV命令产生的环境变量是可以直接作用在容器内的,无论何时都有效,而且使用docker inspect指令也可以在详细信息中看到ENV设置的环境变量。使用ENV设置环境变量是最好的,commit只适合用来做做实验。通过commit产生的镜像,是无法重现其产生过程的,很多内部信息也无法展示,比如jdk装在哪里,tomcat装在哪里,都不知道。这种镜像自己凑合用用还行,想把它作为一个基础镜像进行扩展,还是很麻烦的。而dockerfile每一步都有记录,能够清楚地看到构建过程,方便后期修改,在镜像的基础之上制作新的镜像。

更多的资料可以查看docker的官方文档,比如dockerfile的推荐使用方式。

自己的linux知识着实太少了,后面我会专门学习一下shell的知识。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息