docker-openresty, the image matrix behind OpenResty deployments
Docker tooling for OpenResty
At a glance
- What is it?
- The docker-openresty repository is the tooling that produces the official OpenResty container images, across Ubuntu, Debian, Alpine, Fedora, Rocky and Windows, with variants built from upstream packages and variants built from source. The tag naming convention is the part most people have to learn, and the README spends most of its space on it.
- Who is it for?
- docker-openresty suits anyone deploying OpenResty in containers who wants an image built by the upstream project rather than a community one, and the tag table is worth reading before you choose, because the fat, slim, apk and source-built variants differ in more than size.
- Can I use it commercially?
- Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly Dockerfile, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What OpenResty is, and why it needs its own images
docker-openresty is the Docker tooling for OpenResty. The README explains the pairing in a sentence each. Docker is a container management platform, and OpenResty is a full-fledged web application server that bundles the standard nginx core, lots of third-party nginx modules, as well as most of their external dependencies.
That bundling is why a dedicated image set exists. A generic nginx image gives you nginx, and the modules and the Lua runtime and the luarocks tree that OpenResty depends on are not in it. An OpenResty image is closer to a distribution than to a config layer, and that is why the flavour matrix is as wide as it is.
The images are published to the GitHub Container Registry as the primary source, under ghcr.io/neomantra/openresty, and then mirrored to Docker Hub as openresty/openresty, or docker.io/openresty/openresty, for convenience and backward compatibility. So a pull from Docker Hub is a mirror of a GHCR artifact, and a consumer who cares about where the image came from should know that.
The project also documents its own history in a way that is worth reading. The README thanks Travis CI for donating their build infrastructure to the project for over seven years, and says they have since migrated to GitHub Actions. The build status badge in the header points at the docker-publish workflow on master, and there is a microbadger badge for the Docker Hub image.
The licence is BSD 2-Clause, the last push was on 2026-10-09, and the default branch is master. The single release tag, 1.9.7.4, dates from 2016, so the tags in this repository are not where the current images are tracked.
Reading a tag, and the difference between upstream and source builds
The README's first advice is that it is best practice to pin your images to an explicit image tag, and the rest of that section exists so you can read one.
A versioned tag looks like openresty/openresty:1.29.2.4-1-noble. The first part is the OpenResty version, then a build counter, then the operating system codename. So 1.29.2.4-1-resolute is a built-from-source Ubuntu Resolute Raccoon image, 1.29.2.4-1-noble is built-from-source Ubuntu Noble Narwhal, 1.29.2.4-1-jammy is built-from-source Ubuntu Jammy Jellyfish, 1.29.2.4-1-bookworm-fat is built-from-upstream Debian Bookworm, 1.29.2.4-1-alpine is built-from-source Alpine, and 1.29.2.4-1-alpine-apk is built-from-upstream Alpine. The restyrepo tag, 1.31.1.1-1-restyrepo, is a built-from-source build of the OpenResty GitHub branch on Debian Trixie, and 1.31-alpine is the latest Alpine image in the 1.31 release series.
So there are two axes in every tag, and conflating them is the common mistake. The operating system suffix says which base, and the flavor part of the name says whether the image was assembled from upstream OpenResty packages or compiled from source in this repository.
The untagged names follow the same convention with the version dropped, so openresty/openresty:resolute is the latest Ubuntu Resolute build, and there is a matching set for noble, jammy, alpine and restyrepo.
The reason upstream and source builds are not interchangeable is stated in the README. The flavors available and built from upstream OpenResty packages are alpine-apk, the bookworm family, fedora and rocky, and windows. The flavors built from source are intended for more advanced and custom usage, caveat emptor, and that list includes alma, the alpine family, jammy, noble, resolute and restyrepo. The upstream package route gives you a build that upstream ships. The source route gives you a build of a specific commit with whatever configuration the Dockerfile applies, which is what you want when you need a patch, a module, or a version that upstream has not packaged yet.
There are also debug and valgrind variants, built with the openresty-debug and openresty-valgrind packages, available for the bookworm flavor.
Running the image, and the two filesystem details that bite
The usage section is short because the image is meant to be familiar. If you are happy with the build defaults, you can use the image from Docker Hub, with the tags listed at the top of the README, and the run command is:
docker run [options] openresty/openresty:bookworm-fatThe options are the usual ones, with -p to map ports, -v to map volumes, and -d to daemonize.
Two filesystem details are worth knowing before you hit them.
The first is logging. docker-openresty symlinks /usr/local/openresty/nginx/logs/access.log and error.log to /dev/stdout and /dev/stderr respectively, so that Docker logging works correctly. The catch is that this is tied to the default paths. If you change the log paths in your nginx.conf, you should symlink those paths as well. This is not possible with the windows image, which is a reasonable limitation given that Windows containers handle stdout differently.
The second is temporary directories. Temporary directories such as client_body_temp_path are stored in /var/run/openresty/. The README suggests you may consider mounting that volume rather than writing to a container-local directory. The reason is that those directories hold the buffered request bodies nginx is still processing, and a container-local path means they disappear with the container and are not shared between replicas. Again, this is not done for the windows image.
Both details point at the same underlying fact, which is that the image makes sensible defaults that you inherit whether you want them or not, and the defaults assume a Unix container with a writable and mountable filesystem.
The repository as a set of Dockerfiles, and the documents beside them
The top level of the repository is the image matrix itself, one directory per base image, each holding its Dockerfile or Dockerfiles. There is alpine/, alpine-apk/, alma/, bookworm/, fedora/, jammy/, noble/, resolute/, restyrepo/ and windows/, and each holds the Dockerfile or Dockerfiles for that flavor. The upstream family uses several files in one directory, such as bookworm/Dockerfile, Dockerfile.fat, Dockerfile.debug, Dockerfile.valgrind and Dockerfile.buildpack, while other families split variants across files, such as alpine/Dockerfile and alpine/Dockerfile.fat.
At the root are the two files that the base image is built on, nginx.conf and nginx.vh.default.conf, which is the site configuration the image starts with. Then there are the supporting files: a Taskfile.yml for the build tasks, scripts/ for the release automation, tests/ for the image tests, archive/ for older material, LATEST_SERIES, and a.dockerignore.
The two documents that matter for an adopter are the ones the README points to, and the distinction between them is instructive. BUILDING.md is where you learn to build your own custom and derived images, and HARDENING.md is where you learn to secure your operations. Both are referenced in the opening paragraph of the README, and neither is optional reading for anyone running this in production.
The hardening document in particular is a sign of how the project sees itself. A hardened image is not shipped as a separate tag here, which means the security work is something you do rather than something you pull. That is a deliberate design choice rather than an omission, and it has a cost: the more of the image you replace, the further you move from what upstream tests.
The repository also carries an AGENTS.md, an AUTHORS.md, a CHANGELOG.md, a COPYRIGHT file and a.github/ directory, and the README has a table of contents that also points to sections for image labels, the Docker CMD, the OPM, LuaRocks, and a Tips and Pitfalls section, which are the operational details that only matter once you are running the image rather than just pulling it.
Editorial conclusion
docker-openresty suits anyone deploying OpenResty in containers who wants an image built by the upstream project rather than a community one, and the tag table is worth reading before you choose, because the fat, slim, apk and source-built variants differ in more than size. It is the wrong choice if you need a hardened image out of the box, because the README points to HARDENING.md as a document you follow yourself rather than a hardened image you pull, and it is the wrong choice if you need the most recent OpenResty, since the restyrepo flavor tracks a GitHub branch and the versioned tags move on their own schedule. Before deploying, pin an explicit tag, check whether you want the upstream or source-built flavor, and remember that the log symlinks to stdout are tied to the default nginx.conf paths.
Frequently asked questions
Which OpenResty Docker image should I use?
The README recommends pinning an explicit tag. A versioned tag such as openresty/openresty:1.29.2.4-1-noble gives the OpenResty version, a build number and the operating system codename, and the flavor part tells you whether the image was built from upstream OpenResty packages or from source in this repository.
What is the difference between the upstream and source-built images?
The alpine-apk, bookworm, fedora, rocky and windows flavors are built from upstream OpenResty packages, so they use the builds that upstream ships and tests. The flavors built from source, which include alma, the alpine family, jammy, noble, resolute and restyrepo, are intended for more advanced and custom usage, which the README qualifies with caveat emptor.
Where are the OpenResty images published?
The CI/CD pipeline builds to the GitHub Container Registry as the primary source, at ghcr.io/neomantra/openresty, and the images are then mirrored to Docker Hub as openresty/openresty for convenience and backward compatibility.
How do I get the access and error logs into Docker logging?
The image symlinks /usr/local/openresty/nginx/logs/access.log and error.log to /dev/stdout and /dev/stderr. If you change the log paths in your nginx.conf you need to symlink those paths as well, and this is not possible with the windows image.
Should I mount a volume for nginx temporary directories?
Temporary directories such as client_body_temp_path are stored in /var/run/openresty/, and the README says you may consider mounting that volume rather than writing to a container-local directory. This is not done for the windows image.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/openresty-docker-openresty)Was this useful?