Publish Marp slides on GitHub Pages with Actions or Docker
Publish Marp decks on GitHub Pages with one workflow: check out the repository, run marp-cli over the slides folder to produce HTML (and PDF) in a dist/ folder, upload that folder as the Pages artifact, deploy. Every push updates the course site, and students get a stable link per week. The Docker image marpteam/marp-cli runs the same build on any machine without installing Node.
This guide gives the workflow file, the folder layout, the PDF step, the Docker command, and the two things that break (local images and custom themes) with their fixes.
Folder layout
course/
slides/
week-01.md
week-02.md
assets/ images
themes/
cs101.css
.github/workflows/pages.yml
marp-cli converts a whole folder with --input-dir (-I), keeping the structure, so slides/week-01.md becomes dist/week-01.html.
The workflow
# .github/workflows/pages.yml
name: Publish slides
on:
push:
branches: [main]
permissions:
contents: read
pages: write
id-token: write
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- name: Build HTML
run: npx @marp-team/marp-cli@latest -I slides -o dist --theme-set themes --html
- name: Build PDF
run: npx @marp-team/marp-cli@latest -I slides -o dist --theme-set themes --pdf --allow-local-files
- name: Copy assets
run: cp -r slides/assets dist/assets
- uses: actions/upload-pages-artifact@v3
with:
path: dist
deploy:
needs: build
runs-on: ubuntu-latest
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- id: deployment
uses: actions/deploy-pages@v4
In the repository settings, set Pages to deploy from GitHub Actions. The PDF step needs a browser; the ubuntu-latest runner has Chrome, which marp-cli finds on its own. --allow-local-files is what lets the PDF include the images in slides/assets; --html is only needed if the decks use inline styles or iframes.
A community action (KoharaKazuya/marp-cli-action) wraps the conversion step; the npx line above does the same with no extra dependency.
Links that stay stable
Students bookmark https://user.github.io/course/week-05.html. Keep file names fixed across the term (week-05, not scheduling-v2), and when a deck changes, push; the link stays. For a PDF per week, the same name with .pdf. An index.md in slides/ converted like the others makes a landing page listing the weeks.
Docker
The same build without Node on the machine:
docker run --rm -v "$PWD:/home/marp/app/" -e LANG=$LANG marpteam/marp-cli -I slides -o dist --pdf --allow-local-files
The image ships a browser, so PDF and PPTX work inside it. It is the right tool for a lab machine or a CI system that is not GitHub.
What breaks and the fix
- Images missing in the PDF: the paths in the deck must be relative to the Markdown file, and the PDF step needs
--allow-local-files. - Theme not applied: pass
--theme-set themesand make sure the deck'stheme:matches the/* @theme name */comment in the CSS. - Fonts different in the PDF: the runner has no Lato or Inter; import them in the theme from Google Fonts, or use system fonts.
- A private course: GitHub Pages on a private repository is public unless the organisation plan supports private Pages. For internal material, build the artifact and put it behind the LMS instead of Pages.
Lecture Studio and git
Lecture Studio keeps a course as a folder with one deck per unit and shows a git bar when the folder is a repository; commit and push from the app, and the workflow above publishes the decks. Nothing in the app needs to change for this to work, since the decks are plain Marp files. The app runs on macOS 15 or later; the assistant needs an Oberik project key.
FAQ
How do I publish Marp slides on GitHub Pages?
A workflow that runs npx @marp-team/marp-cli -I slides -o dist on push, uploads dist with actions/upload-pages-artifact, and deploys with actions/deploy-pages. Set Pages to deploy from Actions.
Can GitHub Actions build Marp PDFs?
Yes. The Ubuntu runner has Chrome; run marp-cli with --pdf --allow-local-files.
Is there a Marp Docker image?
marpteam/marp-cli (also on ghcr.io). Mount the folder at /home/marp/app/ and pass the usual flags.
How do I convert a whole folder of Marp decks?
marp -I slides -o dist converts every Markdown file in slides, keeping the structure.