How to setup local OPAM mirror

I had a similar need and my solution to it might help you out. I didn’t create a local git repo within my org, instead I just use the provided repository by the default ocaml docker images, and I tweak them a bit to work for me. All builds I trigger at my job are airtight (ie they don’t reach out to the internet – at least not directly, more below). So I leveraged the following things:

  • An HTTP proxy that caches fetched artifacts (this is the only thing that can reach the internet), pointing only to opam.ocaml.org.
  • The OPAMFETCH environment variable. Which in the man page reads
OPAMFETCH specifies how to download files: either `wget', `curl' or a
custom command where variables %{url}%, %{out}%, %{retry}%,
%{compress}% and %{checksum}% will be replaced. Overrides the
'download-command' value from the main config file.
  • A custom script that uses my HTTP proxy instead of opam.ocaml.org, which I set to OPAMFETCH according to the docs. The checksum is in the form of something like md5=<md5sum>. So for example you can see the sha256 for merlin3.3.3 here:

And you can see that it’s cached in opam.ocaml.org:

 $ curl --head https://opam.ocaml.org/cache/sha256/72/72909ef47eea1f6fca13b4109a34dccf8fe3923a3c026f1ed1db9eb5ee9aae15
HTTP/1.1 200 OK
...

The script I set to OPAMFETCH just replaces opam.ocaml.org with something like cache-proxy.my-big-enterprise.tld.

I noticed that what @avsm mentions is what they do in opam.ocaml.org (or something very similar, I don’t remember, I looked it up long ago), so by doing that you’d get a similar cache locally. I didn’t want to maintain that and I’m happy to just use the upstream opam.ocaml.org cache. I’m not assuming there’s any guarantees around that (nor do I expect that), but it’s a convenient way for me to fetch the sources defined by the default opam repository. Otherwise I’d have to set up all the different proxies to fetch sources and it would be a mess for me.

One thing I’d note however, please keep supporting OPAMFETCH! It was a life saver :smile:

Once that setup is done in my customized docker container, I just prefetch and install stuff like core, utop, etc.

I’m sure there’s a more convenient way of doing this, so if you end up documenting it then I’ll be very keen to read it.