Data-driven curriculum vitae built with Eleventy (11ty) that can automatically capture a shareable PDF during Eleventy runs (npm run build, npm run dev, npm run prod) unless disabled. Resume content lives in YAML, is rendered with Nunjucks templates, and styled for both screen and print layouts.
https://resume.nicholas.clooney.io/
Web
- Copy
_data/cv.template.yamlto_data/cv.yaml, then update the new file with your details. - Copy
_data/contact.example.yamlto_data/contact.yaml, then update the email and phone values used in the print preview. - Install dependencies:
npm install - Launch the development server:
npm run dev, then openhttp://localhost:8080 - Build the static output:
npm run build(artifacts land in_site/, including_site/resume.pdf)
- Launch the dev server and open
http://localhost:8080/for the mobile-friendly layout. - Use the top bar links to jump to the print-focused view at
/print_preview/, print directly, or grab the generated PDF. - The page styles live in
css/resume-responsive.css; tweak spacing or breakpoints here when iterating.
- Use
docker-compose-no-pdf.ymlto run Eleventy in Docker without PDF generation. - Start the dev or prod service:
docker compose -f docker-compose-no-pdf.yml up resume-dev-no-pdfdocker compose -f docker-compose-no-pdf.yml up resume-prod-no-pdf
- Or run both at once:
docker compose -f docker-compose-no-pdf.yml up - Open
http://localhost:8090for dev orhttp://localhost:8091for prod. - PDF generation is disabled via the
:disable_pdfcommands withDISABLE_PDF=1in thepackage.jsonfile.
- Use
compose.ymlto run with the localDockerfileimage, which installs Chromium for Puppeteer-based PDF export. - The PDF-capable image is still on the larger side (about
1.75GB) due to Chromium and Puppeteer dependencies. - Default mode (public ports):
docker compose up -d- Dev:
http://127.0.0.1:8080 - Prod:
http://127.0.0.1:8090
- Shared-edge mode (no host ports; for reverse proxy via Caddy on the
edgenetwork):- One-time network create:
docker network create edge 2>/dev/null || true - Run:
docker compose -f compose.yml -f compose.edge.yml up -d - Caddy (in the ingress stack) should
reverse_proxyto thedevorprodcontainer names on theedgenetwork.
- One-time network create:
- Show merged config:
docker compose -f compose.yml -f compose.edge.yml config - Find container DNS names on the edge network:
docker network inspect edge --format '{{range $id,$c := .Containers}}{{$c.Name}} aliases={{printf "%v" $c.Aliases}}{{"\n"}}{{end}}'
_data/cv.yaml— primary data source; copy it from the template and update the content with your experience, skills, and links._data/cv.template.yaml— reference template that mirrors the expected schema for_data/cv.yaml._data/contact.yaml— email and phone values surfaced in the print preview header._data/contact.example.yaml— starter template for_data/contact.yaml._includes/layout.njk— base HTML frame, including print-friendly styles and the PDF trigger._includes/layout-responsive.njk— mobile-first chrome used by the responsive on-screen review.src/index.njk— responsive resume view rendered at/for mobile and desktop previews.src/print_preview.njk— print-optimized resume view rendered at/print_preview/.css/base.css— shared typography and page scaffolding for screen and print.css/display.css— screen-focused layout enhancements and interactive chrome.css/sections.css— styling for the individual resume sections and typography.css/print.css— print-only overrides plus@pagesizing.css/resume-responsive.css— responsive-only styling for the alternate preview page.scripts/generate-pdf.js— Puppeteer helper that captures_site/resume.pdfafter Eleventy runs (unless disabled)..eleventy.js— Eleventy configuration enabling YAML data loading and stylesheet passthrough.
- Edit
_data/cv.yaml(after copying from_data/cv.template.yaml) to adjust content. Keep entries chronological (newest first) to match the rendered order. - Modify or add sections in
src/index.njkto reflect additional resume components (e.g., awards, speaking). - Tweak typography, spacing, and print rules across
css/base.css,css/display.css,css/sections.css, andcss/print.css. The layout relies on A4 dimensions (210mmwidth,@pagesize).
- Running
npm run buildtriggersscripts/generate-pdf.js, which temporarily serves_site/on an ephemeral localhost port and captures_site/resume.pdfwith Puppeteer. npm run devandnpm run prodalso run the same PDF step after Eleventy writes output; usenpm run dev:disable_pdfornpm run prod:disable_pdfto skip it.- The “Download PDF” button links directly to
/resume.pdf; make sure the build completed so the file exists. - When printing manually, disable browser-supplied headers/footers if you want a clean PDF (Chrome: More Settings → Headers and footers).
- Ensure print margins remain at the defaults defined in CSS (
12mmvia@page).
- Run
npm run buildbefore sharing updates to confirm the project compiles without errors. - After each content or styling change, review the page in desktop and print preview to confirm layout, link targets, and page count.