> For the complete documentation index, see [llms.txt](https://docs.linx.software/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.linx.software/8/docker-guide.md).

# Docker guide

This guide explains how to build and run a Linx 8 application as a Docker container — first against a local [Docker Desktop](https://www.docker.com/products/docker-desktop/) installation, and then in a remote Docker environment using the `/pack` command. It assumes you have already created an application by following the [Linx 8 Bootstrapper guide](/8/bootstrapper-getting-started.md).

When you create an application with `linx8 create`, a `Dockerfile` and a `.dockerignore` are scaffolded into the application root for you, so no extra setup is needed before building an image. The Dockerfile uses a multi-stage build — the .NET 10 SDK image (`mcr.microsoft.com/dotnet/sdk:10.0`) restores and publishes the application, and the smaller ASP.NET runtime image (`mcr.microsoft.com/dotnet/aspnet:10.0`) runs it. It restores packages from both the public NuGet feed and the Twenty57 Linx 8 feed.

## Requirements

* A Linx 8 application created with `linx8 create` (see the [Linx 8 Bootstrapper guide](/8/bootstrapper-getting-started.md)).
* For local builds: [Docker Desktop](https://www.docker.com/products/docker-desktop/).
* For remote builds: access to a machine running Docker (for example over SSH), and the [.NET SDK 10.0](https://dotnet.microsoft.com/download) on your development machine to run `/pack`.

## Build and run locally with Docker Desktop

With Docker Desktop running, build an image from the scaffolded Dockerfile. Run these commands from the application root (the folder containing the `Dockerfile`):

```
docker build -t <app-name> .
```

`<app-name>` is the image tag — choose any lowercase name, for example `myapp`. Throughout this guide, anything in angle brackets (for example `<app-name>` or `<ServiceUri>`) is a placeholder you replace with your own value — do not type the brackets.

Once the image is built, run it as a container:

```
docker run --rm <app-name>
```

The `--rm` flag removes the container when it stops, which is convenient while testing.

The scaffolded `.dockerignore` already excludes build output and other files that should not be sent to the Docker build (`**/bin/`, `**/obj/`, `**/*.g.cs`, `**/*.Tests/`, `artifacts/`, `.git/`, `.vscode/` and `.claude/`), so the image stays small and builds reproducibly.

## Publishing ports

A container's ports are not reachable from the host until you publish them with `-p <host-port>:<container-port>`:

```
docker run --rm -p 8080:8080 <app-name>
```

The address a REST host listens on comes from the application's settings (the service URI in `AppSettings`), so the port you publish must match the port the application is actually listening on inside the container. You can set that address at runtime with an environment variable override (see [Overriding settings with environment variables](#overriding-settings-with-environment-variables) below). Bind to `0.0.0.0` rather than `localhost` so the listener accepts connections from outside the container:

```
docker run --rm -e Setting.<ServiceUri>="http://0.0.0.0:8080" -p 8080:8080 <app-name>
```

Replace `<ServiceUri>` with the name of the setting that holds your service's URI. With the above, the service is reachable from the host at `http://localhost:8080`.

## Mounting folders

To share a folder between the host and the container — for configuration, secrets, or output files — mount it with `--mount type=bind,source=<host-path>,destination=<container-path>`:

```
docker run --rm --mount type=bind,source=C:\host\data,destination=/app/data <app-name>
```

A common use is to supply a secret (such as a connection string) as a file and point a setting at it, which keeps the secret out of your shell history and the container's environment listing:

```
docker run --rm --mount type=bind,source=C:\host\secrets,destination=/app/secrets -e Setting.<ConnectionString>.File="/app/secrets/connection-string.txt" <app-name>
```

## Overriding settings with environment variables

Any application setting can be overridden at container start time, without rebuilding the image, by passing an environment variable prefixed with `Setting.`:

* **Simple setting** — `Setting.<PropertyName>`, for example `-e Setting.DatabaseName="MyApp"`.
* **Nested setting** — use a dot for each level, for example `-e Setting.Service.Timeout="00:00:30"`.
* **Setting from a file** — append `.File` and give the path to a file (typically a mounted one); the file's contents become the value, for example `-e Setting.ApiKey.File="/app/secrets/api-key.txt"`.

Values are converted to the setting's type automatically, including `string`, enums, `Uri`, `Guid`, `TimeSpan`, nullable types, and any type supported by the standard .NET conversions (such as `int`, `bool` and `decimal`).

## Package for a remote Docker environment with `/pack`

To build and run the application on a remote Docker host, package it first with the `/pack` slash-command in Claude Code.

`/pack` confirms which application project to package, then produces a self-contained tarball at `artifacts/<ProjectName>.linx`. The tarball contains a `Dockerfile` at its root, the application source under `src/<project>`, and the solution's `docs` folder under `src/docs`.

Copy the `.linx` file to the remote Docker host. Docker can build from this file directly. Pass `-` to read the build context from stdin and feed the file in:

```
docker build -t <app-name> - < <ProjectName>.linx
```

(The `<` before `<ProjectName>.linx` is the shell's stdin redirect — only `<ProjectName>` is a placeholder.)

Then run the container exactly as you would locally, reusing the port-publishing, folder-mounting and setting-override flags described above:

```
docker run --rm -e Setting.<ServiceUri>="http://0.0.0.0:8080" -p 8080:8080 <app-name>
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.linx.software/8/docker-guide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
