# How to Run a Detached Nginx Container with Port Publishing

> Easily run a detached Nginx container with port publishing using a simple command. Map host port 8080 to container port 80 and keep your Nginx server running in the background. Learn how to manage your containers effectively.

- Repository: [Apple/container](https://github.com/apple/container)
- Tags: how-to-guide
- Published: 2026-07-05

---

**Use `container run -d -p 8080:80 nginx:latest` to start an Nginx container in the background with host port 8080 mapped to container port 80.**

The `apple/container` repository provides a Swift-based container runtime that supports standard Docker-like workflows. Running a detached Nginx container with port publishing requires understanding how the `container run` command parses the `-d` and `-p` flags and delegates to the runtime service.

## How the `container run` Command Works

The `container run` command serves as the primary interface for creating and starting containers in the `apple/container` project. When you execute this command with the **`-d`** (or **`--detach`**) flag, the CLI implementation in [`Sources/ContainerCommands/Container/ContainerRun.swift`](https://github.com/apple/container/blob/main/Sources/ContainerCommands/Container/ContainerRun.swift) processes the request through several flag categories defined in the `ContainerRun` struct (lines 38‑55).

The execution flow follows these steps:

1. **Flag Parsing**: The command processes `processFlags`, `resourceFlags`, and `managementFlags`, extracting the `detach` boolean and `publish` port mappings.

2. **Container Creation**: The CLI builds a `ContainerCreateOptions` object (lines 11‑13), incorporating settings like `autoRemove` based on the `--rm` flag.

3. **Runtime Registration**: The `client.create()` method registers the container with the runtime, passing the image name and configuration including port specifications.

4. **Detach Logic**: When `managementFlags.detach` is true, the code enters a conditional block (lines 54‑60) that calls `process.start()`, closes I/O handling, prints the generated container ID, and returns immediately to the shell.

5. **Network Setup**: The actual port binding occurs in [`Sources/Services/RuntimeLinux/Server/RuntimeService.swift`](https://github.com/apple/container/blob/main/Sources/Services/RuntimeLinux/Server/RuntimeService.swift), which creates the network namespace, attaches virtual NICs, and binds host sockets according to the publish specifications.

## Port Publishing Syntax and Configuration

The **`-p`** (or **`--publish`**) flag uses the standard container port mapping syntax:

```

[host-ip:]host-port:container-port[/protocol]

```

For Nginx, which listens on port 80 internally, you typically map this to an available host port (e.g., 8080). The runtime handles this by creating a listening socket on the host that forwards traffic to the container's network namespace.

## Practical Code Examples

### 1. Minimal Detached Command

Run Nginx in the background with a simple port mapping:

```bash
container run -d -p 8080:80 nginx:latest

```

This creates a container with a random ID, starts it detached, and publishes host port 8080 to container port 80. The command prints the container ID to stdout and exits immediately.

### 2. Named Container with CID File

For easier management, assign a custom name and write the container ID to a file:

```bash
container run -d --name web \
  -p 8080:80 \
  --cidfile /tmp/web.cid \
  nginx:latest

```

The `--name web` parameter allows you to reference the container as **web** in subsequent commands. The `--cidfile` option (handled in [`ContainerRun.swift`](https://github.com/apple/container/blob/main/ContainerRun.swift) lines 38‑52) persists the generated ID to `/tmp/web.cid` for automation scripts.

### 3. Multiple Ports and Environment Variables

Expose both HTTP and HTTPS ports while passing configuration via environment variables:

```bash
container run -d \
  --name web \
  -p 8080:80 -p 8443:443 \
  -e NGINX_HOST=example.com \
  nginx:latest

```

This maps port 8080 to 80 and 8443 to 443. The `-e` flag injects environment variables through `processFlags`, processed by `Utility.containerConfigFromFlags` (lines 95‑104 in [`ContainerRun.swift`](https://github.com/apple/container/blob/main/ContainerRun.swift)).

## Verifying Container Status and Port Bindings

Confirm your detached container is running and inspect its network configuration:

```bash

# List running containers

container list

# Inspect detailed port configuration

container inspect web

```

The inspect output includes a `Ports` array showing the active bindings:

```json
"Ports": [
  {
    "HostIP": "0.0.0.0",
    "HostPort": "8080",
    "ContainerPort": "80",
    "Protocol": "tcp"
  }
]

```

Access the Nginx welcome page by navigating to `http://localhost:8080` in your browser.

## Summary

- **Detached mode** (`-d`) returns control to the terminal immediately while the container runs in the background, implemented in [`ContainerRun.swift`](https://github.com/apple/container/blob/main/ContainerRun.swift) lines 54‑60.
- **Port publishing** (`-p host:container`) creates host-side listeners that forward to the container's network namespace, configured during runtime initialization in [`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift).
- **Container naming** (`--name`) and **CID files** (`--cidfile`) simplify container management and automation.
- Verify active port mappings using `container inspect` to confirm the runtime correctly bound your specified ports.

## Frequently Asked Questions

### What is the difference between `-d` and `--detach`?

There is no functional difference; `-d` is the shorthand alias for `--detach`. Both flags set `managementFlags.detach` to true in [`ContainerRun.swift`](https://github.com/apple/container/blob/main/ContainerRun.swift), triggering the code path that starts the container process without attaching the current terminal's standard input, output, and error streams.

### Can I publish a range of ports when running a detached container?

Yes, you can specify multiple `-p` flags to map several ports or port ranges. Each flag is parsed and added to the container's network configuration. The runtime ([`RuntimeService.swift`](https://github.com/apple/container/blob/main/RuntimeService.swift)) iterates through these specifications to create the corresponding host listening sockets and firewall rules for traffic forwarding.

### How does the runtime handle port conflicts?

If the specified host port is already in use, the `client.create()` call in [`ContainerRun.swift`](https://github.com/apple/container/blob/main/ContainerRun.swift) will fail during the runtime service initialization phase. The error propagates back to the CLI, which prints a binding error message without starting the container. You must specify an available host port or omit the host port to let the runtime assign an ephemeral port automatically.

### Where are the container logs stored when running detached?

When running in detached mode, the container process continues writing to log files managed by the runtime service rather than the parent terminal. You can access these logs using the `container logs` command followed by the container name or ID. The logging driver and destination are configured through the `processFlags` and resource management options passed during container creation.