├── .gitignore ├── step1 ├── oraInst.loc ├── install_rlwrap.sh ├── limits.conf ├── install.sh ├── sysctl.conf ├── Dockerfile ├── db_install.rsp └── dbca.rsp ├── step2 ├── colorecho ├── Dockerfile ├── ora_env ├── create_database.sh ├── entrypoint_oracle.sh └── db_template.dbt ├── LICENSE ├── Vagrantfile ├── Makefile └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | database/ 2 | -------------------------------------------------------------------------------- /step1/oraInst.loc: -------------------------------------------------------------------------------- 1 | inst_group=oinstall 2 | inventory_loc=/app/oracle/oraInventory 3 | -------------------------------------------------------------------------------- /step1/install_rlwrap.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | yum install -y https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm 4 | yum install -y rlwrap 5 | 6 | # yum clean all 7 | # rm -rf /var/lib/{cache,log} /var/log/lastlog 8 | -------------------------------------------------------------------------------- /step1/limits.conf: -------------------------------------------------------------------------------- 1 | 2 | # https://docs.oracle.com/database/121/LADBI/usr_grps.htm#LADBI7674 3 | oracle soft nofile 1024 4 | oracle hard nofile 65536 5 | oracle soft nproc 2047 6 | oracle hard nproc 16384 7 | oracle soft stack 10240 8 | oracle hard stack 32768 9 | 10 | -------------------------------------------------------------------------------- /step1/install.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -e 3 | 4 | trap "echo '******* Caught SIGINT signal. Stopping...'; exit 2" SIGINT 5 | 6 | gosu oracle /bin/bash -c "cd /tmp/install/database/ && ./runInstaller -waitforcompletion -ignoreSysPrereqs -ignorePrereq -silent -noconfig -responseFile /tmp/install/db_install.rsp" & 7 | wait $! 8 | $ORACLE_HOME/root.sh 9 | -------------------------------------------------------------------------------- /step2/colorecho: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ccred='\033[0;31m' 4 | ccyellow='\033[0;33m' 5 | ccgreen='\033[32m' 6 | ccend='\033[0m' 7 | 8 | echo_red() { 9 | echo -e "${ccred}$@${ccend}" 10 | } 11 | 12 | echo_yellow() { 13 | echo -e "${ccyellow}$@${ccend}" 14 | } 15 | 16 | echo_green() { 17 | echo -e "${ccgreen}$@${ccend}" 18 | } 19 | 20 | -------------------------------------------------------------------------------- /step2/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bofm/oracle12c:installed 2 | MAINTAINER bofm 3 | 4 | RUN mkdir /data && chmod 777 /data 5 | COPY db_template.dbt /tmp/ 6 | COPY colorecho /bin/ 7 | COPY entrypoint_oracle.sh /bin/ 8 | COPY create_database.sh ora_env /tmp/ 9 | RUN chmod +x /bin/entrypoint_oracle.sh /tmp/create_database.sh /tmp/ora_env /bin/colorecho 10 | ENV PATH=$PATH:/usr/bin:/usr/local/bin 11 | EXPOSE 1521 12 | USER oracle 13 | ENTRYPOINT ["entrypoint_oracle.sh"] 14 | CMD ["database"] 15 | -------------------------------------------------------------------------------- /step2/ora_env: -------------------------------------------------------------------------------- 1 | export ORACLE_BASE=/app/oracle 2 | export ORACLE_HOME=$ORACLE_BASE/product/12.1.0/dbhome_1 3 | export PATH=$ORACLE_HOME/bin:$PATH 4 | export ORACLE_SID=ORCL 5 | export ORACLE_DATA=/data/oracle 6 | export PATH=/usr/sbin:$PATH 7 | export PATH=$ORACLE_HOME/bin:$PATH 8 | export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib 9 | export CLASSPATH=$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib 10 | export NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS" 11 | export ORACLE_HOME_LISTNER=$ORACLE_HOME 12 | -------------------------------------------------------------------------------- /step1/sysctl.conf: -------------------------------------------------------------------------------- 1 | # System default settings live in /usr/lib/sysctl.d/00-system.conf. 2 | # To override those settings, enter new settings here, or in an /etc/sysctl.d/.conf file 3 | # 4 | # For more information, see sysctl.conf(5) and sysctl.d(5). 5 | fs.aio-max-nr = 1048576 6 | fs.file-max = 6815744 7 | kernel.sem = 250 32000 100 128 8 | net.core.rmem_default = 262144 9 | net.core.rmem_max = 4194304 10 | net.core.wmem_default = 262144 11 | net.core.wmem_max = 1048576 12 | net.ipv4.ip_local_port_range = 9000 65500 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 bofm 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /step1/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM oraclelinux 2 | MAINTAINER bofm 3 | 4 | RUN yum -y install oracle-rdbms-server-12cR1-preinstall.x86_64 && \ 5 | yum clean all && \ 6 | rm -rf /var/lib/{cache,log} /var/log/lastlog 7 | 8 | # Install gosu 9 | RUN curl -o /usr/local/bin/gosu -SL 'https://github.com/tianon/gosu/releases/download/1.7/gosu-amd64' \ 10 | && chmod +x /usr/local/bin/gosu 11 | 12 | COPY sysctl.conf oraInst.loc /etc/ 13 | COPY limits.conf /tmp/ 14 | RUN cat /tmp/limits.conf >> /etc/security/limits.conf 15 | 16 | ENV ORACLE_BASE=/app/oracle 17 | ENV ORACLE_HOME=$ORACLE_BASE/product/12.1.0/dbhome_1 18 | ENV PATH=$ORACLE_HOME/bin:$PATH 19 | ENV NLS_DATE_FORMAT=YYYY-MM-DD\ HH24:MI:SS \ 20 | ORACLE_DATA=/data/oracle \ 21 | ORACLE_SID=ORCL \ 22 | ORACLE_HOME_LISTNER=$ORACLE_HOME 23 | 24 | COPY *.rsp install.sh install_rlwrap.sh /tmp/install/ 25 | 26 | RUN mkdir -p $ORACLE_BASE && chown -R oracle:oinstall $ORACLE_BASE && \ 27 | chmod -R 775 $ORACLE_BASE && \ 28 | mkdir -p /app/oraInventory && \ 29 | chown -R oracle:oinstall /app/oraInventory && \ 30 | chmod -R 775 /app/oraInventory && \ 31 | chmod 664 /etc/oraInst.loc && \ 32 | chmod a+x /tmp/install/install.sh 33 | 34 | 35 | -------------------------------------------------------------------------------- /step2/create_database.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | source colorecho 4 | trap "echo_red '******* ERROR: Something went wrong.'; exit 1" ERR 5 | trap "echo_red '******* Caught SIGINT signal. Stopping...'; exit 2" SIGINT 6 | 7 | mkdir -p $ORACLE_DATA/oradata $ORACLE_DATA/dbs $ORACLE_DATA/fra 8 | chown -R oracle:oinstall $ORACLE_DATA 9 | chmod -R 775 $ORACLE_DATA 10 | 11 | log="$ORACLE_BASE/cfgtoollogs/dbca/$ORACLE_SID/$ORACLE_SID.log" 12 | pfile=$ORACLE_DATA/dbs/init$ORACLE_SID.ora 13 | 14 | tail -n0 -F $log | while read line; do echo -e "dbca_log: $line"; done & 15 | DBCA_TAIL_PID=$! 16 | 17 | shm_size="$(( $(df | grep /dev/shm | head -1|awk '{print $2}') / 1024))" 18 | # Substract 16 MB here because Oracle is bad at math. 19 | # For example, passind -totalMemory 1889 results in Oracle's attempt to use 20 | # 1996488704 bytes, which is 1904 MB. 21 | memory_target=$(($shm_size - 16)) 22 | echo_yellow Creatind database with MEMORY_TARGET="$memory_target"M 23 | 24 | dbca -silent -createDatabase \ 25 | -templateName /tmp/db_template.dbt \ 26 | -gdbName $ORACLE_SID \ 27 | -sid $ORACLE_SID \ 28 | -responseFile NO_VALUE \ 29 | -characterSet AL32UTF8 \ 30 | -totalMemory $memory_target \ 31 | -emConfiguration LOCAL \ 32 | -sysPassword sys \ 33 | -systemPassword system \ 34 | -datafileDestination $ORACLE_DATA/oradata \ 35 | -recoveryAreaDestination $ORACLE_DATA/fra \ 36 | -redoLogFileSize 100 \ 37 | -storageType FS \ 38 | -variables ORACLE_DATA=$ORACLE_DATA \ 39 | -initParams audit_file_dest=$ORACLE_DATA/admin/$ORACLE_SID/adump,diagnostic_dest=$ORACLE_DATA,filesystemio_options=SETALL \ 40 | -sampleSchema true \ 41 | -automaticMemoryManagement true \ 42 | -databaseType MULTIPURPOSE \ 43 | | while read line; do echo -e "dbca: $line"; done 44 | test ${PIPESTATUS[0]} -eq 0 || (echo_red "dbca exit code is $?." && sleep 5 && false) 45 | 46 | kill $DBCA_TAIL_PID 47 | 48 | sqlplus / as sysdba <<-EOF | 49 | whenever sqlerror exit failure 50 | create pfile='$pfile' from spfile; 51 | alter system register; 52 | exit 0 53 | EOF 54 | while read line; do echo -e "sqlplus: $line"; done 55 | 56 | echo_green pfile saved to $pfile 57 | -------------------------------------------------------------------------------- /step1/db_install.rsp: -------------------------------------------------------------------------------- 1 | oracle.install.responseFileVersion=/oracle/install/rspfmt_dbinstall_response_schema_v12.1.0 2 | oracle.install.option=INSTALL_DB_SWONLY 3 | ORACLE_HOSTNAME=oradb12c 4 | UNIX_GROUP_NAME=oinstall 5 | INVENTORY_LOCATION=/app/oraInventory 6 | SELECTED_LANGUAGES=en 7 | ORACLE_HOME=/app/oracle/product/12.1.0/dbhome_1 8 | ORACLE_BASE=/app/oracle 9 | oracle.install.db.InstallEdition=EE 10 | oracle.install.db.DBA_GROUP=dba 11 | oracle.install.db.OPER_GROUP=dba 12 | oracle.install.db.BACKUPDBA_GROUP=dba 13 | oracle.install.db.DGDBA_GROUP=dba 14 | oracle.install.db.KMDBA_GROUP=dba 15 | oracle.install.db.rac.configurationType= 16 | oracle.install.db.CLUSTER_NODES= 17 | oracle.install.db.isRACOneInstall= 18 | oracle.install.db.racOneServiceName= 19 | oracle.install.db.rac.serverpoolName= 20 | oracle.install.db.rac.serverpoolCardinality= 21 | oracle.install.db.config.starterdb.type=GENERAL_PURPOSE 22 | oracle.install.db.config.starterdb.globalDBName=ORCL 23 | oracle.install.db.config.starterdb.SID=ORCL 24 | oracle.install.db.ConfigureAsContainerDB= 25 | oracle.install.db.config.PDBName= 26 | oracle.install.db.config.starterdb.characterSet=AL32UTF8 27 | oracle.install.db.config.starterdb.memoryOption=true 28 | oracle.install.db.config.starterdb.memoryLimit=512 29 | oracle.install.db.config.starterdb.installExampleSchemas= 30 | oracle.install.db.config.starterdb.password.ALL=Comply123 31 | oracle.install.db.config.starterdb.password.SYS= 32 | oracle.install.db.config.starterdb.password.SYSTEM= 33 | oracle.install.db.config.starterdb.password.DBSNMP= 34 | oracle.install.db.config.starterdb.password.PDBADMIN= 35 | oracle.install.db.config.starterdb.managementOption=DEFAULT 36 | oracle.install.db.config.starterdb.omsHost= 37 | oracle.install.db.config.starterdb.omsPort= 38 | oracle.install.db.config.starterdb.emAdminUser= 39 | oracle.install.db.config.starterdb.emAdminPassword= 40 | oracle.install.db.config.starterdb.enableRecovery=false 41 | oracle.install.db.config.starterdb.storageType=FILE_SYSTEM_STORAGE 42 | oracle.install.db.config.starterdb.fileSystemStorage.dataLocation=/app/oracle/oradata 43 | oracle.install.db.config.starterdb.fileSystemStorage.recoveryLocation=/app/oracle/fast_recovery_area 44 | oracle.install.db.config.asm.diskGroup= 45 | oracle.install.db.config.asm.ASMSNMPPassword= 46 | MYORACLESUPPORT_USERNAME= 47 | MYORACLESUPPORT_PASSWORD= 48 | SECURITY_UPDATES_VIA_MYORACLESUPPORT=false 49 | DECLINE_SECURITY_UPDATES=true 50 | PROXY_HOST= 51 | PROXY_PORT= 52 | PROXY_USER= 53 | PROXY_PWD= 54 | COLLECTOR_SUPPORTHUB_URL= 55 | -------------------------------------------------------------------------------- /step2/entrypoint_oracle.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | source colorecho 5 | 6 | alert_log="$ORACLE_DATA/diag/rdbms/orcl/$ORACLE_SID/trace/alert_$ORACLE_SID.log" 7 | listener_log="$ORACLE_BASE/diag/tnslsnr/$HOSTNAME/listener/trace/listener.log" 8 | pfile=$ORACLE_DATA/dbs/init$ORACLE_SID.ora 9 | 10 | # monitor $logfile 11 | monitor() { 12 | tail -F -n 0 $1 | while read line; do echo -e "$2: $line"; done 13 | } 14 | 15 | 16 | if [ "$1" = 'listener' ]; then 17 | 18 | trap "echo_red 'Caught SIGTERM signal, shutting down listener...'; lsnrctl stop" SIGTERM 19 | trap "echo_red 'Caught SIGINT signal, shutting down listener...'; lsnrctl stop" SIGINT 20 | monitor $listener_log listener & 21 | MON_LSNR_PID=$! 22 | lsnrctl start 23 | wait %1 24 | 25 | elif [ "$1" = 'database' ]; then 26 | 27 | trap_db() { 28 | trap "echo_red 'Caught SIGTERM signal, shutting down...'; stop" SIGTERM; 29 | trap "echo_red 'Caught SIGINT signal, shutting down...'; stop" SIGINT; 30 | } 31 | 32 | start_db() { 33 | echo_yellow "Starting listener..." 34 | monitor $listener_log listener & 35 | lsnrctl start | while read line; do echo -e "lsnrctl: $line"; done 36 | MON_LSNR_PID=$! 37 | echo_yellow "Starting database..." 38 | trap_db 39 | monitor $alert_log alertlog & 40 | MON_ALERT_PID=$! 41 | sqlplus / as sysdba <<-EOF | 42 | pro Starting with pfile='$pfile' ... 43 | startup pfile='$pfile'; 44 | alter system register; 45 | exit 0 46 | EOF 47 | while read line; do echo -e "sqlplus: $line"; done 48 | wait $MON_ALERT_PID 49 | } 50 | 51 | create_db() { 52 | echo_yellow "Database does not exist. Creating database..." 53 | date "+%F %T" 54 | monitor $alert_log alertlog & 55 | MON_ALERT_PID=$! 56 | monitor $listener_log listener & 57 | lsnrctl start | while read line; do echo -e "lsnrctl: $line"; done 58 | MON_LSNR_PID=$! 59 | /tmp/create_database.sh 60 | echo_green "Database created." 61 | date "+%F %T" 62 | trap_db 63 | wait $MON_ALERT_PID 64 | } 65 | 66 | stop() { 67 | trap '' SIGINT SIGTERM 68 | shu_immediate 69 | echo_yellow "Shutting down listener..." 70 | lsnrctl stop | while read line; do echo -e "lsnrctl: $line"; done 71 | kill $MON_ALERT_PID $MON_LSNR_PID 72 | exit 0 73 | } 74 | 75 | shu_immediate() { 76 | ps -ef | grep ora_pmon | grep -v grep > /dev/null && \ 77 | echo_yellow "Shutting down the database..." && \ 78 | sqlplus / as sysdba <<-EOF | 79 | set echo on 80 | shutdown immediate; 81 | exit 0 82 | EOF 83 | while read line; do echo -e "sqlplus: $line"; done 84 | } 85 | 86 | echo "Checking shared memory..." 87 | df -h | grep "Mounted on" && df -h | egrep --color "^.*/dev/shm" || echo "Shared memory is not mounted." 88 | [ -f $pfile ] && start_db || create_db 89 | 90 | else 91 | exec "$@" 92 | fi 93 | -------------------------------------------------------------------------------- /Vagrantfile: -------------------------------------------------------------------------------- 1 | # -*- mode: ruby -*- 2 | # vi: set ft=ruby : 3 | 4 | # All Vagrant configuration is done below. The "2" in Vagrant.configure 5 | # configures the configuration version (we support older styles for 6 | # backwards compatibility). Please don't change it unless you know what 7 | # you're doing. 8 | Vagrant.configure(2) do |config| 9 | # The most common configuration options are documented and commented below. 10 | # For a complete reference, please see the online documentation at 11 | # https://docs.vagrantup.com. 12 | 13 | # Every Vagrant development environment requires a box. You can search for 14 | # boxes at https://atlas.hashicorp.com/search. 15 | config.vm.box = "ubuntu/trusty64" 16 | config.vm.define "docker-oracle12c" 17 | 18 | # Disable automatic box update checking. If you disable this, then 19 | # boxes will only be checked for updates when the user runs 20 | # `vagrant box outdated`. This is not recommended. 21 | # config.vm.box_check_update = false 22 | 23 | # Create a forwarded port mapping which allows access to a specific port 24 | # within the machine from a port on the host machine. In the example below, 25 | # accessing "localhost:8080" will access port 80 on the guest machine. 26 | # config.vm.network "forwarded_port", guest: 80, host: 8080 27 | config.vm.network "forwarded_port", guest: 1521, host: 1521 28 | 29 | # Create a private network, which allows host-only access to the machine 30 | # using a specific IP. 31 | # config.vm.network "private_network", ip: "192.168.33.10" 32 | 33 | # Create a public network, which generally matched to bridged network. 34 | # Bridged networks make the machine appear as another physical device on 35 | # your network. 36 | # config.vm.network "public_network" 37 | 38 | # Share an additional folder to the guest VM. The first argument is 39 | # the path on the host to the actual folder. The second argument is 40 | # the path on the guest to mount the folder. And the optional third 41 | # argument is a set of non-required options. 42 | # config.vm.synced_folder "../data", "/vagrant_data" 43 | 44 | # Provider-specific configuration so you can fine-tune various 45 | # backing providers for Vagrant. These expose provider-specific options. 46 | # Example for VirtualBox: 47 | 48 | config.vm.provider "virtualbox" do |vb| 49 | # Display the VirtualBox GUI when booting the machine 50 | # vb.gui = true 51 | 52 | # Customize the amount of memory on the VM: 53 | vb.memory = "2048" 54 | vb.cpus = 4 55 | end 56 | # 57 | # View the documentation for the provider you are using for more 58 | # information on available options. 59 | 60 | # Define a Vagrant Push strategy for pushing to Atlas. Other push strategies 61 | # such as FTP and Heroku are also available. See the documentation at 62 | # https://docs.vagrantup.com/v2/push/atlas.html for more information. 63 | # config.push.define "atlas" do |push| 64 | # push.app = "YOUR_ATLAS_USERNAME/YOUR_APPLICATION_NAME" 65 | # end 66 | 67 | # Enable provisioning with a shell script. Additional provisioners such as 68 | # Puppet, Chef, Ansible, Salt, and Docker are also available. Please see the 69 | # documentation for more information about their specific syntax and use. 70 | # config.vm.provision "shell", inline: <<-SHELL 71 | # sudo apt-get update 72 | # sudo apt-get install -y apache2 73 | # SHELL 74 | config.vm.provision "shell", inline: <<-SHELL 75 | wget -qO- https://get.docker.com/ | sudo sh 76 | sudo echo 'DOCKER_OPTS="--storage-opt dm.basesize=20G"' >> /etc/default/docker 77 | sudo usermod -aG docker vagrant 78 | SHELL 79 | end 80 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | REPO = bofm/oracle12c 2 | NAME = aa_oracle_zz 3 | CURDIR = `pwd` 4 | SHM_SIZE = 1GB 5 | OPTS = --shm-size $(SHM_SIZE) 6 | DOCKER_SAVE_FILENAME = docker_img_oracle_database_created_$$(date +%Y-%m-%d).tgz 7 | ccred=\033[0;31m 8 | ccgreen=\033[32m 9 | ccyellow=\033[0;33m 10 | ccend=\033[0m 11 | 12 | .PHONY: all 13 | 14 | # Use bofm/oracle12c:preinstall from Docker Hub 15 | all: install postinstall 16 | 17 | # Build from scratch 18 | full: preinstall install postinstall 19 | docker-save: docker-commit-created docker-save-created 20 | 21 | docker_cleanup: 22 | @[ `docker images -q --filter "dangling=true"| wc -l` -gt 0 ] && docker rmi `docker images -q --filter "dangling=true"` || true 23 | @[ `docker volume ls -q --filter "dangling=true"| wc -l` -gt 0 ] && docker volume rm `docker volume ls -q --filter "dangling=true"` || true 24 | 25 | clean: 26 | @echo `docker rm -v $(NAME) > /dev/null 2>&1 && echo Container "oracle" has been removed.` 27 | 28 | preinstall: 29 | @echo "$(ccgreen)Building base image...$(ccend)" 30 | # The following loop is a workaround for the bug of "docker build", related to device mapper. 31 | # Bug example: 32 | # INFO[0019] Error getting container ea069f9ff24469184e70e5ce9b2d6132a31109bf1d0a3e0e5d30e50da8cbd0b6 from driver devicemapper: 33 | # Error mounting '/dev/mapper/docker-8:1-263449-ea069f9ff24469184e70e5ce9b2d6132a31109bf1d0a3e0e5d30e50da8cbd0b6' on 34 | # '/var/lib/docker/devicemapper/mnt/ea069f9ff24469184e70e5ce9b2d6132a31109bf1d0a3e0e5d30e50da8cbd0b6': no such file or directory 35 | @for n in `seq 10`; do \ 36 | docker build -t $(REPO):preinstall step1 &&\ 37 | break || echo "$(ccred)******* FAILED $$n times$(ccend)" && sleep 2;\ 38 | done 39 | 40 | postinstall: 41 | @echo "$(ccgreen)Building the final image...$(ccend)" 42 | @for n in `seq 10`; do \ 43 | docker build -t $(REPO):latest step2 &&\ 44 | break || echo "$(ccred)******* FAILED $$n times$(ccend)" && sleep 2;\ 45 | done 46 | @echo "$(ccgreen)Image created: $(REPO):latest$(ccend)" 47 | @docker images $(REPO) 48 | 49 | install: 50 | @echo "$(ccgreen)Installing Oracle Database software...$(ccend)" 51 | @if docker ps -a|grep $(NAME)_install; then docker rm $(NAME)_install; fi 52 | @docker run $(OPTS) --name $(NAME)_install -v $(CURDIR)/../database:/tmp/install/database $(REPO):preinstall /tmp/install/install.sh 53 | @echo "$(ccgreen)Committing image with tag 'installed'...$(ccend)" 54 | @docker commit $(NAME)_install $(REPO):installed 55 | @docker rm $(NAME)_install 56 | 57 | bash: 58 | @docker run -it --rm $(OPTS) --name $(NAME) $(REPO) bash 59 | 60 | bash-v: 61 | docker run -it --rm -v /data $(OPTS) --name $(NAME) $(REPO) bash 62 | 63 | test: 64 | docker run -it -v /data $(OPTS) --name $(NAME) $(REPO) database 65 | docker start -ia $(NAME) 66 | docker rm -v $(NAME) 67 | 68 | test2: 69 | docker run -it -v /data $(OPTS) --name $(NAME) $(REPO) database 70 | docker rm -v $(NAME) 71 | 72 | test3: 73 | docker run -it $(OPTS) --name $(NAME) $(REPO) database 74 | docker rm -v $(NAME) 75 | 76 | docker-commit-created: 77 | @echo "$(ccgreen)Running new container and creating database...$(ccend)" 78 | docker run -d $(OPTS) --name $(NAME) $(REPO) database 79 | docker logs -f $(NAME) & 80 | @while true; do \ 81 | docker logs $(NAME) 2>/dev/null | grep "Database created." && break || sleep 20; \ 82 | done 83 | @echo "$(ccgreen)Stopping container...$(ccend)" 84 | docker stop -t 120 $(NAME) 85 | @echo "$(ccgreen)Committing image with tag '$(REPO):created' ...$(ccend)" 86 | docker commit $(NAME) $(REPO):created 87 | 88 | docker-save-created: 89 | @echo "$(ccgreen)Saving image...$(ccend)" 90 | docker save $(REPO):created | gzip -c > $(DOCKER_SAVE_FILENAME) 91 | @docker rm $(NAME) > /dev/null 92 | @echo "$(ccgreen)Image saved to: `readlink -f $(DOCKER_SAVE_FILENAME)`$(ccend)" 93 | 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Goals 2 | * Provide an easy way to build a lightweight [Docker](http://www.docker.com/) image for [Oracle Database](http://docs.oracle.com/database/121/index.htm). 3 | * Just run a database and skip the complexities of installation and configuration. 4 | 5 | ## Features 6 | * `docker run` creates and starts up a new database or the existing database, if it is already created. 7 | * `docker logs` shows all the logs prefixed with log source (in the style of syslog). 8 | * Uses `trap` to handle signals and shutdown gracefully. 9 | * Data and logs are stored in `/data` so that `-v /data` could be used. 10 | * Total memory used by Oracle instance (MEMORY_TARGET) is set depending on `--shm-size` parameter. 11 | * rlwrap can be installed by running `bash /tmp/install/install_rlwrap.sh` (+ 50 MB on disk). 12 | 13 | 14 | ## Build 15 | Optional: if you are using [Vagrant](https://www.vagrantup.com/), you can use this [Vagrantfile](Vagrantfile) for your build environment. 16 | 17 | 1. download `linuxamd64_12102_database_1of2.zip` and `linuxamd64_12102_database_2of2.zip` from [oracle.com](http://www.oracle.com/technetwork/database/enterprise-edition/downloads/database12c-linux-download-2240591.html) **and extract the archives to current directory**. 18 | 2. Execute the following lines in bash and wait ~15 minutes: 19 | ```shell 20 | git clone https://github.com/bofm/docker-oracle12c.git 21 | cd docker-oracle12c 22 | make all 23 | ``` 24 | 25 | ## Usage 26 | *Note: In the following examples `oracle_database` is the name of the container.* 27 | 28 | * Create or run database and listener 29 | * Daemon mode 30 | 31 | ```bash 32 | # Create and start 33 | docker run -d --shm-size 1GB --name oracle_database -p 1521:1521 -v /data bofm/oracle12c 34 | # Stop 35 | docker stop -t 120 oracle_database 36 | # Start again 37 | docker start oracle_database 38 | ``` 39 | **Important:** Always stop with `-t`, otherwise Docker will kill the database instance, if it doesn't shut down in 10 seconds. 40 | * Foreground mode 41 | 42 | ```bash 43 | # Start 44 | docker run -it --shm-size 1GB --name oracle_database -p 1521:1521 -v /data bofm/oracle12c 45 | # `ctrl+c` (SIGINT) to stop 46 | ``` 47 | 48 | * Create a gzipped tar archive suitable for `docker load` (an archive of the image with a created database and without volumes) 49 | 50 | It is recommended to use large (>=20GB, the default is 10GB) Docker base volume size, for which Vagrant with [Vagrantfile](Vagrantfile) can be used. 51 | 52 | ```bash 53 | # Build everything and save the created image to a file. 54 | # This will echo something like this: 55 | # Image saved to: /some/path/docker_img_oracle_database_created_YYYY-MM-DD.tgz 56 | make all docker-save 57 | 58 | # The saved image can be loaded from the file 59 | # The image will be loaded with tag bofm/oracle12c:created 60 | docker load < docker_img_oracle_database_created_YYYY-MM-DD.tgz 61 | 62 | # Run the image in the new container 63 | # Daemon 64 | docker run -d --shm-size 1GB --name oracle_database -p 1521:1521 bofm/oracle12c:created 65 | # Foreground 66 | docker run -it --shm-size 1GB --name oracle_database -p 1521:1521 bofm/oracle12c:created 67 | ``` 68 | 69 | * Logs 70 | 71 | ```bash 72 | # Check all the logs in one place 73 | docker logs oracle_database 74 | 75 | # Check alert log 76 | docker logs oracle_database | grep alertlog: 77 | 78 | # Check listener log 79 | docker logs oracle_database | grep listener: 80 | ``` 81 | 82 | * SQL*Plus, RMAN or any other program 83 | 84 | ```bash 85 | # Bash 86 | # as root 87 | docker exec -it -u root oracle_database bash 88 | # as oracle 89 | docker exec -it oracle_database bash 90 | 91 | # Run sqlplus in the running container 92 | docker exec -it oracle_database sqlplus / as sysdba 93 | 94 | # Run rman in the running container 95 | docker exec -it oracle_database rman target / 96 | 97 | # Run sqlplus in a separate container and 98 | # connect to the database in the linked container 99 | docker run -it --rm --link oracle_database:oradb bofm/oracle12c sqlplus sys/sys@oradb/ORCL as sysdba 100 | ``` 101 | 102 | * Start listener only (not sure if anybody needs it :) ) 103 | 104 | ```bash 105 | docker run -d --name listener -p 1521:1521 bofm/oracle12c listener 106 | # Or link it to the running container 107 | docker run -d --name listener -p 1521:1521 --link bofm/oracle12c listener 108 | ``` 109 | 110 | ### Compatibility 111 | * Tested on Docker 1.12 112 | 113 | ### Limitations and Bugs 114 | * `--shm-size` option is required to mount /dev/shm to use Oracle's automatic memory management. 115 | * Oracle Database doesn't work with Docker ZFS storage driver by default. Check [this issue](https://github.com/bofm/docker-oracle12c/issues/10) for the workaround. 116 | * Database options and sample schemas installation through DBCA is a mystery. In this repo dbca is run with `-sampleSchema true` and [db_template.dbt](step2/db_template.dbt) contains this line `