Please provide sample docker compose file that includes persistent storage as sample. This would be a good example to have handy as starting point for DBA's that are less familiar with docker, but work with teams using Docker Datacenter.
Here you go:
version: '2'
services:
database:
image: <internal-registry>/oracle/database:<tag> # e.g: registry.company.br/oracle/database:12.1.0.2-ee
environment:
- ORACLE_SID=xe
- ORACLE_PDB=test
volumes:
- ./oracle/oradata:/opt/oracle/oradata # persistent oracle database data.
- ./data-bridge:/data-bridge # just to have someplace to put data into the running container if needed
ports:
- 1521:1521
- 8080:8080
- 5500:5500
You just have one problem with this approach:
Actually the ./oracle/oradata folder is owned by a host user in the host machine, usually the root user or yours. The oracle docker image runs everything under the oracle user, created in the Dockerfile. When it starts, it runs the runOracle.sh under the oracle user. But when it mounts the volume into the container, it mounts the folder under root permissions, so the database instance that is running under the oracle permissions is unable to write into the volume.
Assuming that the docker-compose.yml file is in /home/user,
[user@container-host ~]$ docker-compose up -d
[user@container-host ~]$ docker-compose exec database bash
[oracle@a90a54d1fee8 ~]$ # now you're good to go
oracle user inside the container.[oracle@a90a54d1fee8 ~]$ id oracle
uid=1000(oracle) gid=500(dba) groups=500(dba),501(oinstall)
[user@container-host ~]$ sudo chown -R 1000:500 ./oracle
[user@container-host ~]$ docker-compose restart
Everything should be working normally now.
Change the Dockerfile from the repo and set the permissions to this volume at an image build time:
RUN chown -R oracle:dba /opt/oracle/oradata
VOLUME /opt/oracle/oradata
A real example
If you already have a database container running,that may be hard to recreate every time you run docker compose, and need to test something like a dblink integration you can also specify in your docker-compose.yaml :
database:
#other stuff ....
networks:
- dbnet
external_links: # https://docs.docker.com/compose/compose-file/#/externallinks
- hard_to_create_oracle:oracle
You also will need to add a network,because both containers need to be at same network:
[user@machine]$ docker network create dbnet && docker network connect dbnet hard_to_create_oracle
And add to network your docker-compose.yaml file:
version: '2'
services:
database:
# service definition
networks: # https://docs.docker.com/compose/compose-file/#/networks
dbnet:
external: true
With docker composer you can create a network at your docker composer file,but you can't add to network a container which is not defined inside of your docker composer file,so that's why the network created outside of the docker composer file.
@armand1m I think your second solution will work.
I've actually tested the solution 2 today, and it doesn't really works.. Don't know if I'm doing something wrong, but I always need to create the oradata folder in the host system and execute sudo chown -R 1000:500 <path> on it before running the container, as actually described in the Solution 1. If this is step is not done, the container is unable to start the oracle instance. It throws an error that calls SIGTERM, and then shuts down the container.
A Docker Compose sample file is now provide within the samples folder: 12102-docker-compose
As to the error mentioned above, this works as expected. When using Docker volumes Docker merely creates a folder outside the container with the typical characteristics of a Linux folder. That is, a new folder with read and execute permissions for everybody and write permission for the current user: drwxr-xr-x As Docker is running under root the folder is owned by the user root and the group root.
Oracle Database inside the container is run by the oracle user under the dba group. In order for the database to write the database files to disk it needs permissions on the Linux folder it should write those files into. Unfortunately, by default, that is not guaranteed by Docker.
Im trying to create multiple containers using docker-compose each exposing separate port for access.
version: '2'
services:
db-1:
image: oracle/database:12.2.0.1-se2
ports:
- 15211:1521
- 55001:5500
environment:
- ORACLE_SID=ORCLCDB
- ORACLE_PDB=ORCLPDB1
- ORACLE_PWD=C@nn0ts@y1
- ORACLE_CHARACTERSET=AL32UTF8
db-2:
image: oracle/database:12.2.0.1-se2
ports:
- 15212:1521
- 55002:5500
environment:
- ORACLE_SID=ORCLCDB
- ORACLE_PDB=ORCLPDB1
- ORACLE_PWD=C@nn0ts@y1
- ORACLE_CHARACTERSET=AL32UTF8
As per the sample if i add the line volumes:
/home/oracle/oradata:/opt/oracle/oradata # persistent oracle database data. , there is an error creating the database and it stops.
what will be a better way for volumes to be added and if i need to create user and assign permissions to the account.
Most helpful comment
A Docker Compose sample file is now provide within the samples folder: 12102-docker-compose
As to the error mentioned above, this works as expected. When using Docker volumes Docker merely creates a folder outside the container with the typical characteristics of a Linux folder. That is, a new folder with read and execute permissions for everybody and write permission for the current user:
drwxr-xr-xAs Docker is running underrootthe folder is owned by the userrootand the grouproot.Oracle Database inside the container is run by the
oracleuser under thedbagroup. In order for the database to write the database files to disk it needs permissions on the Linux folder it should write those files into. Unfortunately, by default, that is not guaranteed by Docker.