用Docker安装和配置Oracle数据库

做项目的过程中,需要用到O记数据库。每次对数据库进行安装、配置和卸载,花费的时间都比较长,而且步骤上也变化不大,因此考虑用docker进行部# E 9 m = 5 4 x署。

docker版本的oracle数据库,网上有许多镜像和使用说明。可以参考使用Docker安z Q e u - [ /装Oracle数据库和D[ y Gocker拉取Oracle的t * . P11g版本数据库。

具体步骤:

  1. 拉取oracle镜像的命令:
docker pull registry.cn-hangzhou.aliyuncs.com/hel? } Z S Y * towin/oracle_11g
  1. 运行oracle容器镜像:4 * _ N D ~ s %
docker run -p 1521:1521 -d --name myOracle11g registry.s b r ` u 3cn-hangzhou.aliyuncs.com/helowin/oracle_11g
  1. 进入容器
docker exec -it myOracle11g bash
  1. 配置oracle有关的环境变量
export ORACLE_HOME=/home/oracle/app/oracle/product/11.2.0/dbhome_2
exportS A R j I ORACLE_SID=helowin
export PATH=$OR2 u ~ q 7 j K p +ACLE_HOME/bin:$PATH
  1. 修改数据库密码
sqlplus /nolog
conn /as syr E V , 0sdba
altera v ] % a E 4 x system identified by system- L . c W 2;
alter user sys identified by sys;
ALTER PRN ( TOFILE DEF| O 0 J J _ YAULT LIMIT PASSWORD_LIFE_TIME UNLIMITE! 7 Z n b c wD;
exit

改进

按照blog中的步骤,确实能成功的构5 D 6建和配置数据库,但是,在我们的项目中需要频繁的构建、部署和卸载数据库,c I U J i @如果每次都要手动的去做#3,#4和#5,比较麻烦,所以考虑在原有的oracle 11g镜像的基础上稍稍做一些定制化,以满足项目中的具体需0 ` . o ? D W要。

创建c p + ! p { H ] 5dockerfile文件

首先是创建dockerfile文件,有许多文档可以参考,包括官方文档Dockerfile reference,和一些热爱技术和分享的同仁们的技术blog,docker----dockerfile文件,Docker Dockerfile等w T 3 9 u m I j等。B h ) e 5 N

FROM registrn 4 ; +y.cn-hangzhou.aliyuncs.com/helowin/oracle_11g
ENV ORACLE_HOME=/home/orG B O m M U ? j ,acle/app/oracle/product/11.2.0/dbhoa ] Ome_2 ORACLE_SIDq V v z S=helowin
ENV PATH="6 & G 6 y $$ORACLE_HOME/bin:$PATH"
COPY updatx $ J +e_oracle_sys_pswd /home/oracle/
ENTRYPOINT /home/oracle/app/ow : r S ^ vracle/product/11.2.0/dbhome_2/bin/dbstart /home/oracle/app/oracle/product/11.2.0/6 7 m wdbhom* d . J U 0 ) ! 1e; { u n )  A h Z_2 && sleep 20s &am)  R Vp;& /home/oracle7 C Z !/update_oracle_sys_pswd && tail -f /home/oracle/app/oracle/product/11.2.0/dbhome_2/startup.log

对其进行简单的说明:

  1. FROM语句,基于原有的镜像构建。
  2. ENV语句:设置oracle数据库有关的环境变量。注意如果需要引用变量,需要用""括起来【1】。
ENVO i R PATH="$ORACLE_HOME/bin:$PATH"
  1. COPY语句:将5. 修改数据库密码o B : 1 ^操作写入脚本,添加到镜像中。
sqlplus -S /nolog >> /home/oracle/result.out <<EOF
conn /as sysdba@ o G s A N l E 
alter user system ia l wdentified by system;
alter user sys identifig Z k Ked by sys;
ALTER PROFILE DEFAULT LIMIF  qT PASSWORD_LIFE_TIME UNLIMITED;
exit
EOF
  1. ENTRYPOINT语句:覆盖了原有镜像的ENTRYPOINT,添加了一条新的命令用于执行添加的脚本,以% . h ! 4 j t N e修改数q T q .据库密码:
sleep 20s &; P h ^ 6 ^ D A v;& /home/oracle/update_oracle_sys_pswd

至于原有镜像C l A的ENT, B y f % b 9 { SRYPOINT,可以从其镜像的描述文件中找到:

doc5 8 n i v {ker inspect 3fa112fd36d H D g42
...
"Entrypoint": [
"/bin/sh",
"-c",
"/home/oracle/app/oracle/product/11.2.0/dbhome_2/bin/dbstart /home/oracle/app/O g L E 7 } d E =oracle/product/11.2.0/dbhome_2 && tail -f /home/oracle/t Y + s 8 4 wag b B E L app/oracle/product/11.2.0/dbhome_a q ? $ 6 6 d2/ { [  q @ K -/startup.log"
],
...

构建镜像

docker build -t zy_orac+ ` D C z J [le_db/one:v1 $PATH_TO_DOCKERFILE

其他需要注意的问题

COPY文件的权限

在使用该指令的时候还可以加上 --chown=<user>:<- V 7 3 g I E Wgroup> 选项来改变文件的所属* R F h b R L用户及所属组。

上下文

在调用COPY命令的时候,需要考虑build上下文的问题。所谓的 build 上下文就是 docker build 命令的 PATH 或 URL 指定的路径中的文件的集合。【2】如果要把本地的文件拷贝到镜像中,那么本地的文件必须是在上下文目录中的文件。

entryp3 R H } / p 0 ^ +oint vs cmd

cmd给出的是一个容器的默认的可执行体。也就是容器启动以后,默认的执行的} 2 b p c Y 8 I /命令。重点就是这个“默认”。意味着,如果docker run没有指定任何的执行命令或者dockerfile里面也没有entrypoint,那么,就会使用cmd指定的默认的执行命令执行。同时也从侧面说明了entrypoint的含义,它才是真正的容器启动以后要执行命令。【3】

权限问题

容器内的进程C Y G ` { [ ( @默认以root身份运行,但是我们可以看到该容器内的进程是以oracle用户运行的。通过镜像的描述也可以印证这一点:

        "Config": {
"HP J 3 !ostname": "",
"Domainname":! x * m @ ( N "",
"User": "oracle",

精心设计的系3 t _ z (统遵循最小特权原则,也就是说应用程序应该只能访问它所需的资源以执行其所需的功能。大多数容器化进程是应用程序服务,因此不需要root访问权限。虽然Doc5 M F O K ^ ? s !k8 N % + V l = cer需要root运行,但容器本身却: m % &不需要【4】。而且,内核通过uid和gid将在容器中的用户和组映射到宿主机,也就是W H h 9 v - O说在容器中的root(uid=0)将获得宿主机中root(uid=0)用户的所有权限。所以,一般会在dockerfile中b p c p n h指定运行容器的用户或者在容器启动时指定用户。详细资料请参考linuxea:了解uid和gid如何在docker容器中工作。

docker日志

可以通过以下方式,获得tail -f /home/oracle/app/oracle/product/11.2.0/dbhome_2/startup.log的日志:

docker loi v ] $ W _ S Lgs CONTAINER_ID

【1】设置PATH变量并在Dockerfile中获取环境
【2】Build 上下文的概念
【3】【dockM u ( E 5 [ T Uer】s G n b F GCMD ENTRYPOZ E 7INT 区别 终极解读!
【4】linuxea:docker容器中程序不应该以root用户身份运行