service ports services.web.ports.[0] is missing a target port — a port in the long syntax (published:, host_ip: on separate lines) has no target:, the port inside the container. Add target: and the file loads.

The [0] points at the entry in the service's ports list; the test file has one entry, and it is [0]. Add the container port to that entry, for example target: 80.

The error

PS> docker compose -p fix10-cs-q9 config
service ports services.web.ports.[0] is missing a target port

The command exited with code 1. The message starts with service ports and then gives the full path of the entry, services.web.ports.[0]: service web, key ports, entry [0]. The file:

services:
  web:
    image: alpine
    command: ["echo", "web started"]
    ports:
      - published: "15910"
        host_ip: 127.0.0.1

Why it happens

In the long syntax each key of a port entry is written out on its own line. The entry here says which host address and port to open, 127.0.0.1:15910, but not which container port the traffic goes to. Compose refused the file and named the entry by its path, so the service and the entry are both in the message.

docker compose config was enough to see it; no container and no port were needed. A file that publishes ports is worth checking with config before up for that reason.

The fix

...
    ports:
      - target: 80
        published: "15910"
        host_ip: 127.0.0.1
PS> docker compose -p fix10-cs-q9 config
name: fix10-cs-q9
...
    ports:
      - mode: ingress
        host_ip: 127.0.0.1
        target: 80
        published: "15910"
        protocol: tcp
...

With target: 80 the file validated and config exited with code 0; the published port and the host address came through unchanged. config also filled in the keys left out, mode: ingress and protocol: tcp; those five are the keys config printed for this entry. Use the port your application listens on inside the container as the target.

How it was reproduced

One alpine service running echo web started with a long-syntax port entry holding published: "15910" and host_ip: 127.0.0.1 and no target, checked with docker compose config from Windows PowerShell 5.1, then with target: 80 added. Nothing was started and no port was opened. Docker Compose v5.7.0, Docker Engine 29.9.3, Docker Desktop 4.99.0 on Windows (version 10.0.26300). The project name fix10-cs-q9 is this test's own.

Frequently asked

What does 'is missing a target port' mean in docker compose?
A port entry in the long syntax has no target: key, the port inside the container. The path in the message, such as services.web.ports.[0], names the entry.
What is target in docker compose ports?
The port inside the container. published is the port on the host and host_ip the host address. In this test target: 80 with published: 15910 and host_ip: 127.0.0.1 validated.
What does [0] mean in services.web.ports.[0]?
It points at an entry in the ports list. The test file had a single entry, and the message called it [0].

More decoded errors in the Fixes category. For a port list written in the wrong shape, see Docker Compose: ports must be a array.