К основному содержанию
скилл CX Codex

container-publish — скилл для Claude Code: контейнеры без Dockerfile

Собирает OCI-образы прямо из dotnet publish /t:PublishContainer, без Dockerfile. Пригодится, когда проект на .NET 10 надо упаковать в контейнер и запушить в реестр.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add codewithmukesh/dotnet-claude-kit --skill container-publish -a claude-code
Открыть на GitHub

Что делает container-publish

Скилл объясняет публикацию контейнеров средствами .NET 10 SDK: цель MSBuild PublishContainer собирает образ из проекта, а все настройки живут в .csproj как свойства MSBuild — ContainerRepository, ContainerFamily, ContainerPort, переменные окружения и метки. Отдельного файла, который надо синхронизировать с кодом, нет.

Внутри разобраны варианты базовых образов: noble-chiseled без шелла и пакетного менеджера, noble-chiseled-extra с ICU для локализации, alpine с шеллом. Для Native AOT SDK сам подставляет chiseled-aot. Есть мультиархитектурная сборка через ContainerRuntimeIdentifiers, несколько тегов, сохранение в tar-архив без Docker на машине и пример пайплайна GitHub Actions с docker/login-action.

Ограничение важное: если приложению нужны системные пакеты, SDK-публикация не подойдёт — аналога RUN здесь нет, придётся сначала собрать свой базовый образ через Dockerfile и указать его в ContainerBaseImage. Перед пушем в реестр нужна авторизация: без docker login публикация падает с ошибкой CONTAINER1013. И на Windows не забывайте про --os linux --arch x64, иначе получите Windows-контейнер.

Какие задачи решает

  • собрать образ .NET-сервиса без Dockerfile
  • уменьшить размер продового образа через chiseled-варианты
  • собрать мультиархитектурный образ одной командой
  • сохранить образ в tar для сканирования в CI
  • запушить образ в ghcr.io или Azure Container Registry

Примеры запросов агенту

  • Собери контейнер из моего ASP.NET Core проекта без Dockerfile и запушь в ghcr.io тегом 1.0.0
  • Переведи проект на noble-chiseled и добавь мультиархитектурную сборку для linux-x64 и linux-arm64
  • Настрой пайплайн GitHub Actions, который публикует образ в ghcr.io с тегом по SHA коммита

Как установить container-publish

1Через Skills CLI (Vercel)

npx skills add codewithmukesh/dotnet-claude-kit --skill container-publish -a claude-code

2Вручную: положить файлы

~/.claude/skills/container-publish/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/container-publish/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Из того же набора46

verify Запускает проверку .NET-проекта перед ревью: сборку, тесты, безопасность, форматирование и анализ изменений. CX Codex +1 2 800установок code-review Многоуровневое ревью .NET-кода: Roslyn MCP ищет антипаттерны и диагностику, а ручная проверка идёт по зонам риска. CX Codex +1 2 800установок project-setup Подбирает стек технологий для проектов на .NET: базу данных, авторизацию, кеш и очереди. Пригодится на старте архитектурного выбора или ревизии зависимостей. CX Codex +1 2 800установок instinct-system Фиксирует паттерны, правки пользователя и находки в файлах проекта. Нужен, когда агенту надо учиться на повторяющихся решениях. CX Codex +1 2 800установок workflow-mastery Набор практик и готовых конфигураций для ускорения разработки на .NET в Claude Code. Помогает настроить параллельные сессии через git worktree, циклы верификации и лимиты контекста. CX Codex +1 2 800установок aspire Помогает настроить .NET Aspire для локального запуска сервисов, ресурсов и обнаружения сервисов. Нужен при работе с AppHost и общими настройками сервисов. CX Codex +1 2 800установок convention-learner Разбирает существующий код и выводит из него правила проекта: имена, структуру папок, оформление тестов. Пригодится, когда агент пишет код не в том стиле. CX Codex +1 2 800установок api-versioning Направляет агента при версионировании ASP.NET Core API через библиотеку Asp.Versioning. Помогает настроить пути, заголовки и мягкую депрекацию устаревших версий. CX Codex +1 2 800установок

Похожие

container-hardening devops-skills Настраивает запуск контейнеров без root-прав, монтирует файловую систему только для чтения и формирует манифесты Kubernetes securityContext. CX Codex +1 433установок container-registries devops-skills Скилл для работы с реестрами контейнеров: ECR, ACR, GCR, Docker Hub, GHCR и self-hosted. Пригодится, когда нужно запушить образ или настроить политику хранения. CX Codex +1 346установок dockerfile-optimise pproenca Скилл с 48 правилами из официальной документации Docker: кэш слоёв, multi-stage сборки, безопасность. Пригодится при написании и рефакторинге Dockerfile. CX Codex +1 344установок quarkus-native-and-container официальный github Помогает собрать нативный исполняемый файл Quarkus, починить ошибки reflection и сделать образ контейнера с манифестами Kubernetes. ★ 40 418звёзд репо container-escape-techniques yaklang Плейбук по выходу из Docker, LXC и Kubernetes-подов на хост: привилегированный режим, capabilities, docker.sock, cgroup. CX Codex +1 3 600установок docker-compose-patterns docker Набор правил для сборки, отладки и связывания сервисов в compose.yaml. Помогает настроить проверки готовности, тома и оверрайды под локальную разработку. CX Codex +1 1 400установок

Рядом в теме «DevOps и инфраструктура»

Всё по теме «DevOps и инфраструктура» →

Вопросы о container-publish

Как установить container-publish в Claude?

Выполните npx skills add codewithmukesh/dotnet-claude-kit --skill container-publish -a claude-code. Скилл появится в ~/.claude/skills/container-publish/SKILL.md.

Что делает container-publish?

Описывает контейнеризацию через dotnet publish /t:PublishContainer: свойства MSBuild, chiseled-образы, мультиархитектурные сборки и публикацию в реестр. Dockerfile при этом не нужен.

Когда SDK-публикация не подойдёт?

Если приложению нужны системные пакеты: команды вроде apt-get в этом сценарии выполнить негде. Соберите свой базовый образ через Dockerfile и укажите его в ContainerBaseImage.

Исходный текст

SKILL.md · MIT
---
name: container-publish
description: >
  Dockerfile-less containerization using the .NET 10 SDK container publishing
  feature. Covers MSBuild properties, chiseled images, multi-arch builds, and
  registry publishing — all without writing a Dockerfile.
  Load this skill when the user wants to containerize without a Dockerfile, or
  mentions "dotnet publish container", "PublishContainer", "ContainerRepository",
  "ContainerFamily", "chiseled", "distroless", "container publish", "SDK
  container", "no Dockerfile", or "containerize without Docker".
---

# Container Publishing (No Dockerfile)

## Core Principles

1. **No Dockerfile needed** — The .NET 10 SDK builds OCI-compliant container images directly from `dotnet publish /t:PublishContainer`. No Dockerfile to write or maintain.
2. **Chiseled images for production** — Use `noble-chiseled` base images: no shell, no package manager, 7 Linux components vs 100+. Smallest attack surface.
3. **Non-root by default** — .NET 10 container images run as the `app` user automatically. Never override to root in production.
4. **Configuration in the .csproj** — All container settings are MSBuild properties, versioned with your project. No separate files to drift.

## Patterns

### Minimal Container Publish

No project file changes needed. Just publish:

```bash
dotnet publish /t:PublishContainer --os linux --arch x64
```

This creates a container image in your local Docker daemon using the default `aspnet:10.0` base image.

### Production-Ready .csproj Configuration

```xml
<Project Sdk="Microsoft.NET.Sdk.Web">

  <PropertyGroup>
    <TargetFramework>net10.0</TargetFramework>
    <ContainerRepository>mycompany/myapp-api</ContainerRepository>
    <ContainerFamily>noble-chiseled</ContainerFamily>
  </PropertyGroup>

  <ItemGroup>
    <ContainerPort Include="8080" Type="tcp" />
    <ContainerEnvironmentVariable Include="ASPNETCORE_HTTP_PORTS" Value="8080" />
    <ContainerEnvironmentVariable Include="DOTNET_EnableDiagnostics" Value="0" />
    <ContainerLabel Include="org.opencontainers.image.vendor" Value="MyCompany" />
  </ItemGroup>

</Project>
```

### Publishing to a Registry

Authenticate with `docker login` first, then specify the registry:

```bash
# GitHub Container Registry
docker login ghcr.io
dotnet publish /t:PublishContainer --os linux --arch x64 \
    -p ContainerRegistry=ghcr.io \
    -p ContainerImageTag=1.0.0

# Azure Container Registry
az acr login --name myregistry
dotnet publish /t:PublishContainer --os linux --arch x64 \
    -p ContainerRegistry=myregistry.azurecr.io

# Docker Hub (requires username prefix in repository)
dotnet publish /t:PublishContainer --os linux --arch x64 \
    -p ContainerRegistry=docker.io \
    -p ContainerRepository=myuser/myapp
```

### Multi-Architecture Images

Build images for multiple platforms with a single publish:

```xml
<PropertyGroup>
    <RuntimeIdentifiers>linux-x64;linux-arm64</RuntimeIdentifiers>
    <ContainerRuntimeIdentifiers>linux-x64;linux-arm64</ContainerRuntimeIdentifiers>
</PropertyGroup>
```

```bash
dotnet publish /t:PublishContainer
```

This produces an OCI Image Index — registries serve the correct architecture automatically.

### Multiple Tags

```bash
# Bash — note the quoting for semicolons
dotnet publish /t:PublishContainer --os linux --arch x64 \
    -p ContainerImageTags='"1.0.0;latest"'
```

Or in the project file:

```xml
<ContainerImageTags>1.0.0;latest</ContainerImageTags>
```

### Save as Tarball (No Docker Required)

No container runtime needed on the build machine. Useful for CI scanning:

```bash
dotnet publish /t:PublishContainer --os linux --arch x64 \
    -p ContainerArchiveOutputPath=./images/myapp.tar.gz

# Scan with Trivy before pushing
trivy image --input ./images/myapp.tar.gz
```

### Chiseled Image Variants

| ContainerFamily | Use Case | Shell | Size |
|----------------|----------|-------|------|
| *(default)* | General purpose (Debian) | Yes | ~220 MB |
| `noble-chiseled` | Production (no shell) | No | ~110 MB |
| `noble-chiseled-extra` | Production with localization (ICU) | No | ~120 MB |
| `alpine` | Small size, has shell | Yes | ~112 MB |

```xml
<!-- Standard chiseled (InvariantGlobalization=true) -->
<ContainerFamily>noble-chiseled</ContainerFamily>

<!-- Chiseled with ICU for localization -->
<ContainerFamily>noble-chiseled-extra</ContainerFamily>
```

For Native AOT, the SDK auto-selects `chiseled-aot`:

```xml
<PublishAot>true</PublishAot>
<!-- SDK picks runtime-deps:10.0-noble-chiseled-aot automatically -->
```

### CI/CD with GitHub Actions

```yaml
jobs:
  publish:
    runs-on: ubuntu-latest
    permissions:
      packages: write
    steps:
      - uses: actions/checkout@v5
      - uses: actions/setup-dotnet@v5
        with:
          dotnet-version: '10.0.x'
      - uses: docker/login-action@v3
        with:
          registry: ghcr.io
          username: ${{ github.actor }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - run: |
          dotnet publish src/MyApp.Api/MyApp.Api.csproj \
            /t:PublishContainer --os linux --arch x64 \
            -p ContainerRegistry=ghcr.io \
            -p ContainerRepository=${{ github.repository_owner }}/myapp \
            -p ContainerImageTag=${{ github.sha }}
```

## Anti-patterns

### Don't Use the Deprecated Property Names

```xml
<!-- BAD — ContainerImageName is deprecated -->
<ContainerImageName>myapp</ContainerImageName>

<!-- GOOD — use ContainerRepository -->
<ContainerRepository>myapp</ContainerRepository>
```

### Don't Use PublishProfile=DefaultContainer

```bash
# BAD — old approach, inconsistent across project types
dotnet publish -p:PublishProfile=DefaultContainer

# GOOD — use the MSBuild target directly
dotnet publish /t:PublishContainer
```

### Don't Forget to Target Linux

```bash
# BAD on Windows — may produce a Windows container
dotnet publish /t:PublishContainer

# GOOD — explicitly target Linux
dotnet publish /t:PublishContainer --os linux --arch x64
```

### Don't Skip Authentication Before Push

```bash
# BAD — fails with CONTAINER1013 error
dotnet publish /t:PublishContainer -p ContainerRegistry=ghcr.io

# GOOD — authenticate first
docker login ghcr.io
dotnet publish /t:PublishContainer -p ContainerRegistry=ghcr.io
```

### Don't Use SDK Publishing When You Need OS Packages

```xml
<!-- BAD — SDK container publish cannot run apt-get or install native packages -->
<!-- There is no RUN equivalent -->

<!-- GOOD — create a custom base image with a Dockerfile first, then reference it -->
<ContainerBaseImage>myregistry/custom-base:1.0</ContainerBaseImage>
```

## Decision Guide

| Scenario | Recommendation |
|----------|---------------|
| Standard ASP.NET Core API | SDK container publishing with `noble-chiseled` |
| Worker service / console app | SDK container publishing (native .NET 10 support) |
| Needs native OS packages | Dockerfile (or custom base image + SDK publishing) |
| Azure Functions | Dockerfile (not supported by SDK publishing) |
| CI without Docker daemon | Tarball output with `ContainerArchiveOutputPath` |
| Multi-arch deployment (x64 + arm64) | `ContainerRuntimeIdentifiers` property |
| Production image size | `noble-chiseled` (~110 MB) or Native AOT (~10 MB) |
| Local development | `dotnet publish /t:PublishContainer --os linux --arch x64` |
| Registry push | `ContainerRegistry` + `docker login` |

© codewithmukesh · MIT · codewithmukesh/dotnet-claude-kit

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой