This repository contains some basic examples you can use to learn about containers and InterSystems IRIS.
Based on: https://github.com/intersystems/Samples-Containers-Bootcamp by Kerry Kirkham
- Git
- Docker (if you are using Windows, make sure you set your Docker installation to use "Linux containers").
- Docker Compose
- Visual Studio Code + InterSystems ObjectScript VSCode Extension
Have a look at the Overview. Docker Architecture.
- (a.1) Create and start a new temporary BusyBox container. If you do not have the BusyBox image locally already, Docker will download it first:
docker run --rm busybox echo 'hello world'
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
8ec32b265e94: Pull complete
Digest: sha256:b37dd066f59a4961024cf4bed74cae5e68ac26b48807292bd12198afa3ecb778
Status: Downloaded newer image for busybox:latest
hello world
- (a.2) Create and start a new BusyBox container. Include a ping to see that it is running and accessible. Press Ctrl+C after a few pings to stop the process and exit the container.
docker container run busybox ping 8.8.4.4
PING 8.8.4.4 (8.8.4.4): 56 data bytes
64 bytes from 8.8.4.4: seq=0 ttl=37 time=16.385 ms
64 bytes from 8.8.4.4: seq=1 ttl=37 time=13.981 ms
64 bytes from 8.8.4.4: seq=2 ttl=37 time=12.899 ms
64 bytes from 8.8.4.4: seq=3 ttl=37 time=14.085 ms
- (a.3) Create a second container, this time, in detached mode. Docker displays a long, hexadecimal number; this is the full container ID of your new container. This container is now running detached, which means it is running as a background process. Thus, it is not printing the ping results to your terminal.
docker container run --detach busybox ping 8.8.4.4
ac4765e9c91f277dc6b790ea92923993a72577031b2540e93af434c480e95370
- (b.1) To see all of your running containers, you can run the command below. It includes useful information, such as the container name and ID and the image name. If you do not provide a name when initializing the container, Docker generates a random name.
docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ac4765e9c91f busybox "ping 8.8.4.4" 2 minutes ago Up 2 minutes gracious_varahamihira
- (b.2) This command, however, only shows you the containers you have running. To see all containers, running or stopped, run the command below:
docker container ls --all
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ac4765e9c91f busybox "ping 8.8.4.4" 5 minutes ago Up 5 minutes gracious_varahamihira
40c84ca44b94 busybox "ping 8.8.4.4" 6 minutes ago Exited (0) 6 minutes ago condescending_maxwell
- (b.3) You will notice that the temporary BusyBox container from previous example is shown here, with a status of Exited. You can remove this container with the docker rm command. In the command below, replace with the ID of your exited container. Note: You can typically just provide the first few characters of the container ID here.
docker container rm 40c8
40c8
- (b.4) With this command, you cannot directly remove a running container, only a stopped one. To learn more about the rm command and your options for forcing the removal of a running container, enter the help command below.
docker container rm --help
Usage: docker container rm [OPTIONS] CONTAINER [CONTAINER...]
Remove one or more containers
Options:
-f, --force Force the removal of a running container (uses SIGKILL)
-l, --link Remove the specified link
-v, --volumes Remove anonymous volumes associated with the container
- (b.5) As you can see, adding --force will force the removal of a running container. Run a forced removal on your active BusyBox container, replacing with the first few characters from the ID of your container.
docker container rm --force ac47
ac47
- (b.6) The --help option can be applied to most commands within Docker if you want to see more information. Take a look at the options for the ls command by viewing the information under help.
docker container ls --help
Usage: docker container ls [OPTIONS]
List containers
Aliases:
ls, ps, list
Options:
-a, --all Show all containers (default shows just running)
-f, --filter filter Filter output based on conditions provided
--format string Pretty-print containers using a Go template
-n, --last int Show n last created containers (includes all states) (default -1)
-l, --latest Show the latest created container (includes all states)
--no-trunc Don't truncate output
-q, --quiet Only display container IDs
-s, --size Display total file sizes
- (b.7) You can play around with some of these options for listing containers. For instance, you can list all containers — both started and stopped — by only their numeric IDs:
docker container ls --all --quiet
- (b.8) You can also kill all containers, regardless of what state they are in. Important!: If you already had containers on your machine before this lab, carefully remove this workshop containers individually using their IDs.
docker container rm -–force $(docker container ls --quiet --all)
- (c.1) Create another container using the BusyBox image, and connect to its shell in interactive mode. You can do this by using the -i flag (as well as the -t flag, which requests a TTY connection).
docker container run -it busybox sh
/ #
- (c.2) From here, you can explore your container's file system using the ls command.
/ # ls -l
total 36
drwxr-xr-x 2 root root 12288 Aug 20 16:21 bin
drwxr-xr-x 5 root root 360 Aug 24 06:56 dev
drwxr-xr-x 1 root root 4096 Aug 24 06:56 etc
drwxr-xr-x 2 nobody nobody 4096 Aug 20 16:21 home
dr-xr-xr-x 200 root root 0 Aug 24 06:56 proc
drwx------ 1 root root 4096 Aug 24 06:56 root
dr-xr-xr-x 13 root root 0 Aug 24 06:56 sys
drwxrwxrwt 2 root root 4096 Aug 20 16:21 tmp
drwxr-xr-x 3 root root 4096 Aug 20 16:21 usr
drwxr-xr-x 4 root root 4096 Aug 20 16:21 var
- (c.3) Create a new text file
echo 'Hello there…' > test.txt
-
(c.4) List your files again to see that a text file has been created.
-
(c.5) Exit your container
/ # exit
- (c.6) Run the same command as before to start another container from the same image.
docker container run -it busybox sh
- (c.7) Try to find your test.txt file inside this new container via the ls -l command. You will see that it is nowhere to be found. Exit this container.
/ # exit
- (d.1) Run another new BusyBox container and drop it into a shell on that container.
docker run -it busybox sh
- (d.2) Create an empty file on this container.
/ # touch myfile.test
- (d.3) List your files to confirm that myfile.test has been created.
/ # ls -l
- (d.4) Exit your container
/ # exit
- (d.5) List all of your containers, but this time use the ps – or process status – command. It works the same as docker container ls and is often a shorthand choice.
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- (d.6) Notice that this only shows your running containers. Add the -a tag to see all containers, both running and stopped. Note that your results may not look exactly like the provided screenshot, but they should look similar.
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
238c8c81b9dd busybox "sh" 3 minutes ago Exited (0) 48 seconds ago hopeful_almeida
0cb20705b4fb busybox "sh" 18 minutes ago Exited (0) 7 minutes ago modest_euler
- (d.7) You will use the diff command to see what has changed about a container relative to its image. To do this, use the ID of your most recent container in the command below to see the difference between the container and its base image. The results of this command show you information about what has changed. Lines that begin with an A show that a file or directory was added. Lines beginning with a C show that a file or directory was changed. Though none are present in this example, lines beginning with a D would indicate that a file or directory was deleted.
docker container diff 238c
A /myfile.test
C /root
A /root/.ash_history
- (d.8) When you created myfile.test, you wrote information to the container's read/write layer. Now, you are going to save that read/write layer as a new read-only image layer. With this, you will create a new container image that reflects the additions you made. You can do this with the commit command, where myapp is the new image name and 1.0 is the image tag.
docker commit 238c myapp:1.0
sha256:745039f37ffad3de9b51ef1177485e3c37077bb78164b75dd13b4b5622aaaba4
- (d.9) Verify that your new image has been created by listing all of your images.
docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
myapp 1.0 745039f37ffa About a minute ago 1.24MB
busybox latest 42b97d3c2ae9 3 days ago 1.24MB
- (e.1) You are going to build a node application in a image based on a Dockerfile, so you can later run a container with it. Examine the contents of node-app/Dockerfile and node-app/server.js. Notice the base image that is used in the Dockerfile.
docker build -t service:v1 node-app
[+] Building 10.5s (8/8) FINISHED
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 37B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/node:10-slim 2.2s
=> [auth] library/node:pull token for registry-1.docker.io 0.0s
=> [internal] load build context 0.0s
=> => transferring context: 31B 0.0s
=> [1/2] FROM docker.io/library/node:10-slim@sha256:88932859e3d022d79161b99628c4c2c50e836437455e2d1b1a008d98367b10d6 7.7s
=> => resolve docker.io/library/node:10-slim@sha256:88932859e3d022d79161b99628c4c2c50e836437455e2d1b1a008d98367b10d6 0.0s
=> => sha256:88932859e3d022d79161b99628c4c2c50e836437455e2d1b1a008d98367b10d6 776B / 776B 0.0s
=> => sha256:64c30c91d628d40eb8f772ee1477f78aff820e317e8afbc5160857ee804e4b70 1.37kB / 1.37kB 0.0s
=> => sha256:6fbcbbb5c6032ce4013d4c736ffe54e0764c36fa14315ae54cb51f244e813c52 7.09kB / 7.09kB 0.0s
=> => sha256:62deabe7a6db312ed773ccd640cd7cfbf51c22bf466886345684558f1036e358 22.53MB / 22.53MB 4.2s
=> => sha256:f698164f6049bead44aeb7590e88d3df323011c20f0cedbff3d86f62e4c9f184 4.17kB / 4.17kB 0.4s
=> => sha256:bc29352cb629712e7fbce7227a16b53308b541ef41e19122a04c15646756b176 21.91MB / 21.91MB 4.9s
=> => sha256:85e84b4c858fae373ccdf48432de781210efb7fd75d9d801be9917577fe6ca09 2.93MB / 2.93MB 2.7s
=> => sha256:ac72e4359589952a2e38fbe10287d792cbb57f2ec3cd1eb730e9bab685ac9754 295B / 295B 2.9s
=> => extracting sha256:62deabe7a6db312ed773ccd640cd7cfbf51c22bf466886345684558f1036e358 1.3s
=> => extracting sha256:f698164f6049bead44aeb7590e88d3df323011c20f0cedbff3d86f62e4c9f184 0.1s
=> => extracting sha256:bc29352cb629712e7fbce7227a16b53308b541ef41e19122a04c15646756b176 1.5s
=> => extracting sha256:85e84b4c858fae373ccdf48432de781210efb7fd75d9d801be9917577fe6ca09 0.2s
=> => extracting sha256:ac72e4359589952a2e38fbe10287d792cbb57f2ec3cd1eb730e9bab685ac9754 0.0s
=> [2/2] COPY server.js . 0.4s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:97c94d88893b66d3a26c5bc316c67efe8ffc5cbad24aa5ab6163ac276cc3803f 0.0s
=> => naming to docker.io/library/service:v1
(e.2) By reviewing your images again, you will see that your new container image has been created.
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
service v1 97c94d88893b 5 minutes ago 134MB
(e.3) Using the docker history command, you can look at the history of a given image. Run the command below to look at the history of the new service:v1 image you have created.
docker history service:v1
- (f.1) Look at your list of all containers, both running and stopped.
docker ps -a
- (f.2) Stop and remove all of the containers you have created to this point, so that the previously assigned ports are made available again. You can do this in batches by using the two commands below — these commands stop and remove the set of containers returned by the ps -aq command in parentheses. Important!: If you already had containers on your machine before this lab, you should carefully remove the containers individually using their IDs.
docker stop $(docker ps -aq)
docker rm $(docker ps -aq)
- (g.1) This command runs the container from the service:v1 image in detached mode, names it myservice, and exposes the container's port 8080 on your host machine as port 8080. The written output is again your full container ID.
docker run -d --name myservice -p 8080:8080 service:v1
1cca730b6f8588a6f213d04a549cf395eefa9ccfda4c2d13039b7c61739b8310
- (g.2) Run docker ps again to see that your new container is running
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1cca730b6f85 service:v1 "docker-entrypoint.s…" 16 seconds ago Up 14 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp myservice
- (g.3) By running the curl command below, you can verify that this container is, indeed, running the application that you created in your server.js file (you can use also your regular web browser)
curl http://127.0.0.1:8080
Hello World!
- (g.4) You also have the ability to inspect the resource usage statistics associated with your container. To do this, use the docker stats command.
docker stats myservice
- (g.5) Stop your container using the docker stop command. This time, since you provided a name to your container, you can use its name instead of its ID.
docker stop myservice
myservice
- (g.6) Remove your container with the docker rm command.
docker rm myservice
myservice
Bind mounts will map a local file or directory from your host filesystem to a container. It can be used to share files between the host and containers.
- (h.1) Run the following command to start a BusyBox container with a bind mount. This command specifies the directory of the bind mount on the host file system and mounts that directory into the mydata directory of the container file system.
docker run -it --name mytest -v $PWD/mydata:/mydata busybox
- (h.2) At this point, you are in a bash shell at the container level. Run the following commands to enter your mydata directory, add a file, and then exit the bash shell.
docker run -it --name mytest -v $PWD/mydata:/mydata busybox
/ # ls
bin dev etc home mydata proc root sys tmp usr var
/ # cd mydata
/mydata # touch myfile.txt
/mydata # exit
- (h.3) Use the docker inspect command to verify that the bind mount was created correctly in your mytest container. Observe the Mounts section of the output.
docker inspect mytest
- (h.4) Remove all of your containers. Important!: If you already had containers on your machine before this lab, you should carefully remove the containers individually using their IDs.
docker container rm -f $(docker container ls -aq)
- (h.6) Verify your myfile.txt file still exists in the mydata folder on the host machine.
Using volumes will allow you to specify that the containers you are running will persist data in a filesystem section that is managed by Docker (e.g. /var/lib/docker/volumes
). It can be used to share data between containers.
- (i.1) Create a new volume in Docker called demovol.
docker volume create demovol
- (i.2) Inspect the volume you have just created
docker volume inspect demovol
- (i.3) Enter this command to run a container with the demovol volume mounted, and then open a shell on that container.
docker container run -it -v demovol:/demo busybox sh
- (i.4) Run the ls command to list your file system.
/ # ls
bin demo dev etc home proc root sys tmp usr var
- (j.1) Add a file to your demovol volume. Use the command below to create and store mydata.dat inside the demo folder.
/ # echo 'my data' > /demo/mydata.dat
- (j.2) Exit the bash shell of this container.
/ # exit
- (k.1) Obtain the ID of the container you created in before, and then delete this container
docker container rm 5ed5
5ed5
- (k.2) Start a new container, once again using demovol as the mounted volume. This demonstrates the ability to have a persistent data source that can be used across multiple containers.
docker container run -d -v demovol:/demo busybox ping 8.8.8.8
1b5f7d8196ede9da7dc35fc8902f20f33817c70c5971289d6261b533ecbcad71
- (k.3) Obtain the new ID of this container (by using docker ps or docker container ls), and then use the ID to open a shell on the container.
docker container exec -it 1b5f sh
- (k.4) Run the cat command below to read and print the contents of your mydata.dat file. Notice that the file, now from within this new container, is still accessible as it was before.
/ # cat /demo/mydata.dat
my data
Instead of using docker commands, you can use docker-compose
which is a tool for defining and running multi-container applications based on simple YAML configuration files.
-
(l.1) Have a look at docker-compose.yml. Try to figure out what means each section.
-
(l.2) Run an InterSystems IRIS container using the docker-compose.yml configuration in a detached mode. If you are running Docker on Windows please, un-comment the
command
section to avoid errors with the checking of Linux capabilities.
docker-compose up -d
Creating network "workshop-containers_default" with the default driver
Creating irishealth ... done
- (l.3) Have a look at the IRIS container logs:
docker logs irishealth
[INFO] Starting ISC Agent with command "/home/irisowner/irissys/startISCAgent.sh 2188"
Writing status to file: /home/irisowner/irissys/iscagent.status
Reading configuration from file: /home/irisowner/irissys/iscagent.conf
ISCAgent[16]: Starting
ISCAgent[18]: Starting ApplicationServer on *:2188
[INFO] Starting InterSystems IRIS instance IRIS...
[INFO] This copy of InterSystems IRIS has been licensed for use exclusively by:
InterSystems IRIS Community
Copyright (c) 1986-2021 by InterSystems Corporation
Any other use is a violation of your license agreement
Starting IRIS
08/24/21-08:47:25:943 (390) 0 [Generic.Event] Global buffer setting requires attention. Auto-selected 25% of total memory.
08/24/21-08:47:26:012 (390) 0 [Generic.Event] Allocated 4681MB shared memory: 4002MB global buffers, 300MB routine buffers
08/24/21-08:47:26:013 (390) 0 [Crypto.IntelSandyBridgeAESNI] Intel Sandy Bridge AES-NI instructions detected.
08/24/21-08:47:26:126 (390) 0 [WriteDaemon.UsingWIJFile] Using WIJ file: /usr/irissys/mgr/IRIS.WIJ
-
(l.4) Access the IRIS Management Portal at http://localhost:52773/csp/sys/UtilHome.csp. Log-in using default
superuser
/SYS
password account. You will be asked to change the password. -
(l.5) Access IRIS using Terminal
docker exec -it irishealth bash
irisowner@1281cd6efb0c:~$ iris session iris
Node: 1281cd6efb0c, Instance: IRIS
USER>
- (l.6) Stop your IRIS container
docker-compose down
Removing irishealth ... done
Removing network workshop-containers_default
Durable %SYS ensures you can persist instance-specific data for containerized instances of InterSystems IRIS on durable storage.
-
(m.1) Edit docker-compose.yml and un-comment the
environment
section. This will enable durable %SYS in the IRIS instance, storing the configuration data inshared/durable
. -
(m.2) Run again the steps in the previous example and notice the changes in
shared/durable
.