I cannot access services running in a container from the host

I created a Debian 11 container c inside a Debian 12 host. The container is running:

$ lxc ls
+------+---------+-----------------------+-------------------------+
| NAME |  STATE  |         IPV4          |    IPV6     |   TYPE    |
+------+---------+-----------------------+-------------------------+
| c    | RUNNING | 10.128.128.123 (eth0) | ... (eth0)  | CONTAINER |
+------+---------+-----------------------+-------------------------+

Then, I run a basic web service on port 3000 in the container.

c$ wget http://127.0.0.1:4567
--2023-12-26 10:49:15--  http://127.0.0.1:4567/
Connecting to 127.0.0.1:4567... connected.
HTTP request sent, awaiting response... 200 OK
Length: 33 [text/html]
Saving to: ‘index.html’

However, this fails when accessing the service from the host:

host$ wget http://10.128.128.123:4567
--2023-12-26 10:51:56--  http://10.128.128.123:4567/
Connecting to 10.128.128.123:4567... failed: Connection refused.

Additionally, I tested the network inside the container, and it seems it is listening on the port 4567.

c$ netstat -tl
Proto Recv-Q Send-Q Local Address           Foreign Address         State
tcp        0      0 localhost:4567          0.0.0.0:*               LISTEN     
tcp6       0      0 localhost:4567          [::]:*                  LISTEN

As I showed above, the service is not receiving requests from the host. What can be the source of the problem?

Your service needs to bind to the proper interface. I suspect it is only binding to localhost.

An easy way to do this is to bind to 0.0.0.0. This will bind the service to all interfaces.

Thank @jarrodu for your answer. I don’t know how I can bind a service to an interface. Which configuration file I should modify?

Let me explain a little more what I am doing. I created this simple service as the following Sinatra service (app.rb):

require 'sinatra'

set :port, 80

get '/' do
  'Hello world!'
end

I can run the service above with ruby app.rb, which by default creates a service on port 4567. In this case, I am also using the port 80, to be sure there is no filter on some uncommon ports.

This is the first time I have problems with accessing services from containers. Now, I launched two more containers from scratch, one with Debian and another with Ubuntu, to see if it was a problem in the container configuration. However, the result is the same. I also run the service on the host, which is accessible from the host itself.

I guess that there is a problem with the network between the host and the containers. However, I don’t see something special with the network. I just followed the predefined steps in lxd init when creating it.

lxc profile show default
config: {}
description: Default LXD profile
devices:
  eth0:
    name: eth0
    network: lxdbr0
    type: nic
  root:
    path: /
    pool: lxd01
    type: disk
name: default
used_by:
- /1.0/instances/measured-worm
- /1.0/instances/saving-lionfish

I don’t think it is the network. I think it is your Sinatra app configuration. You probably can set the host to 0.0.0.0.

As an experiment, could you try using Caddy? It is easy to install and use. You can configure the address from the command line.

You can see what I am talking about if you use localhost vs. 0.0.0.0 vs. the containers IP.

I will have time on the train tomorrow to test it myself. If you have a public repo, I could even try to run your app. Today is still Christmas. :beers:

If I remember correctly, you can specify the IP using the --listen flag.

Thank @jarrodu! I will take a look and I will post the code.

1 Like

I was able to reproduce what I was talking about. I am running Debian 12 as my host and I used a debian/12/cloud image for the container. I am using Incus 0.4.

So, in the container create an empty directory and an index.html file. Then,

caddy file-server --listen 0.0.0.0:8080 --root

the, you can curl from the host.

curl 10.128.128.123:8080

Now, try again with,

caddy file-server --listen 127.0.0.1:8080 --root

instead, and curl again from the host.

curl 10.128.128.123:8080

The first will connect, but the second will not.

If you can not reproduce my results, then you might want to try using Incus instead of lXD.

If you can reproduce my results, then you might want to use Incus instead of LXD, and figure out how to get Sinatra to bind to 0.0.0.0 instead of 127.0.0.1.

1 Like

You are right! The first version works and the second version does not. Thank you so much. Also, thank you for telling me about caddy. By the way, I plan to migrate to Incus soon.

1 Like