├── .gitignore ├── Dockerfile ├── bin ├── Server.ml └── dune └── dune-project /.gitignore: -------------------------------------------------------------------------------- 1 | .merlin 2 | node_modules/ 3 | _build 4 | _release 5 | *.byte 6 | *.native 7 | *.install 8 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ## This is a two-stage docker file 2 | # This first stage has opam & a ton of other things 3 | # inside it. The full image is 1.4Gigs! Which is way 4 | # too big to keep around. 5 | FROM ocaml/opam:alpine as base 6 | 7 | RUN sudo apk update 8 | RUN sudo apk add m4 9 | RUN sh -c "cd ~/opam-repository && git pull -q" 10 | RUN opam update 11 | # We'll need these two whatever we're building 12 | RUN opam install dune reason > /dev/null 2>&1 13 | 14 | # need these two for building tls, which is needed by cohttp 15 | RUN opam depext conf-gmp.1 16 | RUN opam depext conf-perl.1 17 | RUN opam install tls > /dev/null 2>&1 18 | # these are the dependencies for our server 19 | RUN opam install lwt cohttp cohttp-lwt-unix > /dev/null 2>&1 20 | 21 | # Now we copy in the source code which is in the current 22 | # directory, and build it with dune 23 | COPY --chown=opam:nogroup . /hello-reason 24 | WORKDIR /hello-reason 25 | RUN sh -c 'eval `opam config env` dune build bin/Server.exe' 26 | 27 | ## Here's the second, *much* leaner, stage 28 | # It only contains the server binary! The reason we can do this 29 | # is we statically linked the binary (with -ccopt -static) 30 | FROM scratch 31 | COPY --from=base /hello-reason/_build/default/bin/Server.exe /server 32 | CMD ["/server"] -------------------------------------------------------------------------------- /bin/Server.ml: -------------------------------------------------------------------------------- 1 | open Lwt 2 | open Cohttp 3 | open Cohttp_lwt_unix 4 | 5 | let count = ref 0 6 | 7 | let server = 8 | let callback _conn req body = 9 | let uri = req |> Request.uri |> Uri.to_string in 10 | let meth = req |> Request.meth |> Code.string_of_method in 11 | let headers = req |> Request.headers |> Header.to_string in 12 | count := count.contents + 1; 13 | body |> Cohttp_lwt.Body.to_string >|= (fun body -> 14 | (Printf.sprintf "Hello folks! This site has been visited %d times\n\nUri: %s\nMethod: %s\nHeaders\nHeaders: %s\nBody: %s" 15 | count.contents uri meth headers body)) 16 | >>= (fun body -> Server.respond_string ~status:`OK ~body ()) 17 | in 18 | Server.create ~mode:(`TCP (`Port 8000)) (Server.make ~callback ()) 19 | 20 | let () = ignore (Lwt_main.run server) -------------------------------------------------------------------------------- /bin/dune: -------------------------------------------------------------------------------- 1 | (executable 2 | (name Server) 3 | (modules Server) 4 | (libraries cohttp lwt cohttp-lwt-unix) 5 | (flags (-ccopt -static)) 6 | ) 7 | -------------------------------------------------------------------------------- /dune-project: -------------------------------------------------------------------------------- 1 | (lang dune 1.0) 2 | --------------------------------------------------------------------------------