Block ip port access

1. The problem I’m having:

Caddy deployed with docker compose, listening on ports 80 and 443, my application is deployed on port 8877, through domain.com reverse proxy to port 8877, domain access is normal and ip:port is also accessible, but now I want to allow only the domain access but not the ip port access, can I achieve this through caddy configuration?

2. Error messages and/or full log output:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

2.9.1

3. Caddy version:

4. How I installed and ran Caddy:

a. System environment:

b. Command:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

c. Service/unit/compose file:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

d. My complete Caddy config:

PASTE OVER THIS, BETWEEN THE ``` LINES.
Please use the preview pane to ensure it looks nice.

5. Links to relevant resources:

Is this application in a container? If it is, you don’t need to expose the ports, just have Caddy reverse_proxy the app on that port.

Post your compose.yaml file if it is in a container.

1 Like

The application is not running in a container.
tcp6 0 0 :::8877 :::* .

Incidentally, I have another application that runs in a container with the following configuration:

version: '3.3'
services:
  easyimage:
    image: ddsderek/easyimage:latest
    container_name: easyimage
    ports:
      - '3004:443'
    environment:
      - TZ=Asia/Shanghai
      - PUID=1000
      - PGID=1000
      - DEBUG=false
    volumes:
      - './easyimage/config:/app/web/config'
      - './easyimage/i:/app/web/i'
    restart: unless-stopped

If I want to disable port access live allow domain access, caddy how to set it up?

1 Like

If your app on port 8877 is accessible via IP:8877 when Caddy isn’t running, then Caddy can’t prevent access to it.

Depending on how your app is deployed, you could use:

  • Docker to control how port 8877 is exposed if the app is deployed via Docker Compose.
  • A local firewall if the app is a regular application (i.e., not running in Docker).

Without seeing your Caddyfile and Docker Compose YAML file, we can only guess what you’re doing.

2 Likes

If the app isn’t running in a container, you can:

  • Configure the application to listen on a loopback interface and set up Caddy to proxy to, for example, 127.0.0.1:8877, or
  • Use a local firewall (iptables?) to block access to port 8877 from all but local interfaces.
1 Like

I see what you mean, I misunderstood before.

Caddy can’t do that for you. However, you can modify your Docker Compose setup by replacing this:

    ports:
      - '3004:443'

with, for example, this:

    ports:
      - '127.0.0.1:3004:443'

If your Caddy container is deployed with network_mode: host, you can use:

reverse_proxy 127.0.0.1:3004

If your Caddy container is running in bridge mode under the same bridge as easyimage, you don’t need to expose the easyimage port via ports. Instead, you can use:

reverse_proxy easyimage:443
3 Likes

If caddy is using bridge mode, the web application (port 8833) is not deployed using docker, and the firewall closes port 8833, is caddy not able to proxy the application?

Post your Caddyfile and Docker Compose file - there’s too much guesswork in trying to figure out what you’re trying to do.

1 Like

caddyfile

domain.com {
        reverse_proxy  127.0.0.1:8883
}

caddy compose.yml

services:
  caddy:
    image: caddy:latest
    container_name: caddy  
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy_data:/data
      - ./caddy_config:/config

volumes:
  caddy_data:
  caddy_config:

Port 8883 applications running on the host machine(not in docker) and Firewall closed port 8883 .

In this scenario, isn’t caddy unable to properly proxy this application?

It looks like you’re running Caddy in bridge mode. So this:

domain.com {
        reverse_proxy  127.0.0.1:8883
}

will make Caddy proxy to itself inside the container.

To achieve what you want, add this to your Caddy Docker Compose file:

network_mode: host

and remove ports section.

Edit:

I should have mentioned that network_mode: host works only on Linux. So if you’re running your Caddy container on a different OS, or you simply don’t want to change the network mode, update your Caddyfile configuration from this:

domain.com {
        reverse_proxy  127.0.0.1:8883
}

to this:

domain.com {
    reverse_proxy host.docker.internal:8883
}
1 Like

I used the method you described above. Errors reported in caddy logs after domain access

{"level":"error","ts":1742630104.1104808,"logger":"http.log.error","msg":"dial tcp: lookup host.docker.internal on 127.0.0.11:53: no such host","request":

I tried modifying caddy’s compose configuration

services:
  caddy:
    image: caddy:latest
    container_name: caddy  
    restart: unless-stopped
    ports:
      - "80:80"
      - "443:443"
      - "443:443/udp"
    volumes:
      - ./Caddyfile:/etc/caddy/Caddyfile
      - ./caddy_data:/data
      - ./caddy_config:/config

    extra_hosts:
      - "host.docker.internal:172.17.0.1"    
volumes:
  caddy_data:
  caddy_config:

then error logs

{"level":"error","ts":1742631380.4801953,"logger":"http.log.error","msg":"dial tcp 172.17.0.1:8883: i/o timeout","request"

There’s an extra 1 there that shouldn’t be.


So given your new compose.yaml configuration, I presume you’re running on Windows? I don’t believe the extra_hosts should be necessary, since Docker automatically handles the DNS for the host machine’s IP from host.docker.internal. Leave the reverse_proxy on host.docker.internal, but remove the extra_hosts from your compose.yaml.