Simple web app using OCaml + Dream for photo sharing.
opam switch create . 5.1.1
eval $(opam env)
opam install dune dreamThis project requires specific dependencies to run properly. The core dependencies include:
opam install dune dream caqti caqti-lwt caqti-driver-postgresql lwt lwt_ppx uuidm ptimeThe application uses PostgreSQL as its database. The schema is managed through SQL files in the lib/database directory.
For local development, you can initialize the database using:
# Set your database URL in .env file:
POSTGRES_URL=postgres://user:pass@localhost:5432/dbname
# Initialize the database schema
dune exec scripts/db/init_pg.exeIn production, database initialization and migrations are handled through Docker container initialization. The schema will be automatically applied when the database container starts up.
The schema file is located at:
lib/database/schema.pg.sql
Note: The schema requires the uuid-ossp PostgreSQL extension, which will be automatically enabled during initialization.
This project requires specific OCaml dependencies managed through OPAM switches. The default switch with OCaml 5.3.0 is recommended.
-
Check your current switch:
opam switch
-
Use the default switch (recommended):
opam switch default eval $(opam env)
-
Install all required dependencies:
opam install --yes dune dream caqti caqti-lwt caqti-driver-postgresql lwt lwt_ppx ppx_rapper ppx_rapper_lwt uuidm ptime
If dune build fails with a lock error, you can clear the locks:
rm -f _build/.lock
dune clean
dune buildThe project requires the following dependencies to be installed:
-
Core Libraries:
dune: Build systemdream: Web frameworklwtandlwt_ppx: Asynchronous programming
-
Database Libraries:
caqti,caqti-lwt, andcaqti-driver-postgresql: PostgreSQL database connectivityppx_rapperandppx_rapper_lwt: SQL query type safety with PPX
-
Utilities:
uuidm: UUID generationptime: Time handling
All of these must be installed in your active OPAM switch for the project to build and run correctly.
If you encounter issues with PPX extensions specifically, you can try alternate approaches:
-
Ensure ppx_rapper is correctly installed:
opam install ppx_rapper ppx_rapper_lwt
-
Configure dune files properly:
# Make sure libraries includes ppx_rapper_lwt (libraries caqti caqti-lwt caqti-driver-postgresql ppx_rapper_lwt ...) # And preprocess includes both ppx_rapper and lwt_ppx (preprocess (pps ppx_rapper lwt_ppx)) -
Clean build artifacts thoroughly:
rm -rf _build/ dune clean dune build
If you encounter form submission issues with Dream:
-
Ensure the form has the correct enctype:
<form action="/album/new" method="POST" enctype="application/x-www-form-urlencoded">
-
Consider manual form data parsing for debugging:
let%lwt body = Dream.body req in Printf.printf "[DEBUG] Form body: %s\n%!" body;
dune exec ./bin/main.exeVisit: http://localhost:4000
dune buildBinary will be in _build/default/bin/main.exe
/media/d2du/UG_DRIVE/wedding/afterparty
To copy it out:
cp _build/default/bin/main.exe ./photo_app.
βββ .opam/ # local opam switch (env + packages)
βββ _build/ # dune build artifacts
βββ bin/
β βββ dune # dune config for executable
β βββ main.ml # app entry point
β βββ *.eml.html # dream templates
βββ lib/
β βββ database/ # database interaction
β β βββ db.ml # connection pooling
β β βββ schema.pg.sql # PostgreSQL schema
β β βββ dune # database lib config
βββ scripts/
β βββ db/
β βββ init_pg.ml # database initialization script
β βββ dune # script config
βββ dune-project # project metadata
βββ photocaml.opam # package dependencies
βββ README.md # this file
Press Ctrl+C in the terminal.
Edit main.ml:
Dream.run ~interface:"0.0.0.0" ~port:4000For effective debugging:
(* Define debug helpers at the top of your file *)
let debug fmt = Printf.ksprintf (fun s -> Printf.printf "[DEBUG] %s\n%!" s) fmt
let error fmt = Printf.ksprintf (fun s -> Printf.printf "[ERROR] %s\n%!" s) fmt
(* Use them in your code *)
debug "Creating album: %s" name;
error "Database error: %s" err_msg;- Always use
%!at the end of your format strings to force flushing - Set explicit content types in HTML forms
- Check existing files for coding patterns when implementing new features
- For database queries, ppx_rapper provides type safety but requires proper installation
For forms to work correctly:
<form action="/path" method="POST" enctype="application/x-www-form-urlencoded">
<!-- Form elements -->
</form>The Dream handler should use standard form parsing:
match%lwt Dream.form req with
| `Ok params ->
let name = List.assoc "name" params in
(* Continue processing *)
| `Wrong_content_type ->
Dream.html ~status:`Bad_Request "Wrong content type"
| _ ->
Dream.html ~status:`Bad_Request "Invalid form submission"-
Form submission fails:
- Add
enctype="application/x-www-form-urlencoded"to your forms - Use
match%lwt Dream.form req withpattern for handling form data - Check logs for content-type issues
- Ensure the database is initialized (see Database Setup)
- Form submission errors like "Invalid form submission" often indicate missing database tables
- Add
-
Build errors:
- Clear locks:
rm -f _build/.lock && dune clean - Make sure dependencies are installed in your active switch
- Update opam:
opam update && opam upgrade
- Clear locks:
-
Database errors:
- Ensure PostgreSQL is running and accessible
- Check schema matches what queries expect
- Verify database connection string in .env file
- Run database initialization script if needed
dune build bin/cli/photocaml_cli.exeThe CLI executable will be available at _build/default/bin/cli/photocaml_cli.exe
You can use the CLI in three different ways:
-
Interactive Menu Mode (Recommended for beginners):
_build/default/bin/cli/photocaml_cli.exe menu
This will present you with an easy-to-use menu with the following options:
- List all albums
- Upload photos to album
- Exit
-
Direct Commands:
a. List all albums:
_build/default/bin/cli/photocaml_cli.exe list
b. Upload photos to an album:
_build/default/bin/cli/photocaml_cli.exe upload <album_id> <directory_with_photos>
Example:
_build/default/bin/cli/photocaml_cli.exe upload a95a7319-049e-d8e8-a2e6-bc9fd4888d81 /path/to/photos
To see all available commands and options:
_build/default/bin/cli/photocaml_cli.exe --helpFor help with a specific command:
_build/default/bin/cli/photocaml_cli.exe <command> --helpExample:
_build/default/bin/cli/photocaml_cli.exe upload --help