Skip to content

Commit 112cb13

Browse files
committed
Add dune-pkg image variant with compiler variants
Split the pipeline into independent opam and dune-pkg paths over shared helpers (Distro_util). Add an ocaml-base variant for `dune pkg` builds: ships dune + a baked relocatable compiler, no opam/switch/repo. Scoped to x86_64, apk/apt distros, OCaml >= 5.5. See docs/adr/0001, 0002. On tier-1 distros also build compiler variants (+flambda, +afl, +no-flat-float-array) via the upstream ocaml-options-only-* packages, mirroring how the opam images install variants.
1 parent 2545c82 commit 112cb13

9 files changed

Lines changed: 1141 additions & 430 deletions

File tree

builds.expected

Lines changed: 426 additions & 0 deletions
Large diffs are not rendered by default.

doc/dune-pkg/USAGE.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Using a `dune` image
2+
3+
Ships `dune` + a pre-built OCaml compiler baked into dune's cache. You bring a
4+
committed `dune.lock`; the image builds it, reusing the baked compiler — no opam,
5+
no network, no compiler rebuild.
6+
7+
Tag: `ocaml/opam:<distro>-dune-ocaml-<version>[-<variant>]`, x86_64 only.
8+
E.g. `debian-dune-ocaml-5.5`, `alpine-dune-ocaml-5.5-flambda`.
9+
10+
## On the host (once)
11+
12+
`dune` must be installed. Lock from opam-repository only, so the locked compiler
13+
matches the baked one:
14+
15+
```sh
16+
cat > dune-workspace <<'EOF'
17+
(lang dune 3.20)
18+
(lock_dir (repositories upstream))
19+
EOF
20+
21+
dune pkg lock # writes dune.lock/ — commit it; re-run only when deps change
22+
```
23+
24+
## In the image
25+
26+
```sh
27+
docker run --rm -v "$PWD:/src" -w /src \
28+
ocaml/opam:debian-dune-ocaml-5.5 dune exec ./main.exe
29+
```
30+
31+
Or `COPY . .` the sources in via a Dockerfile (the natural CI shape).
32+
33+
## Gotchas
34+
35+
- **Version/variant must match the tag.** A `dune-ocaml-5.5` image only reuses
36+
the baked compiler if your lock resolves OCaml `5.5` (`(ocaml (= 5.5.0))`); a
37+
`-flambda` image needs `ocaml-options-only-flambda` in your `depends`. A
38+
mismatch forces a from-source compiler build.
39+
- **x86_64 only** — no dune Linux-arm64 binary.

src/conf.ml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
(* For staging arch-specific builds before creating the manifest. *)
22
let staging_repo = "ocurrent/opam-staging"
33

4+
(* dune-pkg staging images don't use the opam staging repo. *)
5+
let dune_staging_repo = "ocurrentbuilder/staging"
6+
47
let public_repo = "ocaml/opam"
58

69
let password_path =

src/distro_util.ml

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
(* Pure helpers shared by the opam and dune image pipelines. No OCurrent
2+
dependency, so both [Pipeline_opam] and [Pipeline_dune] can use them without
3+
either depending on the other. *)
4+
5+
module Distro = Dockerfile_opam.Distro
6+
7+
module Switch_map = Map.Make (Ocaml_version)
8+
module Windows_map = Map.Make (Distro)
9+
10+
let or_die = function
11+
| Ok x -> x
12+
| Error (`Msg m) -> failwith m
13+
14+
(* [aliases_of d] gives other tags which should point to [d].
15+
e.g. just after the Ubuntu 20.04 release, [aliases_of ubuntu-20.04 = [ ubuntu; ubuntu-lts ]] *)
16+
let aliases_of =
17+
let latest = Distro.distros |> List.map (fun d -> (Distro.resolve_alias d : Distro.distro :> Distro.t), d) in
18+
fun d -> List.filter_map (fun (d2, alias) -> if d = d2 && d <> alias then Some alias else None) latest
19+
20+
let master_distro = Distro.((resolve_alias master_distro : distro :> t))
21+
22+
(* 2020-04-29: On Windows, squashing images is still experimental (broken). *)
23+
let squash distro =
24+
Distro.os_family_of_distro distro <> `Windows
25+
26+
(* 2022-07-18: Windows Containers don't support BuildKit.
27+
https://github.com/microsoft/Windows-Containers/issues/34 *)
28+
let buildkit distro =
29+
Distro.os_family_of_distro distro <> `Windows
30+
31+
(* The set of all OCaml switches present across a list of per-arch maps. *)
32+
let all_switches arches =
33+
let module Switch_set = Set.Make (Ocaml_version) in
34+
arches |> ListLabels.fold_left ~init:Switch_set.empty ~f:(fun acc map ->
35+
Switch_map.fold (fun k _v acc -> Switch_set.add k acc) map acc)
36+
|> Switch_set.elements

0 commit comments

Comments
 (0)