Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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 one_binary.opam:

opam-version: "2.0"

depends: [
  "crunch"
  "ocaml" {>= "4.08.0"}
  "dream"
  "dune" {>= "2.0.0"}
]

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.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

$ cd example/w-one-binary
$ opam install --deps-only --yes .
$ dune exec --root . ./one_binary.exe

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