Deploy Hugo on Lizard

Lizard can build a Hugo source site with hugo --minify and serve public/ through nginx on port 80. Start from the Hugo source directory, with a Hugo configuration and content/, rather than uploading only the generated HTML.

Start with the complete source example, which includes the configuration and files used by this recipe.

Prepare the source

Include your Hugo config, content, layouts, assets, and all theme files needed by the build. The Hugo detector looks for configuration such as hugo.toml, hugo.yaml, or config/_default/ plus a content/ directory.

SettingValue
Buildhugo --minify
Outputpublic/
Production servernginx
Service port80

Set baseURL to the intended public site URL, including its trailing slash. Rebuild after assigning a different hostname so links and generated sitemap entries use it. Check Hugo’s build and output guide.

Check build dependencies

The default Hugo build image is hugomods/hugo:base; it does not pin a Hugo version for your project. If a theme needs a particular Hugo version, the extended edition, or Node tooling, use a complete Dockerfile with those dependencies and the version you tested.

A Hugo config and content/ select the Hugo builder before Go or Node detection. Hugo Modules projects with go.mod use a build image with Go support. A package.json causes the build to stop with a request for a Dockerfile: install the Node dependencies, build the assets, then run hugo --minify. See build decision order.

Build locally and deploy

hugo --minify
hugo server

Inspect public/ after the first command. Use the local server to check content and theme rendering; hugo server is not the production start command.

After CLI setup, deploy the source directory:

lizard init --name hugo-site
lizard add --service web
lizard up --service web --port 80
lizard logs --build --service web --json
lizard ps --json

If you use the generated hostname, read it after the first deploy:

lizard service show web --json

Set baseURL in hugo.toml to that hostname:

baseURL = "https://YOUR_PUBLIC_HOST/"

Upload the changed config so the build uses the public URL:

lizard up --service web --port 80

Exclude local generated output and secrets. For an upload, ensure theme source files actually exist in the directory you send; a remote submodule reference alone is not the theme content.

Verify the deployed site

Open the live home page, an inner article, and an image. Check the generated canonical URLs and sitemap.xml. Test a made-up path’s HTTP status. New Hugo builds serve the generated HTML and return HTTP 404 for missing pages. No custom Dockerfile is needed for the simple source layout in this guide. Rebuild older images to pick up the current routing rules.

Use static routes and 404s if you need a custom nginx policy. A custom Hugo build stage must include the theme’s required Hugo version and tools, run hugo --minify, and copy public/ into the serving image.

If theme assets are missing, inspect the build logs, theme source, and baseURL. If the wrong builder starts, check that the Hugo config and content/ are in the upload root and inspect existing service overrides. Hugo produces static files, so content changes need a new build.

See tested versions and cloud results for the September 9, 2026 deployment checks and their limits.

Updated