做项目的过程中,需要用到O记数据库。每次对数据库进行安装、配置和卸载,花费的时间都比较长,而且步骤上也变化不大,因此考虑用docker进行部署。
docker版本的oracle数据库,网上有许多镜像和使用说明。可以参考使用Docker安装Oracle数据库和Docker拉取Oracle的11g版本数据库。
具体步骤:
- 拉取oracle镜像的命令:
docker pull registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g
- 运行oracle容器镜像:
docker run -p 1521:1521 -d --name myOracle11g registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g
- 进入容器
docker exec -it myOracle11g bash
- 配置oracle有关的环境变量
export ORACLE_HOME=/home/oracle/app/oracle/product/11.2.0/dbhome_2
export ORACLE_SID=helowin
export PATH=$ORACLE_HOME/bin:$PATH
- 修改数据库密码
sqlplus /nolog
conn /as sysdba
alter system identified by system;
alter user sys identified by sys;
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;
exit
改进
按照blog中的步骤,确实能成功的构建和配置数据库,但是,在我们的项目中需要频繁的构建、部署和卸载数据库,如果每次都要手动的去做#3,#4和#5,比较麻烦,所以考虑在原有的oracle 11g镜像的基础上稍稍做一些定制化,以满足项目中的具体需要。
创建dockerfile文件
首先是创建dockerfile文件,有许多文档可以参考,包括官方文档Dockerfile reference,和一些热爱技术和分享的同仁们的技术blog,docker----dockerfile文件,Docker Dockerfile等等。
FROM registry.cn-hangzhou.aliyuncs.com/helowin/oracle_11g
ENV ORACLE_HOME=/home/oracle/app/oracle/product/11.2.0/dbhome_2 ORACLE_SID=helowin
ENV PATH="$ORACLE_HOME/bin:$PATH"
COPY update_oracle_sys_pswd /home/oracle/
ENTRYPOINT /home/oracle/app/oracle/product/11.2.0/dbhome_2/bin/dbstart /home/oracle/app/oracle/product/11.2.0/dbhome_2 && sleep 20s && /home/oracle/update_oracle_sys_pswd && tail -f /home/oracle/app/oracle/product/11.2.0/dbhome_2/startup.log
对其进行简单的说明:
- FROM语句,基于原有的镜像构建。
- ENV语句:设置oracle数据库有关的环境变量。注意如果需要引用变量,需要用
""
括起来【1】。
ENV PATH="$ORACLE_HOME/bin:$PATH"
- COPY语句:将
5. 修改数据库密码
的操作写入脚本,添加到镜像中。
sqlplus -S /nolog >> /home/oracle/result.out <
- ENTRYPOINT语句:覆盖了原有镜像的ENTRYPOINT,添加了一条新的命令用于执行添加的脚本,以修改数据库密码:
sleep 20s && /home/oracle/update_oracle_sys_pswd
至于原有镜像的ENTRYPOINT,可以从其镜像的描述文件中找到:
docker inspect 3fa112fd3642
...
"Entrypoint": [
"/bin/sh",
"-c",
"/home/oracle/app/oracle/product/11.2.0/dbhome_2/bin/dbstart /home/oracle/app/oracle/product/11.2.0/dbhome_2 && tail -f /home/oracle/app/oracle/product/11.2.0/dbhome_2/startup.log"
],
...
构建镜像
docker build -t zy_oracle_db/one:v1 $PATH_TO_DOCKERFILE
其他需要注意的问题
COPY文件的权限
在使用该指令的时候还可以加上 --chown=
选项来改变文件的所属用户及所属组。
上下文
在调用COPY命令的时候,需要考虑build上下文的问题。所谓的 build 上下文就是 docker build 命令的 PATH 或 URL 指定的路径中的文件的集合。【2】如果要把本地的文件拷贝到镜像中,那么本地的文件必须是在上下文目录中的文件。
entrypoint vs cmd
cmd给出的是一个容器的默认的可执行体。也就是容器启动以后,默认的执行的命令。重点就是这个“默认”。意味着,如果docker run没有指定任何的执行命令或者dockerfile里面也没有entrypoint,那么,就会使用cmd指定的默认的执行命令执行。同时也从侧面说明了entrypoint的含义,它才是真正的容器启动以后要执行命令。【3】
权限问题
容器内的进程默认以root
身份运行,但是我们可以看到该容器内的进程是以oracle
用户运行的。通过镜像的描述也可以印证这一点:
"Config": {
"Hostname": "",
"Domainname": "",
"User": "oracle",
精心设计的系统遵循最小特权原则,也就是说应用程序应该只能访问它所需的资源以执行其所需的功能。大多数容器化进程是应用程序服务,因此不需要root访问权限。虽然Docker需要root运行,但容器本身却不需要【4】。而且,内核通过uid和gid将在容器中的用户和组映射到宿主机,也就是说在容器中的root(uid=0)将获得宿主机中root(uid=0)用户的所有权限。所以,一般会在dockerfile中指定运行容器的用户或者在容器启动时指定用户。详细资料请参考linuxea:了解uid和gid如何在docker容器中工作。
docker日志
可以通过以下方式,获得tail -f /home/oracle/app/oracle/product/11.2.0/dbhome_2/startup.log
的日志:
docker logs CONTAINER_ID
【1】设置PATH变量并在Dockerfile中获取环境
【2】Build 上下文的概念
【3】【docker】CMD ENTRYPOINT 区别 终极解读!
【4】linuxea:docker容器中程序不应该以root用户身份运行