apache/apisix-docker: running the APISIX gateway in containers
the docker for Apache APISIX
At a glance
- What is it?
- The apisix-docker repository packages Apache APISIX for containers, and its README is mostly a set of runnable recipes: stand-alone mode with a single apisix.yaml, two ways of attaching an etcd configuration centre, the admin API check on port 9180, and a reload command that avoids downtime. The Makefile pins the gateway to version 3.19.0 while the only release tag in the repository is from 2020.
- Who is it for?
- Use this repository when you want to run Apache APISIX in Docker and want a recipe you can copy rather than a chart to read, because the README gives the exact commands for stand-alone mode, for etcd over host networking and for etcd over a bridge network with a mounted config.yaml.
- Can I use it commercially?
- Yes. Apache-2.0 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 last received commits 24 days ago.
- 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
A packaging repository, with the gateway version pinned in one variable
This repository does not contain the gateway. It contains the containers that ship it, and the README is explicit that it points at the Apache APISIX website and documentation for the gateway itself. Apache APISIX is described as a dynamic, real-time, high-performance API Gateway, with traffic management features covering load balancing, dynamic upstream, canary release, circuit breaking, authentication and observability, used for both north-south traffic and east-west traffic between services.
The version you actually get is decided in the Makefile rather than by a tag, and the variables at the top of that file are the first thing to read. APISIX_VERSION defaults to 3.19.0, MAX_APISIX_VERSION defaults to the same value, the image name is apache/apisix and the tar name is apache_apisix, and the source it builds from is the apache/apisix repository on its master branch. The dashboard is a separate image, apache/apisix-dashboard, at version 3.0.1 by default. The default goal of the Makefile is help, which is a small courtesy that tells you the file is meant to be driven.
The directory layout shows the range of packaging work: debian/, redhat/ and ubuntu/ for the distributions, all-in-one/ and compose/ for bundled images, dashboard/ for the dashboard image, utils/ for build helpers, docs/ and example/ for what a user needs.
The example directory is where the practical value is. It holds docker-compose.yml, docker-compose-standalone.yml and docker-compose-arm64.yml, plus apisix_conf/, etcd_conf/, grafana_conf/, prometheus_conf/, mkcert/ and upstream/ subdirectories, so the repository ships a composed environment rather than a single container.
Stand-alone mode is one environment variable and one YAML file
APISIX supports stand-alone mode and also supports the use of etcd database as the configuration centre. In stand-alone mode, APISIX uses apisix.yaml as the configuration center to store routing, upstream, consumer and other information, and after APISIX is started it will load the apisix.yaml file regularly to update the corresponding configuration information.
That regular reload is what makes the rest of the recipe work, because the container is started with the file absent and the file is written afterwards:
docker run -d --name apache-apisix \
-p 9080:9080 \
-e APISIX_STAND_ALONE=true \
apache/apisixThe route and plugin configuration is then pushed into the running container with a heredoc written to /usr/local/apisix/conf/apisix.yaml:
docker exec -i apache-apisix sh -c 'cat > /usr/local/apisix/conf/apisix.yaml <<_EOC_
routes:
-
id: httpbin
uri: /*
upstream:
nodes:
"httpbin.org": 1
type: roundrobin
plugin_config_id: 1
plugin_configs:
-
id: 1
plugins:
response-rewrite:
body: "Hello APISIX\n"
desc: "response-rewrite"
#END
_EOC_'The example route matches any URI, sends traffic to httpbin.org with roundrobin balancing, and attaches a plugin config that rewrites the response body to Hello APISIX. The test is a single request:
curl http://127.0.0.1:9080/which the README shows returning Hello APISIX.
For a local environment this is the whole setup, and it is a fair argument for the stand-alone mode in general: no extra database, one file to read, and the file can live in a volume or in a configuration management system. What it does not give you is a shared configuration centre across several gateway instances, which is where etcd comes in.
etcd over host networking, which is the shortest path
The first etcd recipe starts etcd on the host network and then starts APISIX on the same network. The README is clear about the prerequisites: make sure that all the required ports, default 9080, 9443 and 2379, are available and not used by other system processes.
docker run -d \
--name etcd \
--net host \
-e ALLOW_NONE_AUTHENTICATION=yes \
-e ETCD_ADVERTISE_CLIENT_URLS=http://127.0.0.1:2379 \
bitnamilegacy/etcd:3.5.11docker run -d \
--name apache-apisix \
--net host \
apache/apisixTwo things in that block deserve attention. The etcd container runs with ALLOW_NONE_AUTHENTICATION=yes, which is the setting that lets clients connect without credentials, and it is a development convenience that should not survive into a deployment. The image reference is bitnamilegacy/etcd:3.5.11, an exact version of etcd rather than a floating tag, which is the right instinct.
Using the host network means the containers share the host's network namespace, so there is no port mapping to reason about and the two containers find each other on localhost. The cost is that the containers are not isolated from the host's ports, which is exactly why the README tells you to check 9080, 9443 and 2379 first.
etcd over a bridge network, with the config file mounted in
The second recipe creates a Docker bridge network, and the difference is that APISIX then needs a configuration file to know where etcd is and who may call the admin API.
The network creation and the etcd start are one command, and the README asks you to inspect the result for the subnet address:
docker network create apisix-network --driver bridge && \
docker network inspect -v apisix-network && \
docker run -d --name etcd \
--network apisix-network \
-p 2379:2379 \
-p 2380:2380 \
-e ALLOW_NONE_AUTHENTICATION=yes \
-e ETCD_ADVERTISE_CLIENT_URLS=http://127.0.0.1:2379 \
bitnamilegacy/etcd:3.5.11The config file is then written into the current directory, and the comment in it is the security instruction of the whole README:
cat << EOF > $(pwd)/config.yaml
deployment:
role: traditional
role_traditional:
config_provider: etcd
admin:
allow_admin:
- 0.0.0.0/0 # Please set it to the subnet address you obtained.
# If not set, by default all IP access is allowed.
etcd:
host:
- "http://etcd:2379"
prefix: "/apisix"
timeout: 30
EOFSo the default is that all IP access is allowed to the admin API, and the recipe tells you to replace 0.0.0.0/0 with the subnet address from the network inspect step. The rest of the file selects the traditional deployment role with etcd as the config provider, points at the etcd service by its container name, namespaces the keys under the /apisix prefix, and sets a 30 second timeout.
APISIX is then started on that network with the file mounted and the admin port published:
docker run -d --name apache-apisix \
--network apisix-network \
-p 9080:9080 \
-p 9180:9180 \
-v $(pwd)/config.yaml:/usr/local/apisix/conf/config.yaml \
apache/apisixPort 9080 carries the traffic, and port 9180 is the admin API, which is where the health check goes next.
The admin check, and the key that is printed in the documentation
The test for the etcd setup is a request to the admin API on port 9180 with an API key header:
curl "http://127.0.0.1:9180/apisix/admin/services/" \
-H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'A working gateway answers with an empty service list:
{
"total": 0,
"list": []
}That empty result is the point of the check. It proves the admin API is up, the key was accepted and etcd is reachable, without needing a route configured first.
The key in that command is the default APISIX admin key, printed in the README for convenience, which is exactly why it must be replaced. It is a published value, and the same applies to the ALLOW_NONE_AUTHENTICATION setting on the etcd container in both recipes. Between the two defaults, a deployment that follows the documentation literally exposes an unauthenticated etcd and a known admin key, with the admin API reachable from any address because allow_admin is 0.0.0.0/0 until you change it. The recipes are correct as demonstrations of the plumbing; the three values are the ones to change before they face a network.
For changing configuration without a restart, the README gives a way into the running container:
docker exec -it apache-apisix bashand points at ./conf/config.yaml and ./conf/config-default.yaml for the default configuration to copy.
Reloading without downtime, and the Kubernetes route
If you change your custom configuration, you can reload APISIX without downtime by running one command inside the container:
docker exec -it apache-apisix apisix reloadThis matters more in the etcd mode than in the stand-alone one. In stand-alone mode the gateway polls apisix.yaml on a schedule, so a file change is picked up on its own. With etcd, the configuration centre pushes changes, and the reload command is the explicit way to make a local edit take effect in the running process.
The Kubernetes path is a different repository. During the deployment process, in addition to the above operations, APISIX also derived the apisix-ingress-controller, which can be deployed and used in the K8s environment more conveniently. So this repository is the container path, and the ingress controller is where the Kubernetes case is handled.
The example directory is where to look for a fuller environment. Besides the three compose files, it carries grafana_conf/ and prometheus_conf/ for observability, mkcert/ for local certificate handling, upstream/ for a fake upstream service, apisix_conf/ and etcd_conf/ for the configuration of each side. That is a complete local setup of the gateway, its configuration centre, its monitoring stack and a backend to route to.
Support is handled through the project Slack and mailing list, both linked at the end of the README, and the roadmap is tracked on the Apache APISIX projects roadmap issue.
One tag from 2020, and a tree that is still being worked on
The release history of this repository is a single entry: v1.x, described as the source code for versions 0.9 to 1.5, published on 2020-12-01. That is the only tag, and it belongs to a line of APISIX that long predates the 3.19.0 the Makefile pins. Anyone looking for a release artefact in this repository is looking in the wrong place, because the images are what this project produces, and the version they carry comes from the Makefile variable rather than from a tag.
The tree itself is not dormant. The last push was on 2026-09-29, the repository is not archived, and the default branch is master. The project is an Apache Software Foundation repository, complete with a .asf.yaml, a MAINTAINING.md file, a LICENSE and a README carrying the standard Apache licence notice, and a Makefile whose every line starts with the ASF licence header.
Licensing is straightforward: the repository is under the Apache License, Version 2.0, the same terms as the gateway it packages.
For a reader deciding how to use this, the practical summary is that the Makefile is the release mechanism, the examples are the documentation, and the two security defaults, ALLOW_NONE_AUTHENTICATION and allow_admin set to 0.0.0.0/0, are the parts of the recipe that have to change before the containers face anything you care about.
Editorial conclusion
Use this repository when you want to run Apache APISIX in Docker and want a recipe you can copy rather than a chart to read, because the README gives the exact commands for stand-alone mode, for etcd over host networking and for etcd over a bridge network with a mounted config.yaml. Do not copy the etcd example unchanged, since it starts etcd with ALLOW_NONE_AUTHENTICATION=yes and leaves allow_admin at 0.0.0.0/0, and do not treat the published admin key as a secret you can copy from the documentation. Before you deploy, set allow_admin to the subnet address the recipe tells you to look up, generate your own X-API-KEY, pin the etcd image version you reviewed, and check which APISIX version the Makefile pins, since the repository's only release tag predates the 3.x line it now builds.
Frequently asked questions
How do I run Apache APISIX in stand-alone mode with Docker?
Start the container with docker run -d --name apache-apisix -p 9080:9080 -e APISIX_STAND_ALONE=true apache/apisix, then write your routes and plugin configs into /usr/local/apisix/conf/apisix.yaml. In this mode APISIX uses apisix.yaml as the configuration centre and reloads it regularly.
How do I use etcd as the configuration centre for APISIX?
The README gives two solutions: one that starts etcd and APISIX on the host network, and one that creates a bridge network named apisix-network, starts etcd on it, writes a config.yaml with config_provider set to etcd and mounts that file into the APISIX container. The admin API is then published on port 9180.
How do I reload APISIX configuration without downtime?
Run docker exec -it apache-apisix apisix reload inside the running container. In stand-alone mode the gateway also picks up apisix.yaml changes on its own, since it loads that file regularly.
Which APISIX version does the apisix-docker Makefile build?
APISIX_VERSION defaults to 3.19.0, with MAX_APISIX_VERSION set to the same value, and the image is named apache/apisix. The dashboard is built separately as apache/apisix-dashboard at version 3.0.1.
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/apache-apisix-docker)Was this useful?