In a previous post I briefly mentioned using a more native docker approach for Rockons. In this thread I would like to go deeper into my train of thoughts and discuss any potential issues, shortcomings, oversights, etc. with the proposed approach.
Let’s start with what I gathered so far about the Rockons (please correct me if I’m wrong):
- A Rockon configuration is a JSON file with the needed parameters to start up a docker container for that application including data needed by the Rockon wizard
- Rockon configuration is taken apart, loaded into a wizard, and then stored in the database with the wizard input values in tables specific for volumes, container information, environment variables, labels, docker image, ports, etc.
Advantages I see to this approach:
- Easy to determine which ports are already in use by other Rockons
- If a docker container dies it can be easily recreated with the data in the database
- Possibly faster load times of the Rockon page since the info can just be pulled out of the database
- Easy to update docker configuration by updating the correct records in the correct tables
Drawbacks I see to this approach:
- Keeping the data between the database and docker container in sync might be more difficult
– This might possibly attribute to bugs like this:
— Custom Rockon perpetually uninstalling
— Rockon Openvpn never finishes install
- “Power-users” who install docker containers manually cannot see/manage them through the Rockstor UI
- Status of the Rockon in the UI might not always be in line with status of the actual docker container
- Complex database structure which needs to be maintained
To mitigate some of these drawbacks and serve power-users better, a more native docker approach might be a solution. I saw in the source-code that there is already a good basis for it, but not all functionality is used at this moment.
To all readers: I am not suggesting that Rockstor becomes a docker manager like Portainer or Yacht! You can install those apps in a docker container if you really want fine-grained docker management. I am suggesting a light-weight implementation just to manage the basics.
Having said that, below is the approach I had in mind. I realize I do now know the ins-and-outs of Rockstor nor Rockons at all, so excuse my ignorance on the matter.
Storing docker information:
Since the Rockons are basically docker configuration files in JSON format, they (or a variant of them) can be stored in the database as a blob alongside the Rockon’s identifying name, display name, description and public port, instead of pulling it apart into different tables. Containers and their status can be retrieved using “docker ps” or “docker container ls” with the “-a” option to also see the stopped containers. The identifying name can be used to issue docker commands and identify the matching database entry given the container was created by using the “–name” option set to the identifying name. This way the database can be queried for the display name, description and public port needed in the UI.
For containers that were added by power-users and therefore are not in the database, docker’s random given container name can be shown and the description left empty. If power-users want a display name, they can set one themselves using the “–name” option.
Editing the configuration:
When editting the configuration (wrench icon) and changing the values in the wizard, the JSON configuration blob can be queried from the database, updated accordingly, and stored back into the database. The configuration can then be used to start up the new container in the same way you would when installing a Rockon. For containers that are not installed via Rockons the configuration icon can be disabled and options limitted to starting, stopping and removal of the container. Possibly a message can be shown to indicate that this is a container not managed by Rockstor.
Starting and stopping of Rockons:
“docker start [container name]” and “docker stop [container name]” can be used to respectively start and stop the containers. If the command returns the container name the action was completed successfully.
Removing a Rockon:
This is quite easy. Stop the container, remove it and then remove the table entry containing the identifying name, pretty name, description and JSON configuration blob from the database. No complex table structures to clean up.
Opening the container’s URL (clicking the “xxxx UI” button):
This one is a bit more tricky. For the containers managed by Rockstor (Rockons), the public port can be querried from the database. For power-users that added their container manually, it’s a bit of a guess which port is the one to use. It would be possible to use "docker container inspect " to retrieve the “Config > ExposedPorts” and match that up with “NetworkSettings > Ports” to figure out which port is the public port. However, if there are multiple exposed ports it’s still a guess as to which one to use. Also, having to pull the inspect configuration and matching up ports, might cause long load times in the UI. Instead a dropdown or multiple buttons with the mapped ports (which can easily be retrieved using the “docker container ls” command) could be shown. The power-users can take it from there. Or even easier: don’t show a UI button at all.
Preventing port conflicts:
As described above the “docker container ls” command can be used to extract port information from a container. This can then also be used to check which ports are used and which are not so that newly installed Rockons do not conflict with existing ones. Note, however, that if a new port needs to be used because the original port is already in use, this will also need to be updated in the Rockon JSON configuration blob in the database so that port numbers stay consistent after container updates.
Should the above be implemented it will not have an impact on the Rockon JSON files in the Rockon repository, but it will require an extensive database migration since all data in the Rockon tables would need to be consolidated into a single JSON configuration blob.
I know that a lot of things I listed here are already done as described or at least close to it. I just added them here for completeness’ sake. Please let me know your insights and thoughts on the matter.