When set, `pids_limit` must be consistent with the `pids` attribute in the [Deploy Specification](deploy.md#pids).
### `platform`
`platform` defines the target platform the containers for the service run on. It uses the `os[/arch[/variant]]` syntax.
The values of `os`, `arch`, and `variant` must conform to the convention used by the [OCI Image Spec](https://github.com/opencontainers/image-spec/blob/v1.0.2/image-index.md).
Compose uses this attribute to determine which version of the image is pulled
and/or on which platform the service’s build is performed.
```yml
platform: darwin
platform: windows/amd64
platform: linux/arm64/v8
```
### `ports`
{{% include "compose/services-ports.md" %}}
> [!NOTE]
>
> Port mapping must not be used with `network_mode: host`. Doing so causes a runtime error because `network_mode: host` already exposes container ports directly to the host network, so port mapping isn’t needed.
#### Short syntax
The short syntax is a colon-separated string to set the host IP, host port, and container port
in the form:
`[HOST:]CONTAINER[/PROTOCOL]` where:
- `HOST` is `[IP:](port | range)` (optional). If it is not set, it binds to all network interfaces (`0.0.0.0`).
- `CONTAINER` is `port | range`.
- `PROTOCOL` restricts ports to a specified protocol either `tcp` or `udp`(optional). Default is `tcp`.
Ports can be either a single value or a range. `HOST` and `CONTAINER` must use equivalent ranges.
You can either specify both ports (`HOST:CONTAINER`), or just the container port. In the latter case,
the container runtime automatically allocates any unassigned port of the host.
`HOST:CONTAINER` should always be specified as a (quoted) string, to avoid conflicts
with [YAML base-60 float](https://yaml.org/type/float.html).
IPv6 addresses can be enclosed in square brackets.
Examples:
```yml
ports:
- "3000"
- "3000-3005"
- "8000:8000"
- "9090-9091:8080-8081"
- "49100:22"
- "8000-9000:80"
- "127.0.0.1:8001:8001"
- "127.0.0.1:5000-5010:5000-5010"
- "::1:6000:6000"
- "[::1]:6001:6001"
- "6060:6060/udp"
```
> [!NOTE]
>
> If host IP mapping is not supported by a container engine, Compose rejects
> the Compose file and ignores the specified host IP.
#### Long syntax
The long form syntax lets you configure additional fields that can't be
expressed in the short form.
- `target`: The container port.
- `published`: The publicly exposed port. It is defined as a string and can be set as a range using syntax `start-end`. It means the actual port is assigned a remaining available port, within the set range.
- `host_ip`: The host IP mapping. If it is not set, it binds to all network interfaces (`0.0.0.0`).
- `protocol`: The port protocol (`tcp` or `udp`). Defaults to `tcp`.
- `app_protocol`: The application protocol (TCP/IP level 4 / OSI level 7) this port is used for. This is optional and can be used as a hint for Compose to offer richer behavior for protocols that it understands. Introduced in Docker Compose version [2.26.0](/manuals/compose/releases/release-notes.md#2260).
- `mode`: Specifies how the port is published in a Swarm setup. If set to `host`, it publishes the port on every node in Swarm. If set to `ingress`, it allows load balancing across the nodes in Swarm. Defaults to `ingress`.
- `name`: A human-readable name for the port, used to document it's usage within the service.
```yml
ports:
- name: web
target: 80
host_ip: 127.0.0.1
published: "8080"
protocol: tcp
app_protocol: http
mode: host
- name: web-secured
target: 443
host_ip: 127.0.0.1
published: "8083-9000"
protocol: tcp
app_protocol: https
mode: host
```
### `post_start`
{{< summary-bar feature_name="Compose post start" >}}
`post_start` defines a sequence of lifecycle hooks to run after a container has started. The exact timing of when the command is run is not guaranteed.
- `command`: Specifies the command to run once the container starts. This attribute is required, and you can choose to use either the shell form or the exec form.