| title | Run a Gateway |
|---|---|
| id | run-a-gateway |
This guide explains how to use the swarm-gateway tool to set up your node in gateway mode. Running your node in gateway mode exposes it publicly, allowing access through any typical browser or http API.
:::info Historically, the main tool for running a Swarm HTTP gateway was gateway-proxy, however it is planned to be deprecated in favor of swarm-gateway.
At the time of writing, gateway-proxy still contains some features that are not yet implemented in swarm-gateway - unless you have a specific need for these features however, swarm-gateway is strongly recommended.
:::
This guide describes how to run a Swarm HTTP gateway using swarm-gateway and Bee with a minimal configuration.
At the end of this section, the gateway will be reachable at:
http://your-domain.example
Swarm content will be accessible at:
http://your-domain.example/bzz/<reference>/
:::warning Security notice This setup uses plain HTTP.
Traffic is not encrypted and any Authorization headers can be observed by intermediaries on the network path. This configuration is not suitable for production use.
The purpose of this section is to verify that the gateway is working. HTTPS is added in a later part of the guide. :::
The guide in this section:
- Runs
swarm-gatewayusing Docker - Connects it to an existing Bee node
- Exposes it publicly over HTTP
:::danger This part of the guide does not cover setting up TLS, so your gateway will be accessible through plain HTTP, not HTTPS, making it highly insecure. It should not be exposed publicly without first setting up TLS, which is covered in the next section. :::
- A VPS with:
- A public IP address
- Port 80 open
- Docker
- A domain for hosting your gateway publicly
- A running Bee node in Docker
- A valid stamp batch
Create an A record in your DNS provider:
your-domain.example -> <your-server-ip>
ADD SCREENSHOT
After DNS propagation, verify that the domain resolves to your server (this may take some time, to verify more quickly, try pinging from a different machine or VPS):
ping your-domain.exampleThe gateway container must be able to communicate with your Bee node, for this, both containers must be on the same Docker network.
Create a network and attach the Bee container to it:
docker network create swarm-net
docker network connect swarm-net bee-1Verify:
docker network inspect swarm-netThe output should list bee-1 as an attached container.
docker pull ethersphere/swarm-gateway:0.1.3Start the gateway container:
docker run -d --restart unless-stopped \
--name swarm-gateway \
--network swarm-net \
-p 80:3000 \
-e HOSTNAME="your-domain.example" \
-e BEE_API_URL="http://bee-1:1633" \
-e DATABASE_CONFIG="{}" \
ethersphere/swarm-gateway:0.1.3In this configuration, database-backed features such as subdomain rewrites and moderation are not configured.
From your local machine (not the server on your VPS):
curl http://your-domain.example/healthExpected output:
OK
Upload a file using Bee:
echo "hello swarm" > test.txt
swarm-cli upload test.txtThis will print a Swarm reference.
Open the file through the gateway in your browser:
http://your-domain.example/bzz/<REFERENCE>/Or from the terminal:
url -i http://your-domain.example/bzz/<REFERENCE>/The file contents should be returned.
Example terminal output:
600/
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, swarm-postage-batch-id, swarm-deferred-upload
accept-ranges: bytes
access-control-expose-headers: Content-Disposition
content-disposition: inline; filename="test.txt"
content-type: text/plain; charset=utf-8
date: Mon, 02 Feb 2026 10:21:39 GMT
Content-Length: 12
ETag: W/"c-5RZWYiFSSX7yHMJRTWWjxA9B9oo"
Connection: keep-alive
Keep-Alive: timeout=5
hello swarmBy default, the gateway allows anyone to upload content using your Bee node.
To restrict uploads, set:
AUTH_SECRET— a long random stringSOFT_AUTH=true— only require authentication for POST requests
Example (add these lines to the docker run command):
-e AUTH_SECRET="replace-with-a-long-random-secret" \
-e SOFT_AUTH="true" \See the Swarm Gateway README for more information about authentication and other options.
At this point, you have:
- A working Swarm HTTP gateway
- Connected to your Bee node
- Content accessible publicly over
/bzz/<reference>
The setup is intentionally minimal and suitable for testing and development, however without TLS, it is not secure and should never be used in production or publicly exposed.
The next section explains how to enable TLS so that your gateway can be securely accessed through HTTPS.
This section explains how to secure your gateway using TLS (HTTPS) with Caddy.
Caddy is used here as a front-facing web server that automatically manages TLS certificates and forwards traffic to swarm-gateway.
In this setup:
- Caddy is responsible only for HTTPS and certificate management
swarm-gatewaycontinues to act as the application gateway and reverse proxy for Bee
At the end of this section, your gateway will be reachable at:
https://your-domain.example
And all HTTP traffic will be automatically redirected to HTTPS.
In addition to the prerequisites from Part 1:
- Your domain must already point to your VPS IP address
- Ports 80 and 443 must be open on your VPS firewall
Caddy will become the public entry point, so swarm-gateway should no longer be exposed directly.
Stop and remove the existing container:
docker stop swarm-gateway
docker rm swarm-gatewayRecreate it without publishing port 80:
docker run -d --restart unless-stopped \
--name swarm-gateway \
--network swarm-net \
-e HOSTNAME="your-domain.example" \
-e BEE_API_URL="http://bee-1:1633" \
-e DATABASE_CONFIG="{}" \
ethersphere/swarm-gateway:0.1.3The gateway is now only accessible from within the Docker network.
Create a directory for the Caddy configuration:
mkdir -p ~/caddy
cd ~/caddyCreate a file named Caddyfile:
vim CaddyfileAdd the following configuration (replace the domain):
your-domain.example {
reverse_proxy swarm-gateway:3000
}Start Caddy in Docker and attach it to the same Docker network:
docker run -d --restart unless-stopped \
--name caddy \
--network swarm-net \
-p 80:80 \
-p 443:443 \
-v $HOME/caddy/Caddyfile:/etc/caddy/Caddyfile \
-v caddy_data:/data \
-v caddy_config:/config \
caddy:2Caddy will automatically:
- Obtain a TLS certificate for your domain
- Renew it before it expires
- Redirect all HTTP traffic to HTTPS
From your local machine:
curl https://your-domain.example/healthExpected output:
OK
You can also verify that HTTP is redirected to HTTPS:
curl -I http://your-domain.example/healthExample terminal output:
HTTP/1.1 308 Permanent Redirect
Connection: close
Location: https://your-domain.example/health
Server: Caddy
Date: Mon, 02 Feb 2026 10:31:17 GMT:::caution This section is under construction. Further guidance will be available in the near future. For the time being, please join the #builders channel on the Swarm Discord server. :::
You can find a list of all available options on the Swarm Gateway README on GitHub. Database options can also be set using the DATABASE_CONFIG environment variable.