Shells in OCaml
1FROM ocaml/opam:alpine-ocaml-5.3 AS builder
2WORKDIR /home/opam/src
3COPY --chown=opam merry.opam .
4RUN opam pin . -yn
5RUN opam install . --deps-only --with-test
6COPY --chown=opam . .
7RUN opam exec -- dune build --profile=release
8
9FROM alpine:3.23
10
11# Copy across msh as the new shell!
12COPY --from=builder /home/opam/src/_build/default/src/bin/main.exe /bin/msh
13RUN ln -sf /bin/msh /bin/sh
14SHELL [ "/bin/msh", "-c" ]
15
16LABEL distro_style="apk"
17RUN apk update && apk upgrade
18RUN apk add build-base bzip2 git tar curl ca-certificates openssl
19RUN git config --global user.email "docker@example.com"
20RUN git config --global user.name "Docker"
21RUN git clone https://github.com/ocaml/opam /tmp/opam && cd /tmp/opam && cp -P -R -p . ../opam-sources && git checkout 16116259a7db479cb69f4dbd6c430ec14c5814ad && env MAKE='make -j' shell/bootstrap-ocaml.sh && make -C src_ext cache-archives
22RUN cd /tmp/opam-sources && cp -P -R -p . ../opam-build-2.0 && cd ../opam-build-2.0 && git fetch -q && git checkout adc1e1829a2bef5b240746df80341b508290fe3b && ln -s ../opam/src_ext/archives src_ext/archives && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" ./configure --enable-cold-check && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" make lib-ext all && mkdir -p /usr/local/bin && cp /tmp/opam-build-2.0/opam /usr/local/bin/opam-2.0 && chmod a+x /usr/local/bin/opam-2.0 && rm -rf /tmp/opam-build-2.0
23RUN cd /tmp/opam-sources && cp -P -R -p . ../opam-build-2.1 && cd ../opam-build-2.1 && git fetch -q && git checkout 263921263e1f745613e2882745114b7b08f3608b && ln -s ../opam/src_ext/archives src_ext/archives && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" ./configure --enable-cold-check --with-0install-solver && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" make lib-ext all && mkdir -p /usr/local/bin && cp /tmp/opam-build-2.1/opam /usr/local/bin/opam-2.1 && chmod a+x /usr/local/bin/opam-2.1 && rm -rf /tmp/opam-build-2.1
24RUN cd /tmp/opam-sources && cp -P -R -p . ../opam-build-2.2 && cd ../opam-build-2.2 && git fetch -q && git checkout 01e9a24a61e23e42d513b4b775d8c30c807439b2 && ln -s ../opam/src_ext/archives src_ext/archives && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" ./configure --enable-cold-check --with-0install-solver --with-vendored-deps && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" make lib-ext all && mkdir -p /usr/local/bin && cp /tmp/opam-build-2.2/opam /usr/local/bin/opam-2.2 && chmod a+x /usr/local/bin/opam-2.2 && rm -rf /tmp/opam-build-2.2
25RUN cd /tmp/opam-sources && cp -P -R -p . ../opam-build-2.3 && cd ../opam-build-2.3 && git fetch -q && git checkout 35acd0c5abc5e66cdbd5be16ba77aa6c33a4c724 && ln -s ../opam/src_ext/archives src_ext/archives && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" ./configure --enable-cold-check --with-0install-solver --with-vendored-deps && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" make lib-ext all && mkdir -p /usr/local/bin && cp /tmp/opam-build-2.3/opam /usr/local/bin/opam-2.3 && chmod a+x /usr/local/bin/opam-2.3 && rm -rf /tmp/opam-build-2.3
26RUN cd /tmp/opam-sources && cp -P -R -p . ../opam-build-2.4 && cd ../opam-build-2.4 && git fetch -q && git checkout 7c92631391984f698f31ee24f3ae4dc1cd3698ff && ln -s ../opam/src_ext/archives src_ext/archives && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" ./configure --enable-cold-check --with-0install-solver --with-vendored-deps && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" make lib-ext all && mkdir -p /usr/local/bin && cp /tmp/opam-build-2.4/opam /usr/local/bin/opam-2.4 && chmod a+x /usr/local/bin/opam-2.4 && rm -rf /tmp/opam-build-2.4
27RUN cd /tmp/opam-sources && cp -P -R -p . ../opam-build-2.5 && cd ../opam-build-2.5 && git fetch -q && git checkout edf980ebd18ad6b5e990dbf3b6367cffcaf01815 && ln -s ../opam/src_ext/archives src_ext/archives && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" ./configure --enable-cold-check --with-0install-solver --with-vendored-deps && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" make lib-ext all && mkdir -p /usr/local/bin && cp /tmp/opam-build-2.5/opam /usr/local/bin/opam-2.5 && chmod a+x /usr/local/bin/opam-2.5 && rm -rf /tmp/opam-build-2.5
28RUN cd /tmp/opam-sources && cp -P -R -p . ../opam-build-master && cd ../opam-build-master && git fetch -q && git checkout 16116259a7db479cb69f4dbd6c430ec14c5814ad && ln -s ../opam/src_ext/archives src_ext/archives && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" ./configure --enable-cold-check --with-0install-solver --with-vendored-deps && env PATH="/tmp/opam/bootstrap/ocaml/bin:$PATH" make lib-ext all && mkdir -p /usr/local/bin && cp /tmp/opam-build-master/opam /usr/local/bin/opam-master && chmod a+x /usr/local/bin/opam-master && rm -rf /tmp/opam-build-master
29RUN strip /usr/local/bin/opam*
30
31FROM alpine:3.23
32RUN <<-EOF cat >> /etc/apk/repositories
33 @edge https://dl-cdn.alpinelinux.org/alpine/edge/main
34 @edgecommunity https://dl-cdn.alpinelinux.org/alpine/edge/community
35 @testing https://dl-cdn.alpinelinux.org/alpine/edge/testing
36EOF
37ENV OCAMLRUNPARAM=b
38RUN apk update && apk upgrade
39RUN apk add build-base patch tar ca-certificates git rsync curl sudo bash libx11-dev nano coreutils xz ncurses-dev bubblewrap
40COPY --from=1 [ "/usr/local/bin/opam-2.0", "/usr/bin/opam-2.0" ]
41RUN ln /usr/bin/opam-2.0 /usr/bin/opam
42COPY --from=1 [ "/usr/local/bin/opam-2.1", "/usr/bin/opam-2.1" ]
43COPY --from=1 [ "/usr/local/bin/opam-2.2", "/usr/bin/opam-2.2" ]
44COPY --from=1 [ "/usr/local/bin/opam-2.3", "/usr/bin/opam-2.3" ]
45COPY --from=1 [ "/usr/local/bin/opam-2.4", "/usr/bin/opam-2.4" ]
46COPY --from=1 [ "/usr/local/bin/opam-2.5", "/usr/bin/opam-2.5" ]
47COPY --from=1 [ "/usr/local/bin/opam-master", "/usr/bin/opam-dev" ]
48RUN addgroup -S -g 1000 opam
49RUN adduser -S -u 1000 -G opam opam
50COPY <<-EOF /etc/sudoers.d/opam
51 opam ALL=(ALL:ALL) NOPASSWD:ALL
52EOF
53RUN chmod 440 /etc/sudoers.d/opam
54RUN chown root:root /etc/sudoers.d/opam
55RUN sed -i.bak 's/^Defaults.*requiretty//g' /etc/sudoers
56USER opam
57WORKDIR /home/opam
58RUN mkdir .ssh
59RUN chmod 700 .ssh
60COPY --chown=opam <<-EOF /home/opam/.opamrc-nosandbox
61 wrap-build-commands: []
62 wrap-install-commands: []
63 wrap-remove-commands: []
64 required-tools: []
65EOF
66COPY --chown=opam <<-EOF /home/opam/opam-sandbox-disable
67 #!/bin/sh
68 cp ~/.opamrc-nosandbox ~/.opamrc
69 echo --- opam sandboxing disabled
70EOF
71RUN chmod a+x /home/opam/opam-sandbox-disable
72RUN sudo mv /home/opam/opam-sandbox-disable /usr/bin/opam-sandbox-disable
73COPY --chown=opam <<-EOF /home/opam/.opamrc-sandbox
74 wrap-build-commands: ["%{hooks}%/sandbox.sh" "build"]
75 wrap-install-commands: ["%{hooks}%/sandbox.sh" "install"]
76 wrap-remove-commands: ["%{hooks}%/sandbox.sh" "remove"]
77EOF
78COPY --chown=opam <<-EOF /home/opam/opam-sandbox-enable
79 #!/bin/sh
80 cp ~/.opamrc-sandbox ~/.opamrc
81 echo --- opam sandboxing enabled
82EOF
83RUN chmod a+x /home/opam/opam-sandbox-enable
84RUN sudo mv /home/opam/opam-sandbox-enable /usr/bin/opam-sandbox-enable
85RUN git config --global user.email "docker@example.com"
86RUN git config --global user.name "Docker"
87COPY --link --chown=opam:opam [ ".", "/home/opam/opam-repository" ]
88RUN opam-sandbox-disable
89RUN opam init -k git -a /home/opam/opam-repository --bare
90RUN echo 'archive-mirrors: "https://opam.ocaml.org/cache"' >> ~/.opam/config
91RUN rm -rf .opam/repo/default/.git
92