Technical Articles
A novice experiences with containers
Introduction
I recently worked quite a bit with containers to prepare CAA309 for teched las vegas. Prior to that my experience with containers was limited to running an ABAP trial instance on my laptop using Jakub Filak’s scripts (Btw, I just released my own)
In case you’re wondering, a container is a group of processes isolated from the others, so that it looks almost like its own virtual machine. Uses much less resources (when idle my ABAP trial uses about 1 gb of RAM vs 4 or more for a VM running it) and is very quick to start/stop/create/destroy/backup
Why
As far as I know SAP doesn’t support running netweaver in containers, but does work and with a simple command line one can start a container which is an exact replica of the last time a snapshot was taken. On my laptop takes around 10/15 minutes.
This has a lot of interesting use cases:
- Automated testing
- distributed development, using abapgit
- demos/training
Containers are traditionally an unix/linux thing
We do have windows containers now, but as far as I know trying to use containers on windows or mac is a bit like trying to use office on linux: mostly works but is a pain. As the title sais, I’m a novice and might be wrong
Docker images
A container is always created based on an image, which is like a blueprint of your system.
For instance, if I have an image called netweaver01 a command like:
docker run netweaver01
will
- create a new container with a random name like precious_linx
- start a new netweaver instance inside it
- copy the database or any other file that gets modified while running
You can repeat the process as many times as you want until you run out of memory. Or valid licences.
This will get a dynamic ip address, a dynamic mac address and a dynamic hardware key (except on my aws instance for some reason I can’t fathom), so you may want to use something a bit more elaborate like
docker run -d -h netweaver01 --dns-search abap.local--name netweaver_01 -p 3200:3200 -p 3300:3300 --stop-timeout 1200 --mac-address="01:22:aa:01:00:04" netweaver01 tini /usr/local/bin/startinstance
Which will allow you to access this instance as if it was run on the host, and provide a stable container name (netweaver_01) mac address and hardware ID
You can then start, stop and delete the container from the command line.
Creating the image
The best practice in a docker environment is to script the whole image creation in a Dockerfile
This is above my paygrade as a novice on both docker and SAP installations, mainly for 2 reasons:
- Netweaver wants a stable hostname, docker use a dynamic one which can’t be forced during installation (well, it can but only with some rather ugly hack)
- the installation must be unattended. I bet is easy enough if you know what you’re doing, but I’m a noob
So what I did was quite subpar but has one big advantage: it does work
- run a new container based on your favourite linux distribution, forcing the hostname you want to use
- create and run a script to make some small changes to /etc/hosts and /etc/resolv.conf
- start a regular, manual SAP installation
- when asked to connect with a browser, replace the hostname with the (temporary) IP of your container
- stop the instance
- create an image with docker commit
As said, this is much more manual than the best practice. If you can do better go ahead. But take note there are viable alternatives to the best practices
Persisting the data
Containers are supposed to be transient, and lots of tools will rather liberally create and destroy them at will.
As said before, by default a new container will create a copy of the database and then delete it when deleted. This is great for many use cases (demos, testing), but not for others (i.e. you might want to use containers for a rarely used dev or training system).
We can achieve this using volumes. A volume is a bit of permanent storage which you can mount to your container, and can easily be backed up or restored with tar files.
If your data needs to be persisted make sure it lives in a volume and not in the container