As of 5:00pm today, April 26th 2021, the Singularity Hub cloud space, including storage of over 9TB of containers, a registry server and builders maintained by me (and literally only me) since 2016, is shut off. Before you worry, we’ve migrated all the existing containers (before the 19th of this month) to an archive so they will continue to be pullable at their previous URLs, something I’ll discuss briefly later in this post. For now, let’s take a few moments to appreciate the server previously known as Singularity Hub, now known as Singularity Hub archive.
If you have hosted containers on Singularity Hub, you primarily should know that they will continue to be pullable from the archive, however you won’t be able to build new containers. You should disable the previous webhook in your GitHub repositories, an oversight I realized after I revoked all the GitHub tokens for the integration. If you added a Singularity Hub Badge to your repository, I’ve also generated a newly linked one that you can use as follows (see the gist for the markdown):
For the complete details and other options for building containers, you should read the initial news post. If you are feeling nostalgic, take a look at the last day gallery that I’ve prepared in Singularity Hub’s honor. If you have an issue or question that you want to post for the new archive, you can do so here. This post will continue to give Singularity Hub one last honor before it becomes a distant memory.
You can read the background story here, or watch an interactive version here. I started using containers (Docker, specifically) as a naive graduate student in early 2015, quickly fell in love, and decided it would be my mission to bring containers to our HPC cluster at Stanford. It felt immensely important for scientific reproducibility - or being able to preserve an analysis pipeline by some means (containers are a good start) to run again and reproduce it. I built the original version of Singularity Hub, wrote a paper
Sochat V, Prybol CJ, Kurtzer GM (2017) Enhancing reproducibility in scientific computing: Metrics and registry for Singularity containers. PLoS ONE 12(11): e0188511. https://doi.org/10.1371/journal.pone.0188511 Encapsulation of Environments with Containers¶
and charged forward as an advocate and developer for all things containers. This lasted a few years, until containers “were definitely at thing” and then I stepped back. While discussion of the change in the Singularity community itself from 2016 until now is out of scope for this post, I will say that despite the changes, I still care about supporting the Singularity user base and maintain several Singularity-associated projects.
At the time that I designed Singularity Hub the thought that I likely wouldn’t be able to maintain it forever loomed in my awareness, but I had hope that the company that grew out of Singularity would soon build a service to replace it. They technically did, but unfortunately the free tier was not suitable for what scientific developers would need. And there certainly wasn’t a business model for (most) academics paying for a service, so ultimately I would keep Singularity Hub online much longer than I originally anticipated. A year and then two grew into five years, and in that time I did whatever it took to keep the server and builders running. This meant several refactors, and pursuring funding for the service. While my group could pay small amounts every now and then, the burden of costs was not reasonable, so I ultimately went to Google early on and asked for help. I suspect people have different views about Google, but before you express any negative sentiment remember that at large companies there are people, and I can solidly state that the people who I worked with showed infinite kindness and support for this tiny effort. I am forever grateful to Google for supporting Singularity Hub for all these years – without them it never would have happened. Thank you Google!!
At the beginning of this year, my time at Stanford was coming to a close. I had finished what I set out to do, and it was time for me to move on. At this point, I reached out to the community for help. At best someone could take over the service, and at worst it would simply go away entirely, including all containers. Thankfully the Center for Open Neuroscience and more specifically, Yarikoptic took the reins. We had a simple plan to migrate all the containers and metadata from storage, and then serve the same containers at an archive at Dartmouth. All previously built public containers before the 19th of April would still be available to pull, ensuring reproducibility of those pipelines from all those years. You can in fact now navigate to singularity-hub.org to see the new home! I tried many times to convince Yarik that I should send him ice cream, but I was not successful.
I’ve written about this before, but after maintaining a service and having pretty good knowledge about scientific workflows and software, I’m not convinced that reproducibility is much more than a pipe dream. Yes, I agree that if you use the right technologies, have great documentation, and try to ensure your data and code is preserved over time, the chances that your original analysis will work in 5 years are pretty good. The problem is when we scale out beyond our lifetimes. Have you seen all those GitHub accounts that belong to people that have died because of old age? Probably not, because GitHub has only been around since 2011. But do you ever wonder what happens to your code, and your various services you use to support it, when you are no longer around? The answer is that you need people to continue supporting it.
This is where I will say that sustainability is less about doing the right thing, and more about survival of the valued.
Your code will endure if it continues to be valued. Even if technologies change, if your analysis pipeline or service adds significant value to the community, people will find a way to keep it up to date and running. If you mysteriously go away and leave a hugely useful project unmaintained, someone will fork it and keep it alive. Yes, it’s very likely the case that the awareness and branding that you create around your code will have an impact. For example, you can make the greatest software known to man, but nobody will care if they don’t know about it. But let’s face it. If software or an analysis pipeline does not add value to the world, even if you got a shiny paper out of it, why should there be effort to keep it alive? I used to be a reproducibility stickler and want to save all-the-things, but now I’m more of a reproducibility evolutionist that expects software to grow, change, and die, and wants to support an ecosystem around that.
For these reasons, when I create something these days, I take a needs-based development approach. Sure - when a piece of software is new and I think it could be useful, I spend some time getting the word out. But once the word is out and there are crickets on the GitHub issue board? It’s probably not useful, and I should focus my time on other things. The reality of being a developer is that 99% of what I do is probably not really useful. I’m okay with that, because the 1% can have a huge impact. This is why after something is solidly released in a pretty good state, I only continue to work on it if users open issues and ask me to.
Putting on my reproducibility evolutionist hat, I’m going to say that Singularity Hub was valuable for those first few years when there weren’t many other options. Although it was special to me and used by a few thousand, I’m then going to say that the environment changed so that it wasn’t absolutely essential. There are many different kinds of registries, tricks for building and storing containers, and even new container technologies for HPC that, over time, brought down the overall value. This isn’t to say that it’s not important to maintain containers that were previously built. In a way this is a promise I had hoped to keep, and I’m immensely grateful to be able to do that.
I have a few ideas for how we could continue to serve GitHub built and deployed containers from the shub unique resource identifier, but will hold off on sharing until I’ve had some time to think it over, and test. I do think that, other than the Sylabs library and Docker Hub (or more generally OCI registries) there should be another simple option.
Here is a quick glance at the final state of Singularity Hub. Note that containers, unless they were frozen, would get over-written with a new build (a user pushing to GitHub) and this is how I managed to keep the number down. My original design did not do this, and grew much larger much more quickly.
# A container is associated with a sif binary > Container.objects.count() 7202 # A collection of containers > Collection.objects.count() 3901 # An owner of a collection > User.objects.count() 6530 # A builder associated with a container > Build.objects.count() 8208 # I'm surprised people went out of their way to star collections! Star.objects.count() > 373 # This is the number of collections that had recorded pulls in the last year. > APIRequestCount.objects.count() 2868
Finally, just for the records that I have for the last few months, I can count the number of requests to pull containers across all of Singularity Hub.
total requests 695,493
That’s pretty good! The oldest container, because of the first refactor in 2017, is only from 2017.
> Container.objects.order_by('build_date') <Container: alaindomissy/rnashapes:tag2> datetime.datetime(2017, 10, 15, 18, 24, 56, 188137, tzinfo=<UTC>)
There were surprisingly a handful of demos (documentation, asciinema, or other content related to a container build) despite the feature being disabled pretty early on:
> Demo.objects.count() 29
And very not surprisingly, many labels and apps associated with containers!
> Label.objects.count() 18326 > App.objects.count() 1189
It would be fun to do a weekend project and parse those over. Finally, we can look at the all time leaders for API requests (I’ll truncate at N=500).
miguelcarcamov/container_docker: 140186 ikaneshiro/singularityhub: 87991 singularityhub/busybox: 49156 vsoch/singularity-images: 49036 GodloveD/busybox: 48454 vsoch/hello-world: 26195 GodloveD/lolcow: 19897 tikk3r/lofar-grid-hpccloud: 14454 bouthilx/repro-hub: 14080 singularityhub/centos: 13144 vsoch/singularity-hello-world: 9764 singularityhub/ubuntu: 8392 bouthilx/sgd-space-hub: 8001 marcc-hpc/tensorflow: 7786 dominik-handler/AP_singu: 7246 gem-pasteur/Integron_Finder: 5757 aardk/jupyter-casa: 4320 dynverse/ti_tscan: 3182 nuitrcs/fenics: 3169 truatpasteurdotfr/singularity-alpine: 3034 dynverse/ti_mpath: 3006 ravi-0841/singularity-tensorflow-1.14: 2867 pegasus-isi/montage-workflow-v2: 2745 marcc-hpc/pytorch: 2479 NBISweden/K9-WGS-Pipeline: 2441 staeglis/HPOlib2: 2051 datalad/datalad-container: 1994 nickjer/singularity-rstudio: 1939 dynverse/ti_projected_paga: 1885 dynverse/ti_ouijaflow: 1880 UMMS-Biocore/singularitysc: 1863 dynverse/ti_waterfall: 1858 dynverse/ti_angle: 1851 dynverse/ti_scorpius: 1844 dynverse/ti_comp1: 1838 onuryukselen/singularity: 1824 dynverse/ti_forks: 1816 dynverse/ti_projected_tscan: 1814 dynverse/ti_embeddr: 1814 dynverse/ti_periodpc: 1814 dynverse/ti_monocle_ica: 1813 dynverse/ti_wanderlust: 1809 dynverse/ti_phenopath: 1806 truatpasteurdotfr/singularity-docker-miniconda3: 1558 nickjer/singularity-r: 1553 FCP-INDI/C-PAC: 1532 ISU-HPC/mysql: 1469 dynverse/ti_slicer: 1426 dynverse/ti_elpilinear: 1411 adam2392/deeplearning_hubs: 1328 singularityhub/hello-world: 1307 dynverse/ti_wishbone: 1296 dynverse/ti_fateid: 1256 Characterisation-Virtual-Laboratory/CharacterisationVL-Software: 1249 dynverse/dynwrap: 1248 brucemoran/Singularity: 1233 DavidEWarrenPhD/afnipype: 1188 onuryukselen/initialrun: 1163 as1986/own-singularity: 1161 dynverse/ti_projected_monocle: 1107 bballew/NGS_singularity_recipes: 1072 ReproNim/containers: 1012 TomHarrop/singularity-containers: 1006 cokelaer/graphviz4all: 957 UMMS-Biocore/initialrun: 874 myyoda/ohbm2018-training: 864 chrarnold/Singularity_images: 805 bsiranosian/bens_1337_workflows: 782 justinblaber/synb0_25iso_app: 767 dynverse/ti_mfa: 751 pegasus-isi/fedora-montage: 669 alfpark/linpack: 641 cottersci/DIRT2_Workflows: 641 linzhi2013/MitoZ: 613 lar-airpact/bluesky-framework: 589 apeltzer/EAGER-GUI: 589 datalad/datalad-extensions: 586 maxemil/PhyloMagnet: 564 elimoss/lathe: 562 mwiens91/test-error-containers: 555 ISU-HPC/ros: 551 mwanakijiji/lbti_altair_fizeau: 533 willgpaik/centos7_aci: 519 jekriske/lolcow: 517 tyson-swetnam/osgeo-singularity: 517 ltalirz/singularity-recipe-zeopp: 512
There is a much longer list that has just about as many lines as collections, but we’ll leave it at that for now. Thank you to the community for your excitement about Singularity, and using Singularity Hub! I can’t make any promises, but maybe keep on the lookout for other ideas and developments in the next few months. I certainly hope to contribute more to the world of research software than this small amount of early work.