Enhance APISIX gateway setup with dashboard support and improved configurations

- Update Makefile to reflect full gateway stack commands
- Add dashboard exposure and configuration details in README
- Modify configuration files for etcd and APISIX to support admin API
- Expand Docker and Podman compose files to include APISIX dashboard and bootstrap service
- Introduce bootstrap script for seeding routes and upstreams
- Create dashboard configuration file with authentication settings
This commit is contained in:
2026-06-07 22:38:06 +08:00
parent 8dd42653cc
commit 1844f617ed
9 changed files with 284 additions and 11 deletions
+4 -4
View File
@@ -8,10 +8,10 @@ COMPOSE_FILE:=$(if $(filter podman,$(CONTAINER_ENGINE)),podman-compose.yml,docke
help:
@echo "Targets:"
@echo " up Start APISIX gateway"
@echo " down Stop APISIX gateway"
@echo " logs Follow APISIX logs"
@echo " ps Show gateway containers"
@echo " up Start APISIX, etcd, dashboard, and route bootstrap"
@echo " down Stop the full gateway stack"
@echo " logs Follow gateway stack logs"
@echo " ps Show gateway stack containers"
@echo ""
@echo "Detected container engine: $(if $(CONTAINER_ENGINE),$(CONTAINER_ENGINE),none)"
@echo "Detected compose command: $(if $(COMPOSE_CMD),$(COMPOSE_CMD),none)"
+24 -2
View File
@@ -6,6 +6,7 @@ This project runs Apache APISIX as an API gateway in front of the LTA DataMall F
- Proxies `/api/v1/*` to the backend service
- Forwards backend health and docs endpoints through the gateway
- Exposes Apache APISIX Dashboard for route inspection and editing
- Keeps gateway configuration isolated from the API service project
## Prerequisites
@@ -18,7 +19,7 @@ Podman uses `host.containers.internal`.
This project keeps separate compose wiring for each runtime and the gateway `Makefile` selects the right file automatically.
If your backend runs on a different host or port, update the upstream target in [conf/apisix.yaml](conf/apisix.yaml) for Docker or [conf/apisix.podman.yaml](conf/apisix.podman.yaml) for Podman.
If your backend runs on a different host or port, update `BACKEND_HOST` and `BACKEND_PORT` in the selected compose file.
## Run
@@ -29,7 +30,18 @@ If your backend runs on a different host or port, update the upstream target in
make up
```
3. Send requests through APISIX:
3. Open the dashboard:
```bash
open http://localhost:9000
```
Dashboard default login:
- Username: `admin`
- Password: `admin`
4. Send requests through APISIX:
```bash
curl "http://localhost:9080/api/v1/bus-arrival?BusStopCode=83139&ServiceNo=3&Date=2025-01-01"
@@ -49,3 +61,13 @@ make ps
## Ports
- `9080` - APISIX proxy listener
- `9180` - APISIX Admin API
- `9000` - APISIX Dashboard
## Notes
- This stack uses APISIX traditional mode with etcd so the dashboard can manage routes.
- The initial upstream and routes are seeded automatically by `scripts/bootstrap-routes.sh` when the stack starts.
- `conf/apisix.yaml` and `conf/apisix.podman.yaml` are kept only as standalone-mode references and are not loaded by the dashboard-enabled stack.
- Change the default dashboard login and the Admin API key before using this outside local development.
+1
View File
@@ -1,3 +1,4 @@
# Reference only: the dashboard-enabled stack now seeds routes via the Admin API.
routes:
- id: 1
uri: /healthz
+1
View File
@@ -1,3 +1,4 @@
# Reference only: the dashboard-enabled stack now seeds routes via the Admin API.
routes:
- id: 1
uri: /healthz
+20 -3
View File
@@ -1,7 +1,24 @@
apisix:
node_listen: 9080
enable_admin: true
deployment:
role: data_plane
role_data_plane:
config_provider: yaml
role: traditional
role_traditional:
config_provider: etcd
admin:
admin_key_required: true
admin_key:
- name: admin
key: apisix-dev-admin-key
role: admin
allow_admin:
- 0.0.0.0/0
admin_listen:
ip: 0.0.0.0
port: 9180
etcd:
host:
- http://etcd:2379
prefix: /apisix
timeout: 30
+104
View File
@@ -0,0 +1,104 @@
conf:
listen:
port: 9000
allow_list:
- 0.0.0.0/0
etcd:
endpoints:
- etcd:2379
mtls:
key_file: ""
cert_file: ""
ca_file: ""
log:
error_log:
level: warn
file_path: /dev/stderr
access_log:
file_path: /dev/stdout
max_cpu: 0
authentication:
secret:
apisix-dashboard-local-dev-secret
expire_time: 3600
users:
- username: admin
password: admin
plugins:
- api-breaker
- authz-casbin
- authz-casdoor
- authz-keycloak
- aws-lambda
- azure-functions
- basic-auth
- clickhouse-logger
- client-control
- consumer-restriction
- cors
- csrf
- datadog
- echo
- error-log-logger
- ext-plugin-post-req
- ext-plugin-post-resp
- ext-plugin-pre-req
- fault-injection
- file-logger
- forward-auth
- google-cloud-logging
- grpc-transcode
- grpc-web
- gzip
- hmac-auth
- http-logger
- ip-restriction
- jwt-auth
- kafka-logger
- kafka-proxy
- key-auth
- ldap-auth
- limit-conn
- limit-count
- limit-req
- loggly
- mocking
- opa
- openid-connect
- opentelemetry
- openwhisk
- prometheus
- proxy-cache
- proxy-control
- proxy-mirror
- proxy-rewrite
- public-api
- real-ip
- redirect
- referer-restriction
- request-id
- request-validation
- response-rewrite
- rocketmq-logger
- server-info
- serverless-post-function
- serverless-pre-function
- skywalking
- skywalking-logger
- sls-logger
- splunk-hec-logging
- syslog
- tcp-logger
- traffic-split
- ua-restriction
- udp-logger
- uri-blocker
- wolf-rbac
- zipkin
- elasticsearch-logger
- openfunction
- tencent-cloud-cls
- ai
- cas-auth
+39 -1
View File
@@ -1,10 +1,48 @@
services:
etcd:
image: quay.io/coreos/etcd:v3.5.14
container_name: lta-datamall-etcd
command:
- /usr/local/bin/etcd
- --name=etcd
- --advertise-client-urls=http://etcd:2379
- --listen-client-urls=http://0.0.0.0:2379
restart: unless-stopped
apisix:
image: apache/apisix:3.11.0-debian
container_name: lta-datamall-apisix
depends_on:
- etcd
volumes:
- ./conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
- ./conf/apisix.yaml:/usr/local/apisix/conf/apisix.yaml:ro
ports:
- "9080:9080"
- "9180:9180"
restart: unless-stopped
apisix-dashboard:
image: apache/apisix-dashboard:3.0.1-alpine
container_name: lta-datamall-apisix-dashboard
depends_on:
- etcd
volumes:
- ./conf/dashboard.yaml:/usr/local/apisix-dashboard/conf/conf.yaml:ro
ports:
- "9000:9000"
restart: unless-stopped
apisix-bootstrap:
image: curlimages/curl:8.8.0
container_name: lta-datamall-apisix-bootstrap
depends_on:
- apisix
environment:
APISIX_ADMIN_URL: http://apisix:9180
APISIX_ADMIN_KEY: apisix-dev-admin-key
BACKEND_HOST: host.docker.internal
BACKEND_PORT: "8068"
volumes:
- ./scripts/bootstrap-routes.sh:/bootstrap-routes.sh:ro
entrypoint: ["sh", "/bootstrap-routes.sh"]
restart: "no"
+39 -1
View File
@@ -1,10 +1,48 @@
services:
etcd:
image: quay.io/coreos/etcd:v3.5.14
container_name: lta-datamall-etcd
command:
- /usr/local/bin/etcd
- --name=etcd
- --advertise-client-urls=http://etcd:2379
- --listen-client-urls=http://0.0.0.0:2379
restart: unless-stopped
apisix:
image: apache/apisix:3.11.0-debian
container_name: lta-datamall-apisix
depends_on:
- etcd
volumes:
- ./conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro
- ./conf/apisix.podman.yaml:/usr/local/apisix/conf/apisix.yaml:ro
ports:
- "9080:9080"
- "9180:9180"
restart: unless-stopped
apisix-dashboard:
image: apache/apisix-dashboard:3.0.1-alpine
container_name: lta-datamall-apisix-dashboard
depends_on:
- etcd
volumes:
- ./conf/dashboard.yaml:/usr/local/apisix-dashboard/conf/conf.yaml:ro
ports:
- "9000:9000"
restart: unless-stopped
apisix-bootstrap:
image: curlimages/curl:8.8.0
container_name: lta-datamall-apisix-bootstrap
depends_on:
- apisix
environment:
APISIX_ADMIN_URL: http://apisix:9180
APISIX_ADMIN_KEY: apisix-dev-admin-key
BACKEND_HOST: host.containers.internal
BACKEND_PORT: "8068"
volumes:
- ./scripts/bootstrap-routes.sh:/bootstrap-routes.sh:ro
entrypoint: ["sh", "/bootstrap-routes.sh"]
restart: "no"
@@ -0,0 +1,52 @@
#!/bin/sh
set -eu
ADMIN_URL="${APISIX_ADMIN_URL:-http://apisix:9180}"
ADMIN_KEY="${APISIX_ADMIN_KEY:?APISIX_ADMIN_KEY is required}"
BACKEND_HOST="${BACKEND_HOST:?BACKEND_HOST is required}"
BACKEND_PORT="${BACKEND_PORT:-8068}"
request() {
method="$1"
path="$2"
data="$3"
http_code=$(curl -sS -o /tmp/apisix-bootstrap-response.json -w "%{http_code}" \
-X "$method" \
-H "X-API-KEY: $ADMIN_KEY" \
-H "Content-Type: application/json" \
"$ADMIN_URL$path" \
-d "$data")
if [ "$http_code" -lt 200 ] || [ "$http_code" -ge 300 ]; then
echo "APISIX admin request failed for $path with status $http_code"
cat /tmp/apisix-bootstrap-response.json
exit 1
fi
}
echo "Waiting for APISIX Admin API at $ADMIN_URL"
for _ in $(seq 1 60); do
if curl -fsS -H "X-API-KEY: $ADMIN_KEY" "$ADMIN_URL/apisix/admin/routes" >/dev/null 2>&1; then
break
fi
sleep 2
done
if ! curl -fsS -H "X-API-KEY: $ADMIN_KEY" "$ADMIN_URL/apisix/admin/routes" >/dev/null 2>&1; then
echo "APISIX Admin API did not become ready in time"
exit 1
fi
echo "Seeding upstream and routes"
request PUT /apisix/admin/upstreams/1 "{\"id\":\"1\",\"type\":\"roundrobin\",\"nodes\":{\"${BACKEND_HOST}:${BACKEND_PORT}\":1}}"
request PUT /apisix/admin/routes/1 '{"id":"1","uri":"/healthz","upstream_id":"1"}'
request PUT /apisix/admin/routes/2 '{"id":"2","uri":"/readyz","upstream_id":"1"}'
request PUT /apisix/admin/routes/3 '{"id":"3","uri":"/openapi.json","upstream_id":"1"}'
request PUT /apisix/admin/routes/4 '{"id":"4","uri":"/docs","upstream_id":"1"}'
request PUT /apisix/admin/routes/5 '{"id":"5","uri":"/redoc","upstream_id":"1"}'
request PUT /apisix/admin/routes/6 '{"id":"6","uri":"/api/v1/*","upstream_id":"1"}'
echo "APISIX bootstrap complete"