not accessible from other containers


I have 2 containers running on Docker created with a docker-compose file and 2 dockerfiles. One of the containers is a CUPS-PDF virtual printer. The other container is a java application.

The CUPS-PDF container is exposed at 631:631 and the cupsd.conf file has the Listen directive set to “Listen”. I can access both containers from the IDE and from a browser (http://localhost:631). However, the java container cannot connect to the CUPS-PDF container on If I stop the java container and run it on my IDE it connects to the CUPS-PDF printer container without any issues and the javax.print.PrintServiceLookUp can detect the printer, so it seems it is something with the docker network that is blocking the access to the CUPS-PDF printer container. Inside the java docker container it can curl to the CUPS-PDF container, however the javax.print.PrintServiceLookUp cannot detect the printer.

I made several tries and created a network for both containers but nothing seems to work.

Any ideas or some information that can be helpful?

It would be helpful, if you actually share the compose file AND the snippet of the code that runs into the problem, If the hostname uses a variable, then please show the value used during the tests.

Docker-compose file:
version: "3.7"

      context: ./
      dockerfile: ./printer/Dockerfile
    container_name: printer
    hostname: printer
      - "7192:7192"
      - "/tmp/app.jar:/service"
      context: ./
      dockerfile: ./cups/Dockerfile
    hostname: cups
      - '631:631'
    privileged: true
      - /dev/bus/usb
      - CUPSADMIN=admin
      - CUPSPASSWORD=password
    container_name: cups
    #platform: linux/amd64#change accordingly
    image: cups

Cups dockerfile.

FROM debian

RUN apt-get update \
&& apt-get install -y \
  sudo \
  whois \
  usbutils \
  cups \
  cups-client \
  cups-bsd \
  cups-filters \
  foomatic-db-compressed-ppds \
  printer-driver-all \
  openprinting-ppds \
  hpijs-ppds \
  hp-ppd \
  hplip \
  smbclient \
  printer-driver-cups-pdf \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

# Add user and disable sudo password checking
RUN useradd \
  --groups=sudo,lp,lpadmin \
  --create-home \
  --home-dir=/home/print \
  --shell=/bin/bash \
  --password=$(mkpasswd print) \
  print \
&& sed -i '/%sudo[[:space:]]/ s/ALL[[:space:]]*$/NOPASSWD:ALL/' /etc/sudoers

COPY printers.conf /etc/cups/printers.conf
COPY client.conf /etc/cups/client.conf
RUN ["chmod", "a+rw", "/etc/cups/printers.conf"]
RUN ["chmod", "a+rw", "/etc/cups/cupsd.conf"]

# Baked-in config file changes

#Run Script

RUN sed -i 's/Listen localhost:631/Listen' /etc/cups/cupsd.conf && \
    sed -i 's/Browsing Off/Browsing On/' /etc/cups/cupsd.conf && \
    sed -i 's/<Location \/>/<Location \/>\n  Allow All/' /etc/cups/cupsd.conf && \
    sed -i 's/<Location \/admin>/<Location \/admin>\n  Allow All\n  Require user @SYSTEM/' /etc/cups/cupsd.conf && \
    sed -i 's/<Location \/admin\/conf>/<Location \/admin\/conf>\n  Allow All/' /etc/cups/cupsd.conf && \
    echo "ServerAlias *" >> /etc/cups/cupsd.conf && \
    echo "DefaultEncryption Never" >> /etc/cups/cupsd.conf &&\
    echo "Port 631" >> /etc/cups/cupsd.conf

# Default shell
CMD ["/usr/sbin/cupsd", "-f"]

Java app dockerfile:

FROM eclipse-temurin:17-jre-jammy
FROM  maven:3.8.6-eclipse-temurin-17 AS build


COPY ./app.jar /tmp/app.jar
COPY appstart.sh /tmp

RUN apt-get clean \
    && rm -rf /var/lib/apt/lists/* \
    && chmod +x /tmp/appstart.sh

CMD ["sh","-c","/tmp/appstart.sh"]


cd /tmp

java -Xlog:gc -jar /tmp/app.jar --spring.datasource.initialization-mode=always

Java code that runs into trouble inside the docker environment:

PrintServiceLookup.lookupPrintServices(null, null); // returns null inside the java docker container. If the java //container is stopped and the jar run in the local machine it finds the Cups printer that runs on the container.

The Compose file and the Dockerfiles look good to me. Since you didn’t define any networks explicitly in the compose file, the services will be attached to the default network for the compose project. Since both services create container attached to the same network, there is no restriction regarding the communikation.

The static lookupPrintServices method of the PrintServiceLookup class hides all details that might give a lead why things are not working out. I have no idea how the static method actually detects the printer. Might be a different version of the jvm or even a different distro used on the host vs inside the container.

I found this SO post, but I am not sure if it realy fits as it indicates the cups.conf might be responsible. Though If you run the client on the same host (or a different host?), instead the containerized client, it works with the very same cups container. So maybe it’s not it.

I had tried before with the DefaultPrinter but it doesn’t find the printer anyway, just tried again. I was inclined to a network issue because if I change the to localhost:631 the javax.print.PrintServiceLookUp won’t be able to find it locally but probably for a different reason. This is a frustrating error, probably the java image doesn’t work the same way in the docker and the java native PrintServiceLookUp does not work properly. I tried with the java library CUPS client cups4j and it detects the printer in the container but I cant change the code and I really need to use the java native PrintServiceLookUp. Would the fact that the container name is cups and in the docker network it would be exposed as cups:631 and that could influence the PrintServiceLookUp?

From the docker desktop, on the printer’s container if I execute the command:

curl localhost:631/printers 
I get the following:
curl: (7) Failed to connect to localhost port 631 after 0 ms: Connection refused

If I get the docker container address doing:

docker container inspect cups
 I get:

        "Id": "1941403add06bb82c450e022a8006980bec51433b1f80742c8ca1eb4be888bb6",
        "Created": "2023-01-07T14:15:27.89768401Z",
        "Path": "/usr/sbin/cupsd",
        "Args": [
        "State": {
            "Status": "running",
            "Running": true,
            "Paused": false,
            "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 16601,
            "ExitCode": 0,
            "Error": "",
            "StartedAt": "2023-01-07T14:15:28.207492343Z",
            "FinishedAt": "0001-01-01T00:00:00Z"
        "Image": "sha256:c17c5c6a261293b28246b4391306fd5295211fd0376dbb439ee892017e5fa94b",
        "ResolvConfPath": "/var/lib/docker/containers/1941403add06bb82c450e022a8006980bec51433b1f80742c8ca1eb4be888bb6/resolv.conf",
        "HostnamePath": "/var/lib/docker/containers/1941403add06bb82c450e022a8006980bec51433b1f80742c8ca1eb4be888bb6/hostname",
        "HostsPath": "/var/lib/docker/containers/1941403add06bb82c450e022a8006980bec51433b1f80742c8ca1eb4be888bb6/hosts",
        "LogPath": "/var/lib/docker/containers/1941403add06bb82c450e022a8006980bec51433b1f80742c8ca1eb4be888bb6/1941403add06bb82c450e022a8006980bec51433b1f80742c8ca1eb4be888bb6-json.log",
        "Name": "/cups",
        "RestartCount": 0,
        "Driver": "overlay2",
        "Platform": "linux",
        "MountLabel": "",
        "ProcessLabel": "",
        "AppArmorProfile": "",
        "ExecIDs": [
        "HostConfig": {
            "Binds": [],
            "ContainerIDFile": "",
            "LogConfig": {
                "Type": "json-file",
                "Config": {}
            "NetworkMode": "java-device_agent_printing_default",
            "PortBindings": {
                "631/tcp": [
                        "HostIp": "",
                        "HostPort": "631"
            "RestartPolicy": {
                "Name": "",
                "MaximumRetryCount": 0
            "AutoRemove": false,
            "VolumeDriver": "",
            "VolumesFrom": null,
            "CapAdd": null,
            "CapDrop": null,
            "CgroupnsMode": "private",
            "Dns": null,
            "DnsOptions": null,
            "DnsSearch": null,
            "ExtraHosts": [],
            "GroupAdd": null,
            "IpcMode": "private",
            "Cgroup": "",
            "Links": null,
            "OomScoreAdj": 0,
            "PidMode": "",
            "Privileged": true,
            "PublishAllPorts": false,
            "ReadonlyRootfs": false,
            "SecurityOpt": [
            "UTSMode": "",
            "UsernsMode": "",
            "ShmSize": 67108864,
            "Runtime": "runc",
            "ConsoleSize": [
            "Isolation": "",
            "CpuShares": 0,
            "Memory": 0,
            "NanoCpus": 0,
            "CgroupParent": "",
            "BlkioWeight": 0,
            "BlkioWeightDevice": null,
            "BlkioDeviceReadBps": null,
            "BlkioDeviceWriteBps": null,
            "BlkioDeviceReadIOps": null,
            "BlkioDeviceWriteIOps": null,
            "CpuPeriod": 0,
            "CpuQuota": 0,
            "CpuRealtimePeriod": 0,
            "CpuRealtimeRuntime": 0,
            "CpusetCpus": "",
            "CpusetMems": "",
            "Devices": [
                    "PathOnHost": "/dev/bus/usb",
                    "PathInContainer": "/dev/bus/usb",
                    "CgroupPermissions": "rwm"
            "DeviceCgroupRules": null,
            "DeviceRequests": null,
            "KernelMemory": 0,
            "KernelMemoryTCP": 0,
            "MemoryReservation": 0,
            "MemorySwap": 0,
            "MemorySwappiness": null,
            "OomKillDisable": null,
            "PidsLimit": null,
            "Ulimits": null,
            "CpuCount": 0,
            "CpuPercent": 0,
            "IOMaximumIOps": 0,
            "IOMaximumBandwidth": 0,
            "MaskedPaths": null,
            "ReadonlyPaths": null
        "GraphDriver": {
            "Data": {
                "LowerDir": "/var/lib/docker/overlay2/07917ef7ed081964b293a793e1a52acae0af0ca98393a826600acc7a6b7a789f-init/diff:/var/lib/docker/overlay2/b2jyfy1g05whxxt76zr1e3kyg/diff:/var/lib/docker/overlay2/vam1nxh7j9a67jfdgymq665bc/diff:/var/lib/docker/overlay2/z8lqmjqihtiqmn2y9xppmbqxg/diff:/var/lib/docker/overlay2/p86sfuod2e9rzxi5p9brv9lm6/diff:/var/lib/docker/overlay2/4vgiuae3q1pwce82tq0p7lq0o/diff:/var/lib/docker/overlay2/vfnic7ebdc0q65x5b44gq45a7/diff:/var/lib/docker/overlay2/b07190ae26534601fdc86fa6bb19c5e9f87c9eb8dc36ecd03fd2bc9ce7487f57/diff",
                "MergedDir": "/var/lib/docker/overlay2/07917ef7ed081964b293a793e1a52acae0af0ca98393a826600acc7a6b7a789f/merged",
                "UpperDir": "/var/lib/docker/overlay2/07917ef7ed081964b293a793e1a52acae0af0ca98393a826600acc7a6b7a789f/diff",
                "WorkDir": "/var/lib/docker/overlay2/07917ef7ed081964b293a793e1a52acae0af0ca98393a826600acc7a6b7a789f/work"
            "Name": "overlay2"
        "Mounts": [],
        "Config": {
            "Hostname": "cups",
            "Domainname": "",
            "User": "",
            "AttachStdin": false,
            "AttachStdout": true,
            "AttachStderr": true,
            "ExposedPorts": {
                "631/tcp": {}
            "Tty": false,
            "OpenStdin": false,
            "StdinOnce": false,
            "Env": [
            "Cmd": [
            "Image": "cups",
            "Volumes": null,
            "WorkingDir": "",
            "Entrypoint": null,
            "OnBuild": null,
            "Labels": {
                "com.docker.compose.config-hash": "143105b5d8f107fbe1540586a7ac4888833207036f3cba4ea8eb078a78689df9",
                "com.docker.compose.container-number": "1",
                "com.docker.compose.depends_on": "",
                "com.docker.compose.image": "sha256:c17c5c6a261293b28246b4391306fd5295211fd0376dbb439ee892017e5fa94b",
                "com.docker.compose.oneoff": "False",
                "com.docker.compose.project": "java-device_agent_printing",
                "com.docker.compose.project.config_files": "/Users/paulo.leite/java-socrates/java-device_agent_printing/docker-compose.yml",
                "com.docker.compose.project.working_dir": "/Users/paulo.leite/java-socrates/java-device_agent_printing",
                "com.docker.compose.service": "cups",
                "com.docker.compose.version": "2.13.0"
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "4c7a21bda72bf57ac7d1530055bae7e36ffbe05f829f3a615c1912bc5727eabb",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "631/tcp": [
                        "HostIp": "",
                        "HostPort": "631"
            "SandboxKey": "/var/run/docker/netns/4c7a21bda72b",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "",
            "Gateway": "",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "",
            "IPPrefixLen": 0,
            "IPv6Gateway": "",
            "MacAddress": "",
            "Networks": {
                "java-device_agent_printing_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                    "NetworkID": "5c6e3d84a70ea3c22d77fd07f6b00d791f43c9f6fb79fb0a81beee578e4bc170",
                    "EndpointID": "a4e3ff11432113a07df30099c8c39dbc7992d3809974f95cc7bf12c395d29f20",
                    "Gateway": "",
                    "IPAddress": "",
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:1d:00:02",
                    "DriverOpts": null

If I run curl again but this time with the container’s address:


    <link rel="stylesheet" href="/cups.css" type="text/css">
    <link rel="shortcut icon" href="/apple-touch-icon.png" type="image/png">
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=9">
    <meta name="viewport" content="width=device-width">
    <title>Home - CUPS 2.3.3op2</title>
    <div class="header">
        <li><a href="http://www.cups.org/" target="_blank">CUPS.org</a></li>
        <li><a class="active" href="/">Home</a></li>
        <li><a href="/admin">Administration</a></li>
        <li><a href="/classes/">Classes</a></li>
        <li><a href="/help/">Help</a></li>
        <li><a href="/jobs/">Jobs</a></li>
        <li><a href="/printers/">Printers</a></li>
    <div class="body">
      <div class="row">
        <h1>CUPS 2.3.3op2</h1>
        <p>CUPS is the standards-based, open source printing system developed by <a href="http://www.apple.com/">Apple Inc.</a> for macOS<sup>&reg;</sup> and other UNIX<sup>&reg;</sup>-like operating systems.</p>
      <div class="row">
        <div class="thirds">
          <h2>CUPS for Users</h2>
          <p><a href="help/overview.html">Overview of CUPS</a></p>
          <p><a href="help/options.html">Command-Line Printing and Options</a></p>
          <p><a href="http://www.cups.org/lists.php?LIST=cups">User Forum</a></p>
        <div class="thirds">
          <h2>CUPS for Administrators</h2>
          <p><a href="help/admin.html">Adding Printers and Classes</a></p>
          <p><a href="help/policies.html">Managing Operation Policies</a></p>
          <p><a href="help/network.html">Using Network Printers</a></p>
          <p><a href="help/firewalls.html">Firewalls</a></p>
          <p><a href="help/man-cupsd.conf.html">cupsd.conf Reference</a></p>
        <div class="thirds">
          <h2>CUPS for Developers</h2>
          <p><a href="help/cupspm.html">CUPS Programming Manual</a></p>
          <p><a href="help/api-filter.html">Filter and Backend Programming</a></p>
          <p><a href="http://www.cups.org/lists.php?LIST=cups-devel">Developer Forum</a></p>
    <div class="footer">CUPS and the CUPS logo are trademarks of <a href="http://www.apple.com">Apple Inc.</a> Copyright &copy; 2007-2019 Apple Inc. All rights reserved.</div>
# curl
    <link rel="stylesheet" href="/cups.css" type="text/css">
    <link rel="shortcut icon" href="/apple-touch-icon.png" type="image/png">
    <meta charset="utf-8">
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=9">
    <meta name="viewport" content="width=device-width">
    <script type="text/javascript"><!--
      /* Only display document if we are not in a frame... */
      if (self == top) {
        document.documentElement.style.display = 'block';
      } else {
        top.location = self.location;

      /* Show an error if cookies are disabled */
      function check_cookies() {
        if (!navigator.cookieEnabled) {
              document.getElementById('body').innerHTML = 'This page uses cookies to prevent common cross-site attacks. Please enable cookies in your browser.';
    <title>Printers - CUPS 2.3.3op2</title>
  <body onload="check_cookies();">
    <div class="header">
        <li><a href="http://www.cups.org/" target="_blank">CUPS.org</a></li>
        <li><a href="/">Home</a></li>
        <li><a href="/admin">Administration</a></li>
        <li><a href="/classes/">Classes</a></li>
        <li><a href="/help/">Help</a></li>
        <li><a href="/jobs/">Jobs</a></li>
        <li><a class="active" href="/printers/">Printers</a></li>
    <div class="body">
      <div class="row">
<FORM ACTION="/printers/" METHOD="GET">

<P ALIGN="CENTER"><B>Search in

<P ALIGN="CENTER">Showing 1 of 1 printer.</P>

<TABLE CLASS="list" SUMMARY="Printer List">
<TR><TH>Queue Name</TH><TH>Description</TH><TH>Location</TH><TH>Make and Model</TH><TH>Status</TH></TR>

<TR><TD><A HREF="/printers/Virtual_PDF_Printer">Virtual_PDF_Printer</A></TD><TD>Virtual PDF Printer</TD><TD></TD><TD>Local Raw Printer</TD><TD>Idle</TD></TR>

    <div class="footer">CUPS and the CUPS logo are trademarks of <a href="http://www.apple.com">Apple Inc.</a> Copyright &copy; 2007-2019 Apple Inc. All rights reserved.</div>

If both containers were on the same network wouldn’t a curl localhost:631 work?

No. The same network does’t mean on the same interface. It means the container gets its ip address from the same ip range. Like when you have multiple machines in your home network. If you run a service on one machine, you can’t access it on localhost on an other machine. Each container has its own localhost and not the same as the localhost of the host machine.

using --net=host for both container worked and I can curl localhost:631 from one container to the other which would fix the problem I believe, but now I cant access the printer service from the outside which I want because I want to access the printer service externally which in turn connects to the cups service

I’ve made some progress and using network-mode:host in docker compose in both services and if I run a piece of code right when the application starts to lookup for the printers and list them I can get the list correctly and the PrintLookupService works as expected:
seconds (JVM running for 3.051)
2023-01-07 15:22:10 ----------------------- PRINTERS -----------------------
2023-01-07 15:22:10 Printer: Virtual_PDF_Printer
2023-01-07 15:22:10 Size: na-letter
2023-01-07 15:22:10 -----------------------------------------------

So If I could get a way of having both containers running on the same host and if I could call the printer service from outside exposing the ports as before on -p 7192:7192 my problem would be solved.

I’ll probably try and have just one container with the printer exposes and the cups running in the same container

Okay, I didn’t have time to think about it before, but I try to share what I think.


If cups is listening on in a container without host network, it is listening on the ip addresses of the container. I have no idea how the java method works, but that service should be available on the container’s ip addresses for everyone. According to the title it wasn’t true. Sometimes firewalls installed on the docker host reject requests even between containers on the same network.

If cups is running in a container that uses the host network and cups is listening on it should be available for remote machines as well except if a firewall installed on the docker host blocks those request.

What “piece of code”? Does it mean that it would not work for example a minute after the containr started?

Didn’t you run the containers on the same host before? I am little bit confused, but based on the previous comments you should check your firewall settings since using the host mode and listening on should allow you to conect to the service remotely. Unless you are using Docker Desktop which you didn’t mention.

I’m using docker desktop.

Wrapping up, the docker compose file has 2 containers (printer and cups)

  • I want to have a (printer) service exposed on port 7192 which is the printer service in the docker compose file.
    This printer service receives print requests, works as an API. When it receives a print request it will call PrintLookupService.lookupPrintServices that searches for an available printer.

  • CUPS server is running on port 631 (cups service in the docker compose file).

  • When I run docker-compose up -d --build printer and cups service start on docker desktop on the same default network. Despite cups is listening on printer service cannot see it. From inside printer container if I curl localhost:631 it fails, but works if i curl cups:631. This is what makes PrintLookupService.lookupPrintServices to fail because it searches for printers on localhost:631 and not on cups:631 ( containers need to point to the docker host machine instead of “localhost”).

  • If I stop the printer container and leave the cups container running and run the printer jar in my local machine it works fine and can reach cups on localhost:631 and PrintLookupService.lookupPrintServices works and identifies the cups printer, but I need both services containerized.

  • In regards to the same host, I tried running both services using --net=host and since with this mode the published port 7192 is no longer available I cannot make requests to it, so as an experiment I run PrintLookupService.lookupPrintServices when the application starts (I’m using SpringBoot which has an entrypoint where we can run some code when it is starting) and it can connect to the cups because they are on the same host and it can identify the printer on localhost:631, but I need the printer service to work as an API so I need to publish port 7192.

  • what is the constraint of running docker desktop?

Should have been an information in the first post AND actually the category for this topic.

This is another key information that should have been part of the first post.

@rimelek already explained that same network does not mean same network interface. It means within the same subnet.

For bridge networks: localhost inside a container, is not the same localhost as on the host or another container

For host network: localhost inside the container and host will be same network interface and namespace, unless Docker Desktop is used. Docker Desktop runs the docker engine in a utility vm. As a result the network interface and namespace of the utility vm is used by the containers and not from the host that runs the utility vm.

With a bridge network (what the default compose network creates), the printer service container can only reach ports running inside the container itself with curl localhost, if it needs to reach ports from another container, it needs to use the service name like your already figured out: curl cups.

Of course, it does, because the published port of the cups container will be reachable from localhost of your host os.

There must be a way to provide the hostname that the printservice lookup uses for it’s lookup. The whole problem is abstracted away in the java implementation. I can not help you to get your code right, you need to do it on your own.

It all boils down to a problem in the java code. To make it work in a docker bridge network, you must make it use the remote printer by the docker networks dns-based service discovery name, which is the service name you declared in the compose file, which in your case is cups.

Hi, docker compose have its own network between containers and it will not be expose on your OS interface while you did not exposed it. Also something like will point to its container loopback, not the OS loopback.
So, you can access to other containers in the same compose by their <service_name>: where the service name and port is exactly what you wrote in your docker-compose.yml file.

Hi, i solved it by using a single docker file publishing the java application and running a second process in the image for the printer.