Nice ideas for reducing container size
-
Multi-stage builds can go a long way - been beating this drum for a minute because it's pretty easy to do. That's a great article in general on the topic though. Also, docker-slim has come up before I think, which could be a useful tool. That said, the other key thing would be including less in the base image by default, but that is a longer conversation.
-
The way I think about it, the images are optimized for developer time and admin time as opposed to the size. You can have ultra-minimal alpine based images for sure but if you want to debug anything, none of the tools you want are there and it's just a pain to debug. These days 10GB extra is not that much compared to developer time. Atleast, this is what we optimize for.
-
@girish
I can understand the development time optimization, but is that something we can have if the basic image is still ubuntu but add more lvl?
with Gitlab CI image building can be automated, and this will also improve security, due to easier update and that means more frequent update.Now when we install a Cloudron, we install all the dependencies even if we will never use them.
Splitting the base image into multiple ones can offer the same developer-oriented view, and improve efficiency in size.
And another improvement can be that not all services are started if not used by a container, if what I'm doing is just hosting 1 WordPress, I don't need mongo or psql.
Obviously, this is my personal idea on docker environment and I can understand that you have your workflow, and its base on a single docker image, that for you know is easier to manage.
-
Notably, because most cloudron apps are built from the same base ubuntu image, the storage cost for the base image is only paid once for the whole server. Basically, after you install your first app, all the other apps get the easy development and debuggability that comes from building off of a full ubuntu for free. Hat tip to the design of docker layers.
In fact, this "giga image with all common deps"-design might consume less space than if you used fancy multi-stage builds to "compactify" the size of each individual app because the compaction comes at the cost of lost sharing which may be a net negative for the system as a whole. (Whether that's true in any particular case will depend on the apps you install; ymmv etc etc. The key is that all the apps really need to be running off of the same base image to get this benefit. By the way, if you're a dev just build off the official cloudron base image, its easier and actually consumes less storage.)
the images are optimized for developer time and admin time as opposed to the size
Choosing to optimize for dev/admin time is hands-down my favorite part of Cloudron. Between this and the sharing argument I made above it would take a lot of real image storage waste (i.e. don't be fooled by what
docker images
says, that doesn't account for shared layers) to get my vote for compacting app images. -
Just to put my money where my mouth is, here is a formatted view of
docker system df -v
from one of my cloudrons which shows for each image what its "size", "shared size", and "unique size" is (I hope fits nicely):REPOSITORY SIZE SHARED SIZE UNIQUE SIZE cloudron/org.navidrome.cloudronapp 2.212GB 2.176GB 36MB cloudron/im.riot.cloudronapp 2.223GB 2.176GB 47MB cloudron/com.github.bitwardenrs 3.286GB 2.176GB 1110MB cloudron/org.matrix.synapse 2.555GB 2.176GB 379MB cloudron/org.jupyter.cloudronapp 3.358GB 2.176GB 1183MB cloudron/io.gitea.cloudronapp 2.326GB 2.176GB 150MB cloudron/github.pages.cloudronapp 2.286GB 2.176GB 109MB cloudron/net.minecraft.cloudronapp 2.723GB 2.176GB 547MB cloudron/org.fireflyiii.cloudronapp 3.269GB 2.176GB 1093MB cloudron/com.docker.registry 2.284GB 2.176GB 108MB cloudron/mail 2.844GB 2.176GB 668MB cloudron/sftp 2.194GB 2.176GB 18MB cloudron/io.minio.cloudronapp 2.236GB 2.176GB 59MB cloudron/org.freshrss.cloudronapp 2.184GB 2.176GB 8MB cloudron/postgresql 2.343GB 2.176GB 167MB cloudron/net.roundcube.cloudronapp 2.239GB 2.176GB 63MB infogulch/promnesia-app 2.224GB 2.176GB 48MB cloudron/graphite 2.246GB 2.176GB 70MB cloudron/turn 2.182GB 2.176GB 5MB cloudron/com.electerious.lychee.cloudronapp 2.248GB 2.176GB 72MB cloudron/mysql 2.495GB 2.176GB 318MB cloudron/redis 2.182GB 2.176GB 6MB cloudron/mongodb 2.299GB 2.176GB 122MB infogulch/terminusdb-app 3.331GB 2.176GB 1155MB cloudron/org.radicale.cloudronapp2 2.187GB 2.176GB 11MB cloudron/base 2.176GB 2.176GB 0B
You might notice that the "size" of every image is at least 2.1GB, but that 2.1 GB is shared between all the apps (namely, cloudron/base) because they all use the same base image. And I don't see any world where I wouldn't pay 2.1 GB to have every one of my images be useably-debuggable in case I needed it.
All this said, there may still be opportunities to reduce image sizes by using multi-stage builds to only copy release files (and not source code) to the final image -- but there's no reason for that final image to not be based on cloudron/base.
-
@infogulch said in Nice ideas for reducing container size:
but there's no reason for that final image to not be based on cloudron/base.
That is exactly how I see it as well. Since it's shared it does not matter that much that it's quite big itself.
One should however check why that bitwarden image is so big. That seems pretty excessive.
-
@infogulch said in Nice ideas for reducing container size:
paid once for the whole server
To be fair, you will get the same footprint with a multi-stage build and images that depend on the same shared base.
Let say that we will have a CloudronBase (Image LVL1), this image will include only ubuntu + minim software used for debugging.
As a second step you will get different images with all the dependencies for the different cases:
One image for every type of DB: MariaDB, pSQL, MongoDB.
One for the webservers: Nginx, and Apache (that can maybe already include PHP).Then as the last level (3) of images, we have the language, like: node, python, etc, etc.
This will have the same footprint as the one big image that we have now, it will always be a Cloudron Base, but it will be like:
cloudronbase/nginx-node
cloudronbase/mariadbYes to slit the image in multiple parts will be a big work, but then we can update all the lvl with less effort.
And as a second bonus, we will be able to have a server with just 2 WordPress, without unused library and software.To resume, what I propose is to keep the idea of an cloudron base, but to slit it, so that the apps can be developed easily, but servers with 20 GB of storage don't louse 10% of their space for code that they will never use.