├── .github └── FUNDING.yml ├── .gitignore ├── Dockerfile ├── LICENSE ├── README.md ├── files └── .gitkeep └── scripts ├── install-sqlcl.sh └── start-container.sh /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: martindsouza 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | files/*.zip -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Original source from https://github.com/lucassampsouza/ords_apex 2 | FROM openjdk:8-jre-alpine 3 | LABEL maintainer="Martin DSouza " 4 | 5 | ENV TZ="GMT" \ 6 | SQLCL_DIR="/usr/local/sqlcl" \ 7 | SQLCL_BIN_NAME="sqlcl" \ 8 | PATH="/usr/local/sqlcl/bin:${PATH}" \ 9 | SQLPATH="/oracle/" \ 10 | # #12 Fixes issue with 20.2 11 | LANG="en_US.utf8" 12 | 13 | COPY ["files/sqlcl-*.zip", "scripts/*", "/tmp/"] 14 | 15 | # This is a dummy volume to reference user's custom scripts 16 | # /sqlcl: For use of pwd 17 | # /oracle: to reference login.sql and sqlcl aliases 18 | VOLUME ["/sqlcl","/oracle"] 19 | WORKDIR "/sqlcl" 20 | 21 | RUN echo "" && \ 22 | chmod +x /tmp/install-sqlcl.sh && \ 23 | chmod +x /tmp/start-container.sh && \ 24 | apk update && \ 25 | apk upgrade && \ 26 | # bash is required by sqlcl 27 | apk add bash && \ 28 | # for tput which is required by sqlcl 29 | apk add ncurses && \ 30 | /tmp/install-sqlcl.sh && \ 31 | # debug 32 | # apk add ncurses 33 | echo "" 34 | 35 | # #9: Used to be just sqlcl but caused an issue when $TNS_ADMIN was not set 36 | # ENTRYPOINT ["sqlcl"] 37 | ENTRYPOINT ["/tmp/start-container.sh"] 38 | CMD ["/nolog"] 39 | 40 | # debug 41 | # ENTRYPOINT [ "/bin/ash" ] -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Martin Giffy D'Souza 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Oracle SQLcl Docker Image 2 | 3 | - [Build Image](#build-image) 4 | - [Run](#run) 5 | - [Volumes](#volumes) 6 | - [`/oracle/` Folder](#oracle-folder) 7 | - [`login.sql`](#loginsql) 8 | - [Aliases](#aliases) 9 | - [Oracle Wallet / Oracle OCI ATP](#oracle-wallet--oracle-oci-atp) 10 | 11 | 12 | ## Build Image 13 | 14 | [Download Oracle SQLcl](http://www.oracle.com/technetwork/developer-tools/sqlcl/downloads/index.html) 15 | 16 | ```bash 17 | git clone https://github.com/martindsouza/docker-oracle-sqlcl 18 | cd docker-oracle-sqlcl 19 | 20 | # *** Copy the downloaded sqlcl.zip file into the files directory *** 21 | cp ~/Downloads/sqlcl-.*.zip files/ 22 | 23 | # Build the image 24 | docker build \ 25 | -t oracle-sqlcl:20.2.0 \ 26 | -t oracle-sqlcl:latest \ 27 | . 28 | ``` 29 | 30 | ## Run 31 | 32 | The following is focused on MacOS / Linux users. 33 | 34 | - Create alias 35 | - *Note: the wrapping single quotes `'` instead of a double quote `"` which prevents `pwd` from being evaluated during the alias definition* 36 | 37 | ```bash 38 | alias sqlcl='docker run -it --rm \ 39 | --network="host" \ 40 | -v `pwd`:/sqlcl \ 41 | -v ~/Documents/Oracle/:/oracle \ 42 | -e TNS_ADMIN=$TNS_ADMIN \ 43 | oracle-sqlcl:latest' 44 | ``` 45 | 46 | To persist add the `alias` command to `~/.bash_profile`. If using [zsh](https://ohmyz.sh/) then add to `~/.zshrc`. 47 | 48 | A few things about the parameters: 49 | 50 | 51 | Parameter | Description 52 | ---------|---------- 53 | `--network="host"` | This will mimic the current host networking (with the goal of acting like a binary) 54 | `-v ``pwd``:/sqlcl` | This will set the current directory that `sqlcl` is run to the one that the container is looking at 55 | `-v ~/Documents/Oracle/:/oracle` | _(optional)_ for `login.sql` to load startup scripts 56 | 57 | - To execute: `sqlcl ` 58 | 59 | 60 | **Note:** For the `` it usually looks something like `sqlcl giffy/giffy@localhost:32118/xepdb1`. If you're referencing a port that is being tunneled by host machine (i.e. laptop) `localhost` doesn't seem to work. Instead use `host.docker.internal` to reference the host machine. Ex: `sqlcl giffy/giffy@host.docker.internal:32118/xepdb1`. 61 | 62 | ## Volumes 63 | 64 | Volume | Description 65 | ---------|---------- 66 | `/sqlcl` | This is the folder that SQLcl will reference 67 | `/oracle` | This is the folder that you will put `login.sql` and can load `alias` from here. Ex: `alias load /oracle/sqlcl-alias.xml`. Note the reference is to the container's local `/oracle` folder and not your full path. 68 | 69 | 70 | ## `/oracle/` Folder 71 | 72 | The container has a mapped volume called `/oracle/`. In it you can add files for SQLcl to reference. The listings below cover each type of file. 73 | 74 | ### `login.sql` 75 | 76 | `login.sql` allows you to store commands that you'd like SQLcl to run on init. An example is: 77 | 78 | ```sql 79 | -- Add a reminder where to find this file on your laptop 80 | -- Again in the Container it's mapped to /oracle/login.sql 81 | prompt Settings in ~/Documents/Oracle/login.sql 82 | prompt Remember this is in a Container and all referenced files must be from Containers point of view 83 | 84 | set serveroutput on 85 | set sqlformat ansiconsole 86 | 87 | -- Alias will be covered below 88 | prompt To manage aliases: ~/Documents/Oracle/sqlcl-alias.xml 89 | alias load /oracle/sqlcl-alias.xml 90 | ``` 91 | 92 | ### Aliases 93 | 94 | SQLcl allow for aliases (not to be confused with Bash based aliases). Theres' lots of great examples on how to use them and one of the better ones is found [here](https://mikesmithers.wordpress.com/2019/06/25/sqlcl-alias-because-you-cant-remember-everything/). 95 | 96 | To load an alias see the previous `login.sql` file example. You should store aliases in the same folder as `login.sql` as it is all mapped to the `/oracle/` folder in the Container 97 | 98 | ### Oracle Wallet / Oracle OCI ATP 99 | 100 | When connecting to an Oracle Cloud (OCI) Autonomous Transaction Processing (ATP) database you'll need to reference a folder that contains the wallet information provided by the ATP instance [docs](https://docs.cloud.oracle.com/iaas/Content/Database/Tasks/adbconnecting.htm). 101 | 102 | In the examples above we've mapped `~/Documents/Oracle/` (laptop) to `/oracle` (container) volume. To handle the OCI wallet requirement do the following. 103 | 104 | On your laptop: 105 | 106 | - Put the wallet files in `~/Documents/Oracle/wallets/atp01` (where `atp01` is the folder container the wallet files for a given ATP instance. Note that the folder name is entirely what you want to call it) 107 | - Set the `TNS_ADMIN` variable. **This needs to be how the container will reference the folder**. In this example it would be: `TNS_ADMIN=/oracle/wallets/atp01` 108 | - Connect to the ATP instance using the `sqlcl` alias. 109 | 110 | Full example: 111 | 112 | ```bash 113 | TNS_ADMIN=/oracle/wallets/atp01 114 | sqlcl admin/myatp_password@atp01_high 115 | 116 | SQL> 117 | ``` 118 | 119 | #### Updating `sqlnet.ora` file 120 | When you try to run `sqlcl` using the Oracle Wallet you may get the error `ORA-28759: failure to open file` (see [#13](https://github.com/martindsouza/docker-oracle-sqlcl/issues/13) for more info). This is because of a mapping in the `sqlnet.ora` file that is provided with it. *Note in our example `sqlnet.ora` would be in the unzipped file: `~/Documents/Oracle/wallets/atp01/sqlnet.ora`* You need to change the following in the file: 121 | 122 | From: `?/network/admin` 123 | To: `$TNS_ADMIN` 124 | 125 | You can also script this using `sed`: 126 | 127 | ```bash 128 | sed -i .bak "s|?/network/admin|\$TNS_ADMIN|g" $TNS_ADMIN/sqlnet.ora 129 | ``` 130 | 131 | You only need to change this once -------------------------------------------------------------------------------- /files/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/martindsouza/docker-oracle-sqlcl/6db15b6fe37beb5a2336949150e80a8537364dfc/files/.gitkeep -------------------------------------------------------------------------------- /scripts/install-sqlcl.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ash 2 | 3 | mkdir $SQLCL_DIR 4 | 5 | cd /tmp 6 | 7 | unzip sqlcl*.zip 8 | # Cleanup 9 | rm -rf sqlcl*.zip 10 | 11 | # The unzip will create a folder like: sqlcl 12 | cd sqlcl 13 | 14 | # Rename sql binary if provided 15 | # Not required anymore since binary has now been renamed to sqlcl 16 | if [ ! -z "$SQLCL_BIN_NAME" ]; then 17 | mv bin/sql bin/$SQLCL_BIN_NAME 18 | fi 19 | 20 | mv * $SQLCL_DIR 21 | 22 | -------------------------------------------------------------------------------- /scripts/start-container.sh: -------------------------------------------------------------------------------- 1 | #!/bin/ash 2 | # #9: Unset TNS_ADMIN as causing issue if defined but has no value 3 | if [ -z "$TNS_ADMIN" ]; then 4 | echo "warning: \$TNS_ADMIN is empty, unsetting it" 5 | unset TNS_ADMIN 6 | else 7 | echo "TNS_ADMIN: $TNS_ADMIN" 8 | fi 9 | 10 | # Call SQLcl with all the parameters used when calling sqlcl 11 | sqlcl "$@" --------------------------------------------------------------------------------