diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml
new file mode 100644
index 00000000..89e278f8
--- /dev/null
+++ b/.github/workflows/pages.yml
@@ -0,0 +1,52 @@
+name: Deploy to GitHub Pages
+
+on:
+ push:
+ branches: ["main"]
+ workflow_dispatch:
+
+permissions: {}
+
+concurrency:
+ group: pages
+ cancel-in-progress: true
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ permissions:
+ contents: read
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ with:
+ persist-credentials: false
+
+ - name: Setup mise
+ uses: jdx/mise-action@6d1e696aa24c1aa1bcc1adea0212707c71ab78a8 # v3.6.1
+ with:
+ cache: true
+
+ - name: Build docs
+ run: mise run build-docs
+
+ - name: Configure Pages
+ uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0
+
+ - name: Upload artifact
+ uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
+ with:
+ path: docs/public
+
+ deploy:
+ needs: build
+ runs-on: ubuntu-latest
+ permissions:
+ pages: write
+ id-token: write
+ environment:
+ name: github-pages
+ url: ${{ steps.deployment.outputs.page_url }}
+ steps:
+ - name: Deploy to GitHub Pages
+ id: deployment
+ uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
diff --git a/.gitignore b/.gitignore
index 412baa41..508c44e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,5 @@
/cmd/geoipupdate/geoipupdate
/vendor
.idea
+docs/.hugo_build.lock
+docs/public/
diff --git a/_config.yml b/_config.yml
deleted file mode 100644
index 0536c73c..00000000
--- a/_config.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-exclude: ['README.dev.md', 'vendor']
-
-
diff --git a/docs/hugo.toml b/docs/hugo.toml
new file mode 100644
index 00000000..0177fc83
--- /dev/null
+++ b/docs/hugo.toml
@@ -0,0 +1,14 @@
+baseURL = "https://maxmind.github.io/geoipupdate/"
+title = "GeoIP Update"
+disableKinds = ["taxonomy"]
+
+[[cascade]]
+ layout = "default"
+
+[markup.highlight]
+ noClasses = true
+ style = "github"
+
+[[module.mounts]]
+ source = "../README.md"
+ target = "content/_index.md"
diff --git a/docs/layouts/_default/_markup/render-heading.html b/docs/layouts/_default/_markup/render-heading.html
new file mode 100644
index 00000000..4f4fcc0a
--- /dev/null
+++ b/docs/layouts/_default/_markup/render-heading.html
@@ -0,0 +1,4 @@
+