dream/example/w-one-binary
Anton Bachin c5514d72e3 Use esy
2021-04-21 10:49:15 +03:00
..
2021-04-21 10:49:15 +03:00
2021-04-20 01:36:38 +03:00
2021-04-20 01:36:38 +03:00
2021-04-21 10:49:15 +03:00
2021-04-21 10:49:15 +03:00

w-one-binary

This example bakes static assets into the server binary file. The whole web app is contained inside just one_binary.exe!


First, we make the dune file call crunch to turn the assets/ directory into a file assets.ml:

(rule
 (target assets.ml)
 (deps (source_tree assets))
 (action (with-stdout-to %{null}
  (run ocaml-crunch -m plain assets -o %{target}))))

crunch comes from the opam repository, so we also add it in esy.json:

"dependencies": {
  "@opam/crunch": "*"
}

The generated assets.ml has a signature like this:

val Assets.file_list : string list
(* ["README.md"; "camel.jpeg"] *)

val Assets.read : string -> string option
(* Assets.read "camel.jpeg" and Assets.read "/camel.jpeg" both work. *)

After that, we just need to tell Dream.static to load files from module Assets, rather than from the file system. We do this by passing it the optional ~loader argument:

let loader _root path _request =
  match Assets.read path with
  | None -> Dream.empty `Not_Found
  | Some asset -> Dream.respond asset

let () =
  Dream.run
  @@ Dream.logger
  @@ Dream.router [
    Dream.get "/assets/**" (Dream.static ~loader "")
  ]
  @@ Dream.not_found

Dream.static will take care of adding a Content-Type to each file, based on its extension. You can override it by setting Content-Type yourself when calling Dream.respond, or using Dream.add_header.


To build the whole setup, just do

$ npm install esy && npx esy
$ npx esy start

You can now visit http://localhost:8080/assets/camel.jpeg for a picture of a nice camel:

Camel

http://localhost:8080/assets/README.md gives the source link and license information for the image.


Copy the binary out for deployment with

npx esy cp '#{self.target_dir}/default/one_binary.exe' .

It will continue to serve the camel no matter where it is moved to! The assets/ directory from this example doesn't have to be copied along with it.


If you'd like to inspect the generated assets.ml yourself, run

npx esy less '#{self.target_dir}/default/assets.ml'

To add more files, just add them to the assets/ directory and re-run npx esy run. Dune and crunch will pick them up automatically.


See also:


Up to the example index