AI-Powered Testing: Using Docker Model Runner with Microcks for Dynamic Mock APIs

The non-deterministic nature of LLMs makes them ideal for generating dynamic, rich test data, perfect for validating app behavior and ensuring consistent, high-quality user experiences. Today, we’ll walk you through how to use Docker’s Model Runner with Microcks to generate dynamic mock APIs for testing your applications.

Microcks is a powerful CNCF tool that allows developers to quickly spin up mock services for development and testing. By providing predefined mock responses or generating them directly from an OpenAPI schema, you can point your applications to consume these mocks instead of hitting real APIs, enabling efficient and safe testing environments.

Docker Model Runner is a convenient way to run LLMs locally within your Docker Desktop. It provides an OpenAI-compatible API, allowing you to integrate sophisticated AI capabilities into your projects seamlessly, using local hardware resources.

By integrating Microcks with Docker Model Runner, you can enrich your mock APIs with AI-generated responses, creating realistic and varied data that is less rigid than static examples.

In this guide, we’ll explore how to set up these two tools together, giving you the benefits of dynamic mock generation powered by local AI.

Setting up Docker Model Runner

To start, ensure you’ve enabled Docker Model Runner as described in our previous blog on configuring Goose for a local AI assistant setup. Next, select and pull your desired LLM model from Docker Hub. For example:

docker model pull ai/qwen3:8B-Q4_0

Configuring Microcks with Docker Model Runner

First, clone the Microcks repository:

git clone https://github.com/microcks/microcks –depth 1

Navigate to the Docker Compose setup directory:

cd microcks/install/docker-compose

You’ll need to adjust some configurations to enable the AI Copilot feature within Microcks.In the /config/application.properties file, configure the AI Copilot to use Docker Model Runner:

ai-copilot.enabled=true
ai-copilot.implementation=openai
ai-copilot.openai.api-key=irrelevant
ai-copilot.openai.api-url=http://model-runner.docker.internal:80/engines/llama.cpp/
ai-copilot.openai.timeout=600
ai-copilot.openai.maxTokens=10000
ai-copilot.openai.model=ai/qwen3:8B-Q4_0

We’re using the model-runner.docker.internal:80 as the base URL for the OpenAI compatible API. Docker Model Runner is available there from the containers running in Docker Desktop.  Using it ensures direct communication between the containers and the Model Runner and avoids unnecessary networking using the host machine ports.

Next, enable the copilot feature itself by adding this line to the Microcks config/features.properties file:

features.feature.ai-copilot.enabled=true

Running Microcks

Start Microcks with Docker Compose in development mode:

docker-compose -f docker-compose-devmode.yml up

Once up, access the Microcks UI at http://localhost:8080.

Install the example API for testing. Click through these buttons on the Microcks page:Microcks Hub → MicrocksIO Samples APIs → pastry-api-openapi v.2.0.0 → Install → Direct import → Go.

Figure 1: Screenshot of the Pastry API 2.0 page on Microcks Hub with option to install.

Using AI Copilot samples

Within the Microcks UI, navigate to the service page of the imported API and select an operation you’d like to enhance. Open the “AI Copilot Samples” dialog, prompting Microcks to query the configured LLM via Docker Model Runner.

Figure 2: A display of the “AI Copilot Samples” dialog inside Microcks.

You may notice increased GPU activity as the model processes your request.

After processing, the AI-generated mock responses are displayed, ready to be reviewed or added directly to your mocked operations.

Figure 3: Mocked data generated within the AI Copilot Suggested Samples on Microcks.

You can easily test the generated mocks with a simple curl command. For example:

curl -X PATCH 'http://localhost:8080/rest/API+Pastry+-+2.0/2.0.0/pastry/Chocolate+Cake'
-H 'accept: application/json'
-H 'Content-Type: application/json'
-d '{"status":"out_of_stock"}'

{
"name" : "Chocolate Cake",
"description" : "Rich chocolate cake with vanilla frosting",
"size" : "L",
"price" : 12.99,
"status" : "out_of_stock"
}

This returns a realistic, AI-generated response that enhances the quality and reliability of your test data. 

Now you could use this approach in the tests; for example, a shopping cart application, where the app depends on some inventory service. With realistic yet randomized mocked data, you can cover more application behaviors with the same set of tests. For better reproducibility, you can also specify the Docker Model Runner dependency and the chosen model explicitly in your compose.yml:

models:
qwen3:
model: ai/qwen3:8B-Q4_0
context_size: 8096

Then starting the compose setup will pull the model too and wait for it to be available, the same way it does for containers.

Conclusion

Docker Model Runner is an excellent local resource for running LLMs and provides compatibility with OpenAI APIs, allowing for seamless integration into existing workflows. Tools like Microcks can leverage Model Runner to generate dynamic sample responses for mocked APIs, giving you richer, more realistic synthetic data for integration testing.

If you have local AI workflows or just run LLMs locally, please discuss with us in the Docker Forum! We’d love to explore more local AI integrations with Docker.

Learn more

Get an inside look at the design architecture of the Docker Model Runner. 

Explore the story behind our model distribution specification

Read our quickstart guide to Docker Model Runner.

Find documentation for Model Runner.

Visit our new AI solution page

Subscribe to the Docker Navigator Newsletter.

New to Docker? Create an account. 

Have questions? The Docker community is here to help.

Quelle: https://blog.docker.com/feed/

Build a GenAI App With Java Using Spring AI and Docker Model Runner

When thinking about starting a Generative AI (GenAI) project, you might assume that Python is required to get started in this new space. However, if you’re already a Java developer, there’s no need to learn a new language. The Java ecosystem offers robust tools and libraries that make building GenAI applications both accessible and productive.

In this blog, you’ll learn how to build a GenAI app using Java. We’ll do a step-by-step demo to show you how RAG enhances the model response, using Spring AI and Docker tools. Spring AI integrates with many model providers (for both chat and embeddings), vector databases, and more. In our example, we’ll use the OpenAI and Qdrant modules provided by the Spring AI project to take advantage of built-in support for these integrations. Additionally, we’ll use Docker Model Runner (instead of a cloud-hosted OpenAI model), which offers an OpenAI-compatible API, making it easy to run AI models locally. We’ll automate the testing process using Testcontainers and Spring AI’s tools to ensure the LLM’s answers are contextually grounded in the documents we’ve provided. Last, we’ll show you how to use Grafana for observability and ensure our app behaves as designed. 

Getting started 

Let’s start building a sample application by going to Spring Initializr and choosing the following dependencies: Web, OpenAI, Qdrant Vector Database, and Testcontainers.

It’ll have two endpoints: a “/chat” endpoint that interacts directly with the model and a   “/rag” endpoint that provides the model with additional context from documents stored in the vector database.

Configuring Docker Model Runner

Enable Docker Model Runner in your Docker Desktop or Docker Engine as described in the official documentation.

Then pull the following two models:

docker model pull ai/llama3.1
docker model pull ai/mxbai-embed-large

ai/llama3.1 – chat model

ai/mxbai-embed-large – embedding model

Both models are hosted at Docker Hub under the ai namespace. You can also pick specific tags for the model, which usually provide different quantization of the model. If you don’t know which tag to pick, the default one is a good starting point.

Building the GenAI app

Let’s create a ChatController under /src/main/java/com/example, which will be our entry point to interact with the chat model:

@RestController
public class ChatController {

private final ChatClient chatClient;

public ChatController(ChatModel chatModel) {
this.chatClient = ChatClient.builder(chatModel).build();
}

@GetMapping("/chat")
public String generate(@RequestParam(value = "message", defaultValue = "Tell me a joke") String message) {
return this.chatClient.prompt().user(message).call().content();
}

}

ChatClient is the interface that provides the available operations to interact with the model. We’ll be injecting the actual model value (which model to use) via configuration properties.

If no message query param is provided, then we’ll ask the model to tell a joke (as seen in the defaultValue).

Let’s configure our application to point to Docker Model Runner and use the “ai/llama3.1” model by adding the following properties to /src/test/resources/application.properties

spring.ai.openai.base-url=http://localhost:12434/engines
spring.ai.openai.api-key=test
spring.ai.openai.chat.options.model=ai/llama3.1

spring.ai.openai.api-key is required by the framework, but we can use any value here since it is not needed for Docker Model Runner.

Let’s start our application by running ./mvnw spring-boot:test-run or ./gradlew bootTestRun and ask it about Testcontainers:

http :8080/chat message=="What’s testcontainers?"

Below, we can find the answer provided by the LLM (ai/llama3.1)

Testcontainers is a fantastic and increasingly popular library for **local testing with containers**. Let's break down what it is, why it's useful, and how it works:

**What is Testcontainers?**

Testcontainers provides a way to run real, fully functional containerized services (like databases, message queues, web servers, etc.) directly within your tests. Instead of relying on mocked or stubbed versions of these services, you're using the *actual* services, which leads to much more realistic and reliable test results.

**Why Use Testcontainers?**

* **Realistic Testing:** This is the biggest benefit. Mocking databases or message queues can be brittle and difficult to maintain. Testcontainers provides a service that behaves exactly like the real thing, leading to tests that more accurately reflect how your application will perform in production.
* **Simplified Test Setup:** Forget about manually setting up and configuring databases or other services on your test machine. Testcontainers automatically handles the container creation, configuration, and cleanup for you.
* **Faster Tests:** Because the services are running locally, there’s no network latency involved, resulting in significantly faster test execution times.
* **Consistent Environments:** You eliminate the "it works on my machine" problem. Everyone running the tests will be using the same, pre-configured environment.
* **Supports Many Services:** Testcontainers supports a huge range of services, including:
* **Databases:** PostgreSQL, MySQL, MongoDB, Redis, Cassandra, MariaDB
* **Message Queues:** RabbitMQ, Kafka, ActiveMQ
* **Web Servers:** Tomcat, Jetty, H2 (for in-memory databases)
* **And many more!** The list is constantly growing.

**How Does It Work?**

1. **Client Library:** Testcontainers provides client libraries for various programming languages (Java, Python, JavaScript, Ruby, Go, .NET, and more).
2. **Container Run:** When you use the Testcontainers client library in your test, it automatically starts the specified container (e.g., a PostgreSQL database) in the background.
3. **Connection:** Your test code then connects to the running container using standard protocols (e.g., JDBC for PostgreSQL, HTTP for a web server).
4. **Test Execution:** You execute your tests as usual.
5. **Cleanup:** When the tests are finished, Testcontainers automatically shuts down the container, ensuring a clean state for the next test run.

**Example (Conceptual – Python):**

“`python
from testcontainers.postgresql import PostgreSQLEnvironment

# Create a PostgreSQL environment
env = PostgreSQLEnvironment()

# Start the container
env.start()

# Connect to the database
db = env.db() # This creates a connection object to the running PostgreSQL container

# Perform database operations in your test
# …

# Stop the container (cleanup)
env.shutdown()
“`

**Key Concepts:**

* **Environment:** A Testcontainers environment is a configuration that defines which containers to run and how they should be configured.
* **Container:** A running containerized service (e.g., a database instance).
* **Connection:** An object that represents a connection to a specific container.

**Resources to Learn More:**

* **Official Website:** [https://testcontainers.io/](https://testcontainers.io/) – This is the best place to start.
* **GitHub Repository:** [https://github.com/testcontainers/testcontainers](https://github.com/testcontainers/testcontainers) – See the source code and contribute.
* **Documentation:** [https://testcontainers.io/docs/](https://testcontainers.io/docs/) – Comprehensive documentation with examples for various languages.

**In short, Testcontainers is a powerful tool that dramatically improves the quality and reliability of your local tests by allowing you to test against real, running containerized services.**

Do you want me to delve deeper into a specific aspect of Testcontainers, such as:

* A specific language implementation (e.g., Python)?
* A particular service it supports (e.g., PostgreSQL)?
* How to integrate it with a specific testing framework (e.g., JUnit, pytest)?

We can see that the answer provided by the LLM has some mistakes, for example, PostgreSQLEnvironment doesn’t exist in testcontainers-python. Another one is the links to the docs, testcontainers.io doesn’t exist. So, we can see some hallucinations in the answer.

Of course, LLM responses are non-deterministic, and since each model is trained until a certain cutoff date, the information may be outdated, and the answers might not be accurate.

To improve this situation, let’s provide the model with some curated context about Testcontainers!

We’ll create another controller, RagController, which will retrieve documents from a vector search database.

@RestController
public class RagController {

private final ChatClient chatClient;

private final VectorStore vectorStore;

public RagController(ChatModel chatModel, VectorStore vectorStore) {
this.chatClient = ChatClient.builder(chatModel).build();
this.vectorStore = vectorStore;
}

@GetMapping("/rag")
public String generate(@RequestParam(value = "message", defaultValue = "What's Testcontainers?") String message) {
return callResponseSpec(this.chatClient, this.vectorStore, message).content();
}

static ChatClient.CallResponseSpec callResponseSpec(ChatClient chatClient, VectorStore vectorStore,
String question) {
QuestionAnswerAdvisor questionAnswerAdvisor = QuestionAnswerAdvisor.builder(vectorStore)
.searchRequest(SearchRequest.builder().topK(1).build())
.build();
return chatClient.prompt().advisors(questionAnswerAdvisor).user(question).call();
}

}

Spring AI provides many advisors. In this example, we are going to use the QuestionAnswerAdvisor to perform the query against the vector search database. It takes care of all the individual integrations with the vector database.

Ingesting documents into the vector database

First, we need to load the relevant documents into the vector database. Under src/test/java/com/example, let’s create an IngestionConfiguration class:

@TestConfiguration(proxyBeanMethods = false)
public class IngestionConfiguration {

@Value("classpath:/docs/testcontainers.txt")
private Resource testcontainersDoc;

@Bean
ApplicationRunner init(VectorStore vectorStore) {
return args -> {
var javaTextReader = new TextReader(this.testcontainersDoc);
javaTextReader.getCustomMetadata().put("language", "java");

var tokenTextSplitter = new TokenTextSplitter();
var testcontainersDocuments = tokenTextSplitter.apply(javaTextReader.get());

vectorStore.add(testcontainersDocuments);
};
}

}

testcontainers.txt under /src/test/resources/docs directory will have the following content  specific information. For a real-world use case, you would probably have a more extensive collection of documents.

Testcontainers is a library that provides easy and lightweight APIs for bootstrapping local development and test dependencies with real services wrapped in Docker containers. Using Testcontainers, you can write tests that depend on the same services you use in production without mocks or in-memory services.

Testcontainers provides modules for a wide range of commonly used infrastructure dependencies including relational databases, NoSQL datastores, search engines, message brokers, etc. See https://testcontainers.com/modules/ for a complete list.

Technology-specific modules are a higher-level abstraction on top of GenericContainer which help configure and run these technologies without any boilerplate, and make it easy to access their relevant parameters.

Official website: https://testcontainers.com/
Getting Started: https://testcontainers.com/getting-started/
Module Catalog: https://testcontainers.com/modules/

Now, let’s add an additional property to the src/test/resources/application.properties file.

spring.ai.openai.embedding.options.model=ai/mxbai-embed-large
spring.ai.vectorstore.qdrant.initialize-schema=true
spring.ai.vectorstore.qdrant.collection-name=test

ai/mxbai-embed-large is an embedding model that will be used to create the embeddings of the documents. They will be stored in the vector search database, in our case, Qdrant. Spring AI will initialize the Qdrant schema and use the collection named test.

Let’s update our TestDemoApplication Java class and add the IngestionConfiguration.class

public class TestDemoApplication {

public static void main(String[] args) {
SpringApplication.from(DemoApplication::main)
.with(TestcontainersConfiguration.class, IngestionConfiguration.class)
.run(args);
}

}

Now we start our application by running ./mvnw spring-boot:test-run or ./gradlew bootTestRun and ask it again about Testcontainers:

http :8080/rag message=="What’s testcontainers?"

This time, the answer contains references from the docs we have provided and is more accurate.

Testcontainers is a library that helps you write tests for your applications by bootstrapping real services in Docker containers, rather than using mocks or in-memory services. This allows you to test your applications as they would run in production, but in a controlled and isolated environment.

It provides modules for commonly used infrastructure dependencies such as relational databases, NoSQL datastores, search engines, and message brokers.

If you have any specific questions about how to use Testcontainers or its features, I'd be happy to help.

Integration testing

Testing is a key part of software development. Fortunately, Testcontainers and Spring AI’s utilities support testing of GenAI applications. So far, we’ve been testing the application manually, starting the application and performing requests to the given endpoints, verifying the correctness of the response ourselves. Now, we’re going to automate it by writing an integration test to check if the answer provided by the LLM is more contextual, augmented by the information provided in the documents.

@SpringBootTest(classes = { TestcontainersConfiguration.class, IngestionConfiguration.class },
webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class RagControllerTest {

@LocalServerPort
private int port;

@Autowired
private VectorStore vectorStore;

@Autowired
private ChatClient.Builder chatClientBuilder;

@Test
void verifyTestcontainersAnswer() {
var question = "Tell me about Testcontainers";
var answer = retrieveAnswer(question);

assertFactCheck(question, answer);
}

private String retrieveAnswer(String question) {
RestClient restClient = RestClient.builder().baseUrl("http://localhost:%d".formatted(this.port)).build();
return restClient.get().uri("/rag?message={question}", question).retrieve().body(String.class);
}

private void assertFactCheck(String question, String answer) {
FactCheckingEvaluator factCheckingEvaluator = new FactCheckingEvaluator(this.chatClientBuilder);
EvaluationResponse evaluate = factCheckingEvaluator.evaluate(new EvaluationRequest(docs(question), answer));
assertThat(evaluate.isPass()).isTrue();
}

private List<Document> docs(String question) {
var response = RagController
.callResponseSpec(this.chatClientBuilder.build(), this.vectorStore, question)
.chatResponse();
return response.getMetadata().get(QuestionAnswerAdvisor.RETRIEVED_DOCUMENTS);
}

}

Importing ContainerConfiguration, Qdrant will be provided.

Importing IngestionConfiguration, will load the documents into the vector database.

We’re going to use FactCheckingEvaluator to tell the chat model (ai/llama3.1) to check the answer provided by the LLM and verify it with the documents stored in the vector database.

Note: The integration test is using the same model we have declared in the previous steps. But we can definitely use a different model.

Automating your tests ensures consistency and reduces the risk of errors that often come with manual execution. 

Observability with the Grafana LGTM Stack

Finally, let’s introduce some observability into our application. By introducing metrics and tracing, we can understand if our application is behaving as designed during development and in production.

Add the following dependencies to the pom.xml

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-otlp</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-tracing-bridge-otel</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>grafana</artifactId>
<scope>test</scope>
</dependency>

Now, let’s create GrafanaContainerConfiguration under src/test/java/com/example.

@TestConfiguration(proxyBeanMethods = false)
public class GrafanaContainerConfiguration {

@Bean
@ServiceConnection
LgtmStackContainer lgtmContainer() {
return new LgtmStackContainer("grafana/otel-lgtm:0.11.4");
}

}

Grafana provides the grafana/otel-lgtm image, which will start Prometheus, Tempo, and OpenTelemetry Collector, and other related services, all combined into a single convenient Docker image.

For the sake of our demo, let’s add a couple of properties at /src/test/resources/application.properties to sample 100% of requests.

spring.application.name=demo
management.tracing.sampling.probability=1

Update the TestDemoApplication class to include GrafanaContainerConfiguration.class

public class TestDemoApplication {

public static void main(String[] args) {
SpringApplication.from(DemoApplication::main)
.with(TestcontainersConfiguration.class, IngestionConfiguration.class, GrafanaContainerConfiguration.class)
.run(args);
}

}

Now, run ./mvnw spring-boot:test-run or ./gradlew bootTestRun one more time, and perform a request.

http :8080/rag message=="What’s testcontainers?"

Then, look for the following text in logs.

o.t.grafana.LgtmStackContainer : Access to the Grafana dashboard:

http://localhost:64908

The port can be different for you, but clicking on it should open the Grafana dashboard. This is where you can query for metrics related to the model or vector search, and also see the traces.

Figure 1: Grafana dashboard showing model metrics, vector search performance, and traces

We can also display the token usage metric used by the chat endpoint.

Figure 2: Grafana dashboard panel displaying token usage metrics for the chat endpoint

List traces for the service with name “demo”, and we can see a list of operations executed as part of this trace. You can use the trace ID with the name http get /rag to see the full control flow within the same HTTP request.

Figure 3:  Grafana dashboard showing trace details for a /rag endpoint in a Java GenAI application

Conclusion

Docker offers powerful capabilities that complement the Spring AI project, allowing developers to build GenAI applications efficiently with Docker tools that they know and trust. It simplifies the startup of service dependencies, including the Docker Model Runner, which exposes an OpenAI-compatible API for running local models. Testcontainers help to quickly spin out integration testing to evaluate your app by providing lightweight containers for your services and dependencies.  From development to testing, Docker and Spring AI have proven to be a reliable and productive combination for building modern AI-driven applications.

Learn more

Get an inside look at the design architecture of the Docker Model Runner. 

Explore the story behind our model distribution specification

Read our quickstart guide to Docker Model Runner.

Find documentation for Model Runner.

Visit our new AI solution page

Quelle: https://blog.docker.com/feed/

Docker Brings Compose to the Agent Era: Building AI Agents is Now Easy

Agents are the future, and if you haven’t already started building agents, you probably will soon. Across industries and use cases, agents can act on our behalf, and offload repetitive work, because they can act on our behalf with judgment and context. 

But while agentic development is moving fast, today it’s tedious, hard, and not fun: you need to quickly iterate with different prompts and models (both frontier models and local/open models), you need to find and connect MCP tools to internal data securely, and you need to declaratively package everything so that others can run your agent. And you need this to be built once, and run anywhere: on your laptop, in CI, or in production.

These problems are not new: they are what Docker was originally conceived for. It’s not an overstatement to say that once upon a time, Docker made microservices possible, and today we’re excited to share how we’re evolving Docker for the era of agents.

Launching today: Compose enters the agent era

Starting today, Docker makes it easy to build, ship, and run agents and agentic applications. Docker Compose launched a decade ago, and solved the problem of how to build and describe multi-container applications. It’s used and loved by millions of developers every day, which is why we’re excited to announce that we have agent building blocks in Compose.

Now, with just a compose.yaml, you can define your open models, agents, and MCP-compatible tools, then spin up your full agentic stack with a simple docker compose up. From dev to production (more on this later), your agents are wired, connected, and ready to run. 

Not just that. Compose is also seamlessly integrated with today’s most popular agentic frameworks:

LangGraph – Define your LangGraph workflow, wrap it as a service, plug it into compose.yaml, and run the full graph with docker compose up. Try the LangGraph tutorial.

Embabel – Use Compose to connect models, embed tools, and get a complete Embabel environment running. Explore the quickstart guide.

Vercel AI SDK – Compose makes it easy to stand up supporting agents and services locally. Check out the Vercel AI examples.

Spring AI – Use Compose to spin up vector stores, model endpoints, and agents alongside your Spring AI backend. View the Spring AI samples.

CrewAI – Compose lets you containerize CrewAI agents. Try the CrewAI Getting Started guide.

Google’s ADK – Easily deploy your ADK-based agent stack with Docker Compose- agents, tools, and routing layers all defined in a single file. Try our example. 

Agno – Use Compose to run your Agno-based agents and tools effortlessly. Explore the Agno example.

But the power of the new Docker Compose goes beyond SDKs: it’s deeply integrated with Docker’s broader suite of AI features.

Docker’s MCP Catalog gives you instant access to a growing library of trusted, plug-and-play tools for your agents. No need to dig through repos, worry about compatibility, or wire things up manually. Just drop what you need into your Compose file and you’re up and running.

Docker Model Runner lets you pull open-weight LLMs directly from Docker Hub, run them locally, and interact with them via built-in OpenAI-compatible endpoints, so your existing SDKs and libraries just work, no rewrites, no retooling. And they run with full GPU acceleration. But what if you don’t have enough local resources?

Introducing Docker Offload: Cloud power, local simplicity

When building agents, local resource limits shouldn’t slow you down. That’s why we’re introducing Docker Offload, a truly seamless way to run your models and containers on a cloud GPU.

Docker Offload frees you from infrastructure constraints by offloading compute-intensive workloads, like large language models and multi-agent orchestration, to high-performance cloud environments. No complex setup, no GPU shortages, no configuration headaches.

With native integration into Docker Desktop and Docker Engine, Docker Offload gives you a one-click path from Compose to cloud. Build, test, and scale your agentic applications just like you always have locally, while Docker handles the heavy lifting behind the scenes. It’s the same simple docker compose up experience, now supercharged with the power of the cloud.

And to get you started, we’re offering 300 minutes of free Offload usage. Try it out, build your agents, and scale effortlessly from your laptop to the cloud.

Compose is now production-ready with Google Cloud and Microsoft Azure

Last, but certainly not least, we’ve worked hard to make sure that the exact same Compose file you used during development works in production, with no rewrites and no reconfiguration.

We’re proud to announce new integrations with Google Cloud Run and Microsoft Azure Container Apps Service that allow Docker Compose to specify a serverless architecture. For example, with Google Cloud, you can deploy your agentic app directly to a serverless environment using the new gcloud run compose up command. And we’re working closely with Microsoft to bring this seamless experience to Azure as well.

From the first line of YAML to production deployment, Compose makes the entire journey consistent, portable, and effortless, just the way agentic development should be.

Let’s Compose the future. Together.

The future of software is agentic, where every developer builds goal-driven, multi-LLM agents that reason, plan, and act across a rich ecosystem of tools and services. 

With Docker Compose, Docker Offload, Docker’s broader AI capabilities, and our partnerships with Google, Microsoft, and Agent SDKs, we’re making that future accessible to, and easy for, everyone. 

In short: Docker is the easiest way to build, run, and scale intelligent agents, from development to production.

We can’t wait to see what you create.

Resources

Docker is simplifying Agent Development 

Explore the capabilities of Docker Offload

Learn more about our AI Agent: Ask Gordon 

Build Agentic Apps with Docker Compose 

Learn more about Docker Model Runner

Quelle: https://blog.docker.com/feed/

The 2025 Docker State of Application Development Report

Executive summary

The 2025 Docker State of Application Development Report offers an ultra high-resolution view of today’s fast-evolving dev landscape. Drawing insights from over 4,500 developers, engineers, and tech leaders — three times more users than last year — the survey explores tools, workflows, pain points, and industry trends. In this our third report, key themes emerge: AI is gaining ground but adoption remains uneven; security is now a shared responsibility across teams; and developers still face friction in the inner loop despite better tools and culture. With a broader, more diverse respondent base than our previous more IT-focused surveys, this year’s report delivers a richer, more nuanced view of how modern software is built and orgs operate.

2025 report key findings

IT is among the leaders in AI — with 76% of IT/SaaS pros using AI tools at work, compared with just 22% across industries. Overall, there’s a huge spread across industries — from 1% to 84%. 

Security is no longer a siloed specialty — especially when vulnerabilities strike. Just 1 in 5 organizations outsource security, and it’s top of mind at most others: only 1% of respondents say security is not a concern at their organization.

Container usage soared to 92% in the IT industry — up from 80% in our 2024 survey. But adoption is lower across other industries, at 30%. IT’s greater reliance on microservice-based architectures — and the modularity and scalability that containers provide — could explain the disparity.

Non-local dev environments are now the norm — not the exception. In a major shift from last year, 64% of developers say they use non-local environments as their primary development setup, with local environments now accounting for only 36% of dev workflows. 

Data quality is the bottleneck when it comes to building AI/ML-powered apps — and it affects everything downstream. 26% of AI builders say they’re not confident in how to prep the right datasets — or don’t trust the data they have. 

Developer productivity, AI, and security are key themes

Like last year’s survey, our 2025 report drills down into three main areas:

What’s helping devs thrive — and what’s still holding them back?

AI is changing software development — but not how you think

Security — it’s a team sport

1. What’s helping devs thrive — and what’s still holding them back?

Great culture, better tools — but developers often still hit sticking points. From pull requests held up in review to tasks without clear estimates, the inner loop remains cluttered with surprisingly persistent friction points.

How devs learn — and what’s changing

Self-guided learning is on the upswing. Across all industries, fully 85% of respondents turn to online courses or certifications, far outpacing traditional sources like school (33%), books (25%), or on-the-job training (25%). 

Among IT folks, the picture is more nuanced. School is still the top venue for learning to code (65%, up from 57% in our 2024 survey), but online resources are also trending upward. Some 63% of IT pros learned coding skills via online resources (up from 54% in our 2024 survey) and 57% favored online courses or certifications (up from 45% in 2024).

How devs like to learn

As for how devs prefer to learn, reading documentation tops the list, as in last year’s report — that despite the rise in new and interactive forms of learning. Some 29% say they lean on documentation, edging out videos and side projects (28% each) and slightly ahead of structured online training (26%). 

AI tools play a relatively minor role in how respondents learn, with GitHub Copilot cited by just 13% overall — and only 9% among IT pros. It’s also cited by 13% as a preferred learning method.

Online resources

When learning to code via online resources, respondents overwhelmingly favored technical documentation (82%) ahead of written tutorials and how-to videos (66% each), and blogs (63%).

Favorite online courses or certifications included Coursera (28%), LinkedIn Learning (24%), and Pluralsight (23%).

Discovering new tools

When it comes to finding out about new tools, developers tend to trust the opinions and insights of other developers — as evidenced by the top four selected options. Across industries, the main ways are developer communities, social media, and blogs (tied at 23%), followed closely by friends/colleagues (22%).

Within the IT industry only, the findings mirror last year’s, though blogs have moved up from third place to first. The primary ways devs learn about new tools are blogs (54%), developer communities (52%), and social media (50%), followed by searching online (48%) and friends/colleagues (46%).Conferences still play a significant role, with 34% of IT folks selecting this response, versus 17% across industries.

Open source contributions

Unsurprisingly, IT industry workers are more active in the open source space: 

48% contributed to open source in the past year, while 52% did not. 

That’s a slight drop from 2024, when 59% reported contributing and 41% had not.

Falling open source contributions could be worth keeping an eye on — especially with growing developer reliance on AI coding copilots. Could AI be chipping away at the need for open source code itself? Future studies could reveal whether this is a blip or a trend.

Across industries, just 13% made open source contributions, while 87% did not. But the desire to contribute is widespread — spanning industries as diverse as energy and utilities (91%), media or digital and education (90% each), and IT and engineering or manufacturing (82% each).

Mirroring our 2024 study, the biggest barrier to contributing to open source is time — 24%, compared with 40% in last year’s IT-focused study. Other barriers include not knowing where to start (18%) and needing guidance from others on how to contribute (15%).

Employers are often supportive: 37% allow employees to contribute to open source, while just 29% do not.

Tech stack

This year, we dove deeper into  the tech stack landscape to understand more about the application structures, languages, and frameworks devs are using — and how they have evolved since the previous survey.

Application structure

Asked about the structure of the applications they work on, respondents’ answers underscored the continued rise of microservices we saw in our 2024 report.

Thirty-five percent said they work on microservices-based applications — far more than those who work on monolithic or hybrid monolith/microservices (24% each), but still behind the 38% who work on client-server apps.

Non-local dev environments are now the norm — not the exception

The tides have officially turned. In 2025, 64% of developers say they use non-local environments as their primary development setup, up from just 36% last year. Local environments — laptops or desktops — now account for only 36% of dev workflows.

What’s driving the shift? A mix of flexible, cloud-based tooling:

Ephemeral or preview environments: 10% (↓ from 12% in 2024)

Personal remote dev environments or clusters: 22% (↑ from 11%)

Other remote dev tools (e.g., Codespaces, Gitpod, JetBrains Space): 12% (↑ from 8%)

Compared to 2024, adoption of persistent, personal cloud environments has doubled, while broader usage of remote dev tools is also on the rise.

Bottom line: As we’ve tracked since our first app dev report in 2022, the future of software development is remote, flexible, and increasingly cloud-native.

IDP adoption remains low — except at larger companies

Internal Developer Portals (IDPs) may be buzzy, but adoption is still in early days. Only 7% of developers say their team currently uses an IDP, while 93% do not.That said, usage climbs with company size. Among orgs with 5,000+ employees, IDP adoption jumps to 36%. IDPs aren’t mainstream yet — but at scale, they’re proving their value.

OS preferences hold steady — with Linux still on top

When it comes to operating systems for app development, Linux continues to lead the pack, used by 53% of developers — the same share as last year. macOS usage has ticked up slightly to 51% (from 50%), while Windows trails just behind at 47% (up from 46%).

The gap among platforms remains narrow, suggesting that today’s development workflows are increasingly OS-flexible — and often cross-platform.

Python surges past JavaScript in language popularity

Python is now the top language among developers, used by 64%, surpassing JavaScript at 57% and Java at 40%. That’s a big jump from 2024, when JavaScript held the lead.

Framework usage is more evenly spread: Spring Boot leads at 19%, with Angular, Express.js, and Flask close behind at 18% each.

Data store preferences are shifting

In 2025, MongoDB leads the pack at 21%, followed closely by MySQL/MariaDB and Amazon RDS (both at 20%). That’s a notable shift from 2024, when PostgreSQL (45%) topped the list.

Tool favorites hold

GitHub, VS Code, and JetBrains editors remain top development tools, as they did in our previous survey. And there’s little change across CI/CD, provisioning, and monitoring tools:

CI/CD: GitHub Actions (40%), GitLab (39%), Jenkins (36%)

Provisioning: Terraform (39%), Ansible (35%), GCP (32%)

Monitoring: Grafana (40%), Prometheus (38%), Elastic (34%)

Containers: the great divide?

Among IT pros, container usage soared to 92% — up from 80% in our 2024 survey. Zoom out to a broader view across industries, however, and adoption appears considerably lower. Just 30% of developers say they use containers in any part of their workflow. 

Why the gap? Differences in app structure may offer an explanation: IT industry respondents work with microservice-based architectures more often than those in other industries (68% versus 31%). So the higher container adoption may stem from IT pros’ need for modularity and scalability — which containers provide in spades.

And among container users, needs are evolving. They want better tools for time estimation (31% compared to 23% of all respondents), task planning (18% for both container users and all respondents), and monitoring/logging (16%) vs designing from scratch (18%) in the number 3 spot for all respondents — stubborn pain points across the software lifecycle.

An equal-opportunity headache: estimating time

No matter the role, estimating how long a task will take is the most consistent pain point across the board. Whether you’re a front-end developer (28%), data scientist (31%), or a software decision-maker (49%), precision in time planning remains elusive.

Other top roadblocks? Task planning (26%) and pull-request review (25%) are slowing teams down. Interestingly, where people say they need better tools doesn’t always match where they’re getting stuck. Case in point, testing solutions and Continuous Delivery (CD) come up often when devs talk about tooling gaps — even though they’re not always flagged as blockers.

Productivity by role: different hats, same struggles

When you break it down by role, some unique themes emerge:

Experienced developers struggle most with time estimation (42%).

Engineering managers face a three-way tie: planning, time estimation, and designing from scratch (28% each).

Data scientists are especially challenged by CD (21%) — a task not traditionally in their wheelhouse.

Front-end devs, surprisingly, list writing code (28%) as a challenge, closely followed by CI (26%).

Across roles, a common thread stands out: even seasoned professionals are grappling with foundational coordination tasks — not the “hard” tech itself, but the orchestration around it.

Tools vs. culture: two sides of the experience equation

On the tooling side, the biggest callouts for improvement across industries include:

Time estimation (23%)

Task planning (18%)

Designing solutions from scratch (18%)

Within the IT industry specifically, the top priority is the same — but even more prevalent:

Time estimation (31%)

Task planning (18%)

PR review (18%)

But productivity isn’t just about tools — it’s deeply cultural. When asked what’s working well, developers pointed to work-life balance (39%), location flexibility such as work from home policies (38%), and flexible hours (37%) as top cultural strengths.

The weak spots? Career development (38%), recognition (36%), and meaningful work (33%). In other words: developers like where, when, and how they work, but not always why.

What’s easy? What’s not?

While the dev world is full of moving parts, a few areas are surprisingly not challenging:

Editing config files (8%)

Debugging in dev (8%)

Writing config files (7%)

Contrast that with the most taxing areas:

Troubleshooting in production (9%)

Debugging in production (9%)

Security-related tasks (8%)

It’s a reminder that production is still where the stress — and the stakes — are highest.

2. AI is changing software development — but not how you think

Rumors of AI’s pervasiveness in software development have been greatly exaggerated. A look under the hood shows adoption is far from uniform. 

AI in dev workflows: two very different camps

One of the clearest splits we saw in the data is how people use AI at work. There are two groups:

Developers using AI tools like ChatGPT, Copilot, and Gemini to help with everyday tasks — writing, documentation, and research.

Teams building AI/ML applications from the ground up.

IT is among the leaders in AI 

Overall, only 22% of respondents said they use AI tools at work. But that number masks a huge spread across industries — from 1% to 84%. IT/SaaS folks sit near the top of the range at 76%. 

IT’s leadership in AI is even more marked when you look at how many are building AI/ML into apps: 

34% of IT/SaaS respondents say they do.

Only 8% of non-tech industries can say the same.

And the strategy gap is just as big. While 73% of tech companies say they have a clear AI strategy, only 16% of non-tech companies do. Translation: AI is gaining traction, but it’s still living mostly inside tech bubbles.

AI tools: overhyped and indispensable

Here’s the paradox: while 59% of respondents say AI tools are overhyped, 64% say they make their work easier.

Even more telling, 65% of users say they’re using AI more now than they did a year ago — and that they use it daily.

The hype is real. But for many devs, the utility is even more real.

These numbers track with our 2024 findings, too — where nearly two-thirds of devs said AI made their job easier, even as 45% weren’t fully sold on the buzz.

AI tool usage is up — and ChatGPT leads the pack

No big surprise here. ChatGPT is still the most-used AI tool by far. But the gap is growing.

Compared to last year’s survey:

ChatGPT usage jumped from 46% → 82%

GitHub Copilot: 30% → 57%

Google Gemini: 19% → 22%

Expect that trend to continue as more teams test drive (and trust) these tools in production workflows, moving from experimentation to greater integration.

Not all devs use AI the same way

While coding is the top AI use case overall, how devs actually lean on it varies by role:

Seasoned devs use AI for documentation and writing tests — but only lightly.

DevOps engineers use it to write docs and navigate CLI tools.

Software developers often turn to it for research and test automation.

And how dependent they feel on AI also shifts:

Seasoned devs: Often rate their dependence as 0/10.

DevOps engineers: Closer to 7/10.

Software devs: Usually around 5/10.

For comparison, the overall average dependence on AI in our 2024 survey was 4/10 (all users). Looking ahead, it will be interesting to see how dependence on AI shifts and becomes further integrated by role. 

The hidden bottleneck: data prep

When it comes to building AI/ML-powered apps, data is the choke point. A full 26% of AI builders say they’re not confident in how to prep the right datasets — or don’t trust the data they have.

This issue lives upstream but affects everything downstream — time to delivery, model performance, user experience. And it’s often overlooked.

Feelings around AI

How do people really feel about AI tools? Mostly positive — but it’s a mixed bag.

Compared to last year’s survey:

AI tools are a positive option: 65% → 66%

They allow me to focus on more important tasks: 55% → 63%

They make my job more difficult: 19% → 40%

They are a threat to my job: 23% → 44%

The predominant emotions around building AI/ML apps are distinctly positive — enthusiasm, curiosity, and happiness or interest.

3. Security — it’s a team sport

Why everyone owns security now

In the evolving world of software development, one thing is clear — security is no longer a siloed specialty. It’s a team sport, especially when vulnerabilities strike. Forget the myth that only “security people” handle security. Across orgs big and small, roles are blending. If you’re writing code, you’re in the security game. As one respondent put it, “We don’t have dedicated teams — we all do it.” 

Just 1 in 5 organizations outsource security.

Security is top of mind at most others: only 1% of respondents say security is not a concern at their organization.

One exception to this trend: In larger IT organizations (50+ employees), software security is more likely to be the exclusive domain of security engineers, with other types of engineers playing less of a role.

Devs, leads, and ops all claim the security mantle

It’s not just security engineers who are on alert. Team leads, DevOps pros, and senior developers all see themselves as responsible for security. And they’re all right. Security has become woven into every function.

When vulnerabilities hit, it’s all hands on deck

No turf wars here. When scan alerts go off, everyone pitches in — whether it’s security engineers helping experienced devs to decode scan results, engineering managers overseeing the incident, or DevOps engineers filling in where needed.

As in our 2024 survey, fixing vulnerabilities is the most common security task (30%) — followed by logging data analysis, running security scans, monitoring security incidents, and dealing with scan results (all tied at 24% each).

Fixing vulnerabilities is also a major time suck. Last year, respondents pointed to better vulnerability remediation tools as a key gap in the developer experience.

Security tools

For the second year in a row, SonarQube is the most widely used security tool, cited by 11% of respondents. But that’s a noticeable drop from last year’s 24%, likely due to the 2024 survey’s heavier focus on IT professionals.

Dependabot follows at 8%, with Snyk and AWS Security Hub close behind at 7% each — all showing lower adoption compared to last year’s more tech-centric sample.

Security isn’t the bottleneck — planning and execution are

Surprisingly, security doesn’t crack the top 10 issues holding teams back. Planning and execution-type activities are bigger sticking points.

Overall, across all industries and development-focused roles, security issues are the 11th and 14th most selected, way behind planning and execution type activities.

Translation? Security is better integrated into the workflow than ever before. 

Shift-left is yesterday’s news

The once-pervasive mantra of “shift security left” is now only the ninth most important trend (14%) — behind Generative AI (27%), AI assistants for software engineering (23%), and Infrastructure as Code (19%). Has the shift left already happened? Is AI and cloud complexity drowning it out? Or is this further evidence that security is, by necessity, shifting everywhere?

Our 2024 survey identified the shift-left approach as a possible source of frustration for developers and an area where more effective tools could make a difference. Perhaps security tools have gotten better, making it easier to shift left. Or perhaps there’s simply broader acceptance of the shift-left trend.

Shift-left may not be buzzy — but it still matters

It’s no longer a headline-grabber, but security-minded dev leads still value the shift-left mindset. They’re the ones embedding security into design, coding, CI/CD, and deployment.

Even if the buzz has faded, the impact hasn’t.

Conclusion

The 2025 Docker State of Application Development Report captures a fast-changing software landscape defined by AI adoption, evolving security roles, and persistent friction in developer workflows. While AI continues to gain ground, adoption remains uneven across industries. Security has become a shared responsibility, and the shift to non-local dev environments signals a more cloud-native future. Through it all, developers are learning, building, and adapting quickly.

In spotlighting these trends, the report doesn’t just document the now — it charts a path forward. Docker will continue evolving to meet the needs of modern teams, helping developers navigate change, streamline workflows, and build what’s next.

Methodology

The 2025 Docker State of Application Development Report was an online, 25-minute survey conducted by Docker’s User Research Team in the fall of 2024. The distribution was much wider than in previous years due to advertising the survey on a larger range of platforms.

Credits

This research was designed, conducted, and analyzed by the Docker UX Research Team: Rebecca Floyd, Ph.D.; Julia Wilson, Ph.D.; and Olga Diachkova.  

Quelle: https://blog.docker.com/feed/

Docker MCP Gateway: Open Source, Secure Infrastructure for Agentic AI

Since releasing the Docker MCP Toolkit, we’ve seen strong community adoption, including steady growth in MCP server usage and over 1 million pulls from the Docker MCP Catalog. With the community, we’re laying the groundwork by standardizing how developers define, run, and share agent-based workloads with Docker Compose. 

Now, we’re expanding on that foundation with the MCP Gateway, a new open-source project designed to help you move beyond local development and into production environments. The MCP Gateway acts as a secure enforcement point between agents and external tools. It integrates seamlessly with Docker Compose while enhancing the security posture of the broader MCP ecosystem.

We believe that infrastructure of this kind should be transparent, secure, and community-driven, which is why we’re open-sourcing all of this work. We’re excited to announce that the MCP Gateway project is available now in this public GitHub repository!

When we started building the MCP Gateway project, our vision was to enable a wide range of agents to access trusted catalogs of MCP servers. The goal was simple: make it easy and safe to run MCP servers. 

Figure 1: Architecture diagram of the MCP Gateway, securely orchestrating and managing MCP servers

This project’s tools are designed to help users discover, configure, and run MCP workloads. In the sections below, we’ll walk through these tools.

Discovery

To view entries in the current default catalog, use the following CLI command.

docker mcp catalog show

This is the set of servers that are available on your host.

As the Official MCP Registry continues to progress, the details for how MCP server authors publish will change. 

For now, we’ve created a PR-based process for contributing content to the Docker MCP Catalog.

Configure

To safely store secrets on an MCP host or to configure an MCP host to support OAuth-enabled MCP servers, we need to prepare the host. For example, servers like the Brave MCP server require an API key. To prepare your MCP host to inject this secret into the Brave MCP server runtime, we provide a CLI interface.

docker mcp secret set 'brave.api_key=XXXXX'

Some servers will also have host-specific configuration that needs to be made available to the server runtimes, usually in the form of environment variables. For example, both the filesystem, and resend server support host specific configurations.

cat << 'EOF' | docker mcp config write
filesystem:
paths:
– /Users/slim
resend:
reply_to: slim@gmail.com
sender: slim@slimslenderslacks.com
EOF

MCP servers have different requirements for host configuration and secret management, so we will need tools to manage this.

Run

An MCP Gateway exposes a set of MCP server runtimes.  For example, if clients should be able to connect to Google-maps and Brave, then those two servers can be enabled by default.

docker mcp server enable google-maps brave
docker mcp gateway run

However, each gateway can also expose custom views. For example, here is a gateway configuration that exposes only the Brave and Wikipedia servers, over SSE, and then only a subset of the tools from each.

docker mcp gateway run
–transport=sse
–servers=brave,wikipedia-mcp
–tools=brave_web_search,get_article,get_summary,get_related_topics

Secure

One of the advantages of a gateway process is that users can plug in generic interceptors to help secure any MCP server. By securing the MCP host, we can ease the adoption burden for any MCP client.

Expect this list to grow quickly, but we have an initial set of features available in the repository to begin demonstrating what’ll be possible.

Verify signatures – ensure that the gateway can verify provenance of the MCP container image before using it.

Block-secrets – scan inbound and outbound payloads for content that looks like secrets of some kind.

Log-calls

These can be enabled when starting the gateway.

docker mcp gateway run
–verify-signatures
–log-calls
–block-secrets

Summary

The MCP Gateway is Docker’s answer to the growing complexity and security risks of connecting AI agents to MCP servers. By aggregating multiple MCP servers behind a single, secure interface, it gives developers and teams a consistent way to build, scale, and govern agent-based workloads from local development to production environments.

The Gateway is available out of the box in the latest release of Docker Desktop. Now open source, it’s also ready for you to use with any community edition of Docker. Whether you’re building AI agents or supporting others who do, the MCP Gateway is a great foundational tool for developing secure, scalable agentic applications with MCP. Visit the Gateway GitHub repository to get started!
Quelle: https://blog.docker.com/feed/

Compose your way with Provider services!

With the release of Docker Compose v2.36.0, we’re excited to introduce a powerful new feature: provider services. This extension point opens up Docker Compose to interact not only with containers but also with any kind of external system, all while keeping the familiar Compose file at the center of the workflow.

In this blog post, we’ll walk through what provider services are, how developers can use them to streamline their workflows, how the provider system works behind the scenes, and how you can build your own provider to extend Compose for your platform needs.

Why Provider Services Are a Game-Changer

Docker Compose has long been a favorite among developers for orchestrating multi-container applications in a simple and declarative way. But as development environments have become more complex, the need to integrate non-container dependencies has become a common challenge. Applications often rely on managed databases, SaaS APIs, cloud-hosted message queues, VPN tunnels, or LLM inference engines — all of which traditionally sit outside the scope of Compose.

Developers have had to resort to shell scripts, Makefiles, or wrapper CLIs to manage these external components, fragmenting the developer experience and making it harder to onboard new contributors or maintain consistent workflows across teams.

Provider services change that. By introducing a native extension point into the Compose, developers can now define and manage external resources directly in their compose.yaml. Compose delegates their lifecycle to the provider binary, coordinating with it as part of its own service lifecycle.

This makes Docker Compose a more complete solution for full-stack, platform-aware development — from local environments to hybrid or remote setups.

Using a Provider Service in Your Compose File

Provider services are declared like any other Compose service, but instead of specifying an image, you specify a provider with a type, and optionally some options. The type must correspond to the name of a binary available in your $PATH that implements the Compose provider specification.

As an example we will use the Telepresence provider plugin, which routes Kubernetes traffic to a local service for live cloud debugging. This is especially useful for testing how a local service behaves when integrated into a real cluster:

In this setup, when you run docker compose up, Compose will call the compose-telepresence plugin binary. The plugin performs the following actions:

Up Action:

Check if the Telepresence traffic manager is installed in the Kubernetes cluster, and install it if needed.

Establish an intercept to re-route traffic from the specified Kubernetes service to the local service.

Down Action:

Remove the previously established intercept.

Uninstall the Telepresence traffic manager from the cluster.

Quit the active Telepresence session.

The structure and content of the options field are specific to each provider. It is up to the plugin author to define and document the expected keys and values.If you’re unsure how to properly configure your provider service in your Compose file, the Compose Language Server (LSP) can guide you step by step with inline suggestions and validation.

You can find more usage examples and supported workflows in the official documentation: https://docs.docker.com/compose/how-tos/provider-services/

How Provider Services Work Behind the Scenes

Under the hood, when Compose encounters a service using the provider key, it looks for an executable in the user’s $PATH matching the provider type name (e.g. docker-model cli plugin or compose-telepresence). Compose then spawns the binary and passes the service options as flags, allowing the provider to receive all required configuration via command-line arguments.

The binary must respond to JSON-formatted requests on stdin and return structured JSON responses on stdout.

Here’s a diagram illustrating the interaction:

Communication with Compose

Compose send all the necessary information to the provider binary by transforming all the options attributes as flags. It also passes the project and the service name. If we look at the compose-telepresence provider example, on the up command Compose will execute the following command:

$ compose-telepresence compose –project-name my-project up –name api –port 5732:api-80 –namespace avatars –service api dev-api

On the other side, providers can also send runtime messages to Compose:

info: Reports status updates. Displayed in Compose’s logs.

error: Reports an error. Displayed as the failure reason.

setenv: Exposes environment variables to dependent services.

debug: Debug messages displayed only when running Compose with -verbose.

This flexible protocol makes it easy to add new types and build rich provider integrations.

Refer to the official protocol spec for detailed structure and examples.

Building Your Own Provider Plugin

The real power of provider services lies in their extensibility. You can write your own plugin, in any language, as long as it adheres to the protocol.

A typical provider binary implements logic to handle a compose command with up and down subcommands.

The source code of compose-telepresence-plugin will be a good starting point. This plugin is implemented in Go and wraps the Telepresence CLI to bridge a local dev container with a remote Kubernetes service.

Here’s a snippet from its up implementation:

This method is triggered when docker compose up is run, and it starts the service by calling the Telepresence CLI based on the received options.

To build your own provider:

Read the full extension protocol spec

Parse all the options as flags to collect the whole configuration needed by the provider

Implement the expected JSON response handling over /stdout

Don’t forget to add debug messages to have as many details as possible during your implementation phase.

Compile your binary and place it in your $PATH

Reference it in your Compose file using provider.type

You can build anything from service emulators to remote cloud service starters. Compose will automatically invoke your binary as needed.

What’s Next?

Provider services will continue to evolve, future enhancements will be guided by real-world feedback from users to ensure provider services grow in the most useful and impactful directions.

Looking forward, we envision a future where Compose can serve as a declarative hub for full-stack dev environments,  including containers, local tooling, remote services, and AI runtimes.

Whether you’re connecting to a cloud-hosted database, launching a tunnel, or orchestrating machine learning inference, Compose provider services give you a native way to extend your dev environment, no wrappers, no hacks.

Let us know what kind of providers you’d like to build or see added. We can’t wait to see how the community takes this further.

Stay tuned and happy coding!

Quelle: https://blog.docker.com/feed/

Introducing Docker Hub MCP Server: A New Way to Discover, Inspect, and Manage Container Images

Docker Hub has become an essential resource for developers worldwide, serving 11 billion monthly image downloads and hosting over 14 million container images. As agentic AI proliferates, we’re seeing a significant shift in how developers work. More and more developers are leveraging MCP (Model Context Protocol) servers to power their AI agents and automated workflows. These agentic systems can connect to real data and provide intelligent recommendations, but they need access to comprehensive, structured information to be truly effective.

Recognizing this shift, we’re adapting to meet developers where they are. Today, we’re excited to introduce the Docker Hub MCP Server, a tool that bridges the gap between Docker Hub’s vast catalog of container images and the intelligent capabilities of LLMs. By leveraging MCP, this server transforms how developers discover, evaluate, and manage container images, making the entire process more intuitive and efficient.

What is the Docker Hub MCP Server?

The Docker Hub MCP Server is an MCP server that interfaces with Docker Hub APIs to make them accessible to LLMs, enabling intelligent content discovery and repository management. Developers building with containers, especially in AI and LLM-powered workflows, often find that LLMs lack the context needed to select the right image from Docker Hub’s vast catalog. As a result, LLMs struggle to recommend the right images, and developers lose time manually searching instead of building.

Figure 1: The Docker Hub MCP server empowers LLMs and agents with secure content discovery and streamlined repository management.

The Docker Hub MCP Server streamlines your workflow through:

Frictionless setup: No complex local installation or runtime configuration needed. Just one-click install through the MCP Catalog and Toolkit, and you’re ready to go.

Intelligent container image discovery: Provides LLMs with detailed, structured context for Docker Hub images while enabling natural language image discovery — just describe what you need instead of remembering complex tags or repository names.

Simplified Repository Management: Hub MCP Server enables agents to manage repositories through natural language, fetching image details, viewing stats, searching content, and performing key operations quickly and easily.

Enable Docker Hub MCP Server in MCP Toolkit

From the MCP Toolkit menu, select the Catalog tab, search for Docker Hub, and select the plus icon to add the Docker Hub MCP server.

In the server’s Configuration tab, insert your Docker Hub username and personal access token (PAT).

Use Gordon / Docker AI

You can configure Gordon to be a host that can interact with the Docker Hub MCP server.

In the Clients tab in MCP Toolkit, ensure Gordon is connected.

From the Ask Gordon menu, you can now send requests related to your Docker Hub account, in accordance with the tools provided by the Docker Hub MCP server. To test it, ask Gordon: List all repositories in my namespace

Figure 2: Enabling Docker Hub MCP Server in MCP Toolkit

Use Claude Desktop

To configure the Docker Hub MCP Server with Claude Desktop, you don’t need to install the server directly in Claude Desktop. Instead, install the MCP Server using the MCP Toolkit, then add Claude Desktop as a client.

From the Clients tab, select Connect next to Claude Desktop. Restart Claude Desktop if it’s running, and it can now access all the servers in the MCP Toolkit.

Use VS Code

To configure the Docker Hub MCP Server with VS Code, follow the setup instructions in the official documentation.

What’s next?

This is just the beginning for the Docker Hub MCP Server. We’re continuing to expand its capabilities to make container workflows even more intelligent, efficient, and developer-friendly. Keep an eye on the Docker blog for deeper dives, tips, and the latest product announcements.

Learn more

Get the Docker Hub MCP Server from the Docker MCP Catalog.

Visit the repository on GitHub.

Subscribe to the Docker Navigator Newsletter.

New to Docker? Create an account. 

Have questions? The Docker community is here to help.

Quelle: https://blog.docker.com/feed/

From Dev to Deploy: Compose as the Spine of the Application Lifecycle

Nobody wants a spineless application development process. What do I mean by this? The spine is the backbone that supports and provides nerve channels for the human body. Without it, we would be floppy, weaker, and would struggle to understand how our extremities were behaving. A slightly tortured analogy, but consider the application lifecycle of the average software project. The traditional challenge has been, how do we give it a spine? How can we provide a backbone to support developers at every stage and a nerve channel to pass information back and forth, thereby cementing architectural constructs and automating or simplifying all the other processes required for modern applications?

We built Docker Compose specifically to be that spine, providing the foundation for an application from its inception in local development through testing and on to final deployment and maintenance as the application runs in the wild and interacts with real users. With Docker Compose Bridge, Docker Compose filled out the last gaps in full application lifecycle management. Using Compose Bridge, teams can now, with a single Compose file, take a multi-container, multi-tiered application from initial code and development setup all the way to production deployment in Kubernetes or other container orchestration systems.

Before and After: How Docker Compose Adds the Spine and Simplifies AppDev

So what does this mean in practice? Let’s take a “Before” and “After” view of how the spine of Docker Compose changes application lifecycle processes for the better. Imagine you’re building a customer-facing SaaS application—a classic three-tier setup:

Go API handling user accounts, payments, and anti-fraud check

PostgreSQL + Redis for persistence and caching

TypeScript/React UI that customers log into and interact with

You are deploying to Kubernetes because you want resilience, portability, and flexibility. You’ll deploy it across multiple regions in the cloud for low latency and high availability. Let’s walk through what that lifecycle looks like before and after adopting Docker Compose + Compose Bridge.

Before: The Local Development “Works on My Machine” Status Quo

Without Compose, you set up five separate containers with a messy sprawl that might look something that looks like this:

docker network create saas-net
docker run -d –name postgres –network saas-net
-e POSTGRES_PASSWORD=secret postgres:16
docker run -d –name redis –network saas-net redis:7
docker run -d –name go-api –network saas-net
-e DB_URL=postgres://postgres:secret@postgres/saasdb
-p 8080:8080 go-saas-api:latest
docker run -d –name payments –network saas-net payments-stub:1.2
docker run -d –name fraud –network saas-net anti-fraud:latest
docker run -d –name saas-ui –network saas-net
-p 3000:3000 saas-ui:latest

You can certainly automate the setup process with a script. But that would mean everyone else you are working with would need the same script to replicate your setup. You would also need to ensure that they all have the same updated script. And that’s not the end of it. Before Compose, setting up even a basic multi-service stack meant manually crafting networks and links—typically running docker network create and then launching each container with –network to stitch them together (see Docker run network options). Onboarding new developers only made matters worse: your README would balloon with dozens of flags and environment-variable examples, and inevitably, someone would mistype a port or misspell a variable name. Meanwhile, security and compliance tended to be afterthoughts.

There would be no standard WAF or API gateway in front of your services. In many instances, secrets were scattered in plain .env files, and you would have no consistent audit logging to prove who accessed what and who made what changes. Then, for debugging, you manually spin up phpPgAdmin; for observability, you install Prometheus and Jaeger on an ad-hoc basis. For vulnerability scanning, you would pull down Docker Scout each time. Both debugging and scanning would drag you outside your core workflow and break your vibe.

After: One Line for Universal Local Environment

Remember those five containers you had to set up individually? Now, your Docker Compose “Spine” carries the message and structure to automatically set all those up for you with a single command and a single file (compose.yaml)

The resulting YAML pulls down and lists in a readable format the entire setup (database, cache, API, UI/UX) of your setup, all living on a shared network with security, observability, and any other necessary services already in place. Not only does this save time and ensure consistency, but it also greatly boosts security (manual config error remains one of the leading sources of security breaches, according to the Verizon 2025 DBIR Report). This also standardizes all mounts and ports, ensuring secrets are treated uniformly. For compliance and artifact provenance, all audit logs are automatically mounted for local compliance checks.

Compose also makes debugging and hardening apps locally easier for developers who don’t want to think about setting up debug services. With Compose, the developer or platform team can add a debug profile that invokes a host of debug services (Prometheus for metrics, OpenTelemetry for distributed tracing, Grafana for dashboards, ModeSec for firewall rules). That said, you don’t want to add debug services to production apps in Kubernetes.

Enter Compose Bridge. This new addition to Docker Compose incorporates environmental awareness into all services, removing those that should not be deployed in production, and provides a clean Helm Chart or YAML manifest for production teams. So application developers don’t need to worry about stripping service calls before throwing code over the fence. More broadly, Compose Bridge enforces:

Clean separation – production YAML stays lean, with no leftover debug containers or extra resource definitions.

Conditional inclusion – Bridge reads profiles: settings and injects the right labels, annotations, and sidecars only when you ask for them.

Consistent templating – Bridge handles the profile logic at generation time, so all downstream manifests conform to stage and environment-specific policies and naming conventions

The result? Platform Operations teams can maintain different Docker Compose templates for various application development teams, keeping everyone on the established paths while providing customization where needed. Application Security teams can easily review or scan standardized YAML files to simplify policy adherence across configuration verification, secret handling, and services accessed.

Before:  CI & Testing Lead to Script Sprawl and Complexity

Application developers pass their code off to the DevOps team (or have the joy of running the CI/CD gauntlet themes). Teams typically wire up their CI tool (Jenkins, GitLab CI, GitHub Actions, etc.) to run shell-based workflows. Any changes to the application, like renaming a service, adding a dependency, adjusting a port, or adding a new service, mean editing those scripts or editing every CI step that invokes them. In theory, GitOps means automating much of this. In practice, the complexity is thinly buried and the system lacks, for better or for worse, a nervous system along the spine. The result? Builds break, tests fail, and the time to launch a new version and incorporate new code lengthens. Developers are inherently discouraged from shipping code faster because they know there’s a decent chance that even when everything shows green in their local environment tests, something will break in CI/CD. This dooms them to unpleasant troubleshooting ordeals. Without a nervous system along the spine to share information and easily propagate necessary changes, application lifecycles are more chaotic, less secure and less efficient. 

After: CI & Testing Run Fast, Smooth and Secure

After adopting Docker Compose as your application development spine, your CI/CD pipeline becomes a concise, reliable sequence that mirrors exactly what you run locally. A single compose.yaml declares every component so your CI job simply brings up the entire stack with docker compose up -d, orchestrating startup order and health checks without custom scripts or manual delays. You invoke your tests in the context of a real multi-container network via docker compose exec, replacing brittle mocks with true integration and end-to-end validation. When testing is complete, docker compose down tears down containers, networks, and volumes in one step, guaranteeing a clean slate for every build. Because CI consumes exactly the same manifest developers use on their workstations, feedback loops shrink to minutes, and promotions to staging or production require fewer (and often no) manual configuration tweaks.

Compose Bridge further elevates this efficiency and hardens security. After running tests, Bridge automatically converts your Docker Compose YAML file into Kubernetes manifests or a Helm chart, injecting network policies, security contexts, runtime protection sidecars, and audit log mounts based on your profiles and overlays. There’s no need for separate scripts or manual edits to bake in contract tests, policy validations, or vulnerability scanners. Your CI job can commit the generated artifacts directly to a GitOps repository, triggering an automated, policy-enforced rollout across all environments. This unified flow eliminates redundant configuration, prevents drift, and removes human error, turning CI/CD from a fragile sequence into a single, consistent pipeline.

Before: Production and Rollbacks are Floppy and Floundering 

When your application leaves CI and enters production, the absence of a solid spine becomes painfully clear. Platform teams must shoulder the weight of multiple files — Helm charts, raw manifests for network segmentation, pod security, autoscaling, ingress rules, API gateway configuration, logging agents, and policy enforcers. Each change ripples through, requiring manual edits in three or more places before nerves can carry the signal to a given cluster. There is no central backbone to keep everything aligned. A simple update to your service image or environment variable creates a cascade of copy-and-paste updates in values.yaml, template patches, and documentation. If something fails, your deployment collapses and you start manual reviews to find the source of the fault. Rolling back demands matching chart revisions to commits and manually issuing helm rollback. Without a nervous system to transmit clear rollback signals, each regional cluster becomes its own isolated segment. Canary and blue-green releases require separate, bespoke hooks or additional Argo CD applications, each one a new wrinkle in coordination. This floppy and floundering approach leaves your production lifecycle weak, communication slow, and the risk of human error high. The processes meant to support and stabilize your application instead become sources of friction and uncertainty, undermining the confidence of both engineering and operations teams.

After: Production and Rollbacks are Rock Solid

With Docker Compose Bridge acting as your application’s spinal cord, production and rollbacks gain the support and streamlined communication they’ve been missing. Your single compose.yaml file becomes the vertebral column that holds every service definition, environment variable, volume mount, and compliance rule in alignment. When you invoke docker compose bridge generate, the Bridge transforms that backbone into clean Kubernetes manifests or a Helm chart, automatically weaving in network policies, pod security contexts, runtime protection sidecars, scaling rules, and audit-log mounts. There is no need for separate template edits. Changes made to the Compose file propagate in real-time through all generated artifacts. Deployment can be as simple as committing the updated Compose file to your GitOps repository. Argo CD or Flux then serves as the extended nervous system, transmitting the rollout signal across every regional cluster in a consistent, policy-enforced manner. If you need to reverse course, reverting the Compose file acts like a reflex arc: Bridge regenerates the previous manifests and GitOps reverts each cluster to its prior state without manual intervention. Canary and blue-green strategies fit naturally into this framework through Compose profiles and Bridge overlays, eliminating the need for ad-hoc hooks. Your production pipeline is no longer a loose bundle of scripts and templates but a unified, resilient spine that supports growth, delivers rapid feedback, and ensures secure, reliable releases across all environments.

A Fully Composed Spine for the Full Lifecycle

To summarize, Docker Compose and Compose Bridge give your application a continuous spine running from local development through CI / CD, security validation and multi-region Kubernetes rollout. You define every service, policy and profile once in a Compose file, and Bridge generates production ready manifests with network policies, security contexts, telemetry, database, API and audit-log mounts already included. Automated GitOps rollouts and single-commit rollbacks make deployments reliable and auditable and fast. This helps application developers focus on features instead of plumbing, gives AppSec consistent policy enforcement, allows SecOps to maintain standardized audit trails, helps PlatformOps simplify operations and delivers faster time to market with reduced risk for the business.

Ready to streamline your pipeline and enforce security? Give it a try in your next project by defining your stack in Compose, then adding Bridge to automate manifest generation and GitOps rollouts.
Quelle: https://blog.docker.com/feed/

Docker Desktop 4.43: Expanded Model Runner, Reimagined MCP Catalog, MCP Server Submissions, and Smarter Gordon

Docker Desktop 4.43 just rolled out a set of powerful updates that simplify how developers run, manage, and secure AI models and MCP tools. 

Model Runner now includes better model management, expanded OpenAI API compatibility, and fine-grained controls over runtime behavior. The improved MCP Catalog makes it easier to discover and use MCP servers, and now supports submitting your own MCP servers! Meanwhile, the MCP Toolkit streamlines integration with VS Code and GitHub, including built-in OAuth support for secure authentication. Gordon, Docker’s AI agent, now supports multi-threaded conversations with faster, more accurate responses. And with the new Compose Bridge, you can convert local compose.yaml files into Kubernetes configuration in a single command. 

Together, these updates streamline the process of building agentic AI apps and offer a preview of Docker’s ongoing efforts to make it easier to move from local development to production.

New model management commands and expanded OpenAI API support in Model Runner

This release includes improvements to the user interface of the Docker Model Runner, the inference APIs, and the inference engine under the hood.

Starting with the user interface, developers can now inspect models (including those already pulled from Docker Hub and those available remotely in the AI catalog) via model cards available directly in Docker Desktop. Below is a screenshot of what the model cards look like:

Figure 1: View model cards directly in Docker Desktop to get an instant overview of all variants in the model family and their key features.

In addition to the GUI changes, the docker model command adds three new subcommands to  help developers inspect, monitor, and manage models more effectively:

docker model ps: Show which models are currently loaded into memory

docker model df: Check disk usage for models and inference engines

docker model unload: Manually unload a model from memory (before its idle timeout)

For WSL2 users who enable Docker Desktop integration, all of the docker model commands are also now available from their WSL2 distros, making it easier to work with models without changing your Linux-based workflow.

On the API side, Model Runner now offers additional OpenAI API compatibility and configurability. Specifically, tools are now supported with {“stream”: “true”}, making agents built on Docker Model Runner more dynamic and responsive. Model Runner’s API endpoints now support OPTIONS calls for better compatibility with existing tooling. Finally, developers can now configure CORS origins in the Model Runner settings pane, offering better compatibility and control over security. 

Figure 2: CORS Allowed Origins are now configurable in Docker Model Runner settings, giving developers greater flexibility and control.

For developers who need fine-grained control over model behavior, we’re also introducing the ability to set a model’s context size and even the runtime flags for the inference engine via Docker Compose, for example:

services:
mymodel:
provider:
type: model
options:
model: ai/gemma3
context-size: 8192
runtime-flags: "–no-prefill-assistant"

In this example, we’re using the (optional) context-size and runtime-flags parameters to control the behavior of the inference engine underneath. In this case, the associated runtime is the default (llama.cpp), and you can find a list of flags here. Certain flags may override the stable default configuration that we ship with Docker Desktop, but we want users to have full control over the inference backend. It’s also worth noting that a particular model architecture may limit the maximum context size. You can find information about maximum context lengths on the associated model cards on Docker Hub.

Under the hood, we’ve focused on improving stability and usability. We now have better error reporting in the event that an inference process crashes, along with more aggressive eviction of crashed engine processes. We’ve also enhanced the Docker CE Model Runner experience with better handling of concurrent usage and more robust support for model providers in Compose on Docker CE.

MCP Catalog & Toolkit: Secure, containerized AI tools at scale

New and redesigned MCP Catalog 

Docker’s MCP Catalog now features an improved experience, making it easier to search, discover, and identify the right MCP servers for your workflows. You can still access the catalog through Docker Hub or directly from the MCP Toolkit in Docker Desktop, and now, it’s also available via a dedicated web link for even faster access. 

Figure 3: Quickly find the right MCP server for your agentic app and use the new Catalog to browse by specific use cases.

The MCP Catalog currently includes over 100 verified, containerized tools, with hundreds more on the way. Unlike traditional npx or uvx workflows that execute code directly on your host, every MCP server in the catalog runs inside an isolated Docker container. Each one includes cryptographic signatures, a Software Bill of Materials (SBOM), and provenance attestations. 

This approach eliminates the risks of running unverified code and ensures consistent, reproducible environments across platforms. Whether you need database connectors, API integrations, or development tools, the MCP Catalog provides a trusted, scalable foundation for AI-powered development workflows that move the entire ecosystem away from risky execution patterns toward production-ready, containerized solutions.

Submit your MCP Server to the Docker MCP Catalog

We’re launching a new submission process, giving developers flexible options to contribute by following the process here.  Developers can choose between two options: Docker-Built and Community-Built servers. 

Docker-Built Servers 

When you see “Built by Docker,” you’re getting our complete security treatment. We control the entire build pipeline, providing cryptographic signatures, SBOMs, provenance attestations, and continuous vulnerability scanning.

Community-Built Servers 

These servers are packaged as Docker images by their developers. While we don’t control their build process, they still benefit from container isolation, which is a massive security improvement over direct execution.

Docker-built servers demonstrate the gold standard for security, while community-built servers ensure we can scale rapidly to meet developer demand. Developers can change their mind after submitting a community-built server and opt to resubmit it as a Docker-built server. 

Get your MCP server featured in the Docker MCP Catalog today and reach over 20 million developers. Learn more about our new MCP Catalog in our announcement blog and get insights on best practices on building, running, and testing MCP servers.  Join us in building the largest library of secure, containerized MCP servers! .

MCP Toolkit adds OAuth support and streamlined Integration with GitHub and VS Code

Many MCP servers’ credentials are passed as plaintext environment variables, exposing sensitive data and increasing the risk of leaks. The MCP Toolkit eliminates that risk with secure credential storage, allowing clients to authenticate with MCP servers and third-party services without hardcoding secrets. We’re taking it a step further with OAuth support, starting with the most widely used developer tool, GitHub. This will make it even easier to integrate secure authentication into your development workflow.

Figure 4: OAuth is now supported for the GitHub MCP server.

To set up your GitHub MCP server, go to the OAuth tab, connect your GitHub account, enable the server, and authorize OAuth for secure authentication.

Figure 5: Go to the configurations tab of the GitHub MCP servers to enable OAuth for secure authentication

The MCP Toolkit allows you to connect MCP servers to any MCP client, with one-click connection to popular ones such as Claude and Cursor. We are also making it easier for developers to connect to VSCode with the docker mcp client connect vscode command. When run in your project’s root folder, it creates an mcp.json configuration file in your .vscode folder. 

Figure 6: Connect to VS Code via MCP commands in the CLI.

Additionally, you can also configure the MCP Toolkit as a global MCP server available to VSCode by adding the following config to your user settings. Check out this doc for more details. Once connected, you can leverage GitHub Copilot in agent mode with full access to your repositories, issues, and pull requests.

"mcp": {
"servers": {
"MCP_DOCKER": {
"command": "docker",
"args": [
"mcp",
"gateway",
"run"
],
"type": "stdio"
}
}
}

Gordon gets smarter: Multi-threaded conversations and 5x faster performance

Docker’s AI Agent Gordon just got a major upgrade: multi-threaded conversation support. You can now run multiple distinct conversations in parallel and switch between topics like debugging a container issue in one thread and refining a Docker Compose setup in another, without losing context. Gordon keeps each thread organized, so you can pick up any conversation exactly where you left off.

Gordon’s new multi-threaded capabilities work hand-in-hand with MCP tools, creating a powerful boost for your development workflow. Use Gordon alongside your favorite MCP tools to get contextual help while keeping conversations organized by task. No more losing focus to context switching!

Figure 7: Gordon’s new multi-threaded support cuts down on context switching and boosts productivity.

We’ve also rolled out major performance upgrades, Gordon now responds 5x faster and delivers more accurate, context-aware answers. With improved understanding of Docker-specific commands, configurations, and troubleshooting scenarios, Gordon is smarter and more helpful than ever!

Compose Bridge: Seamlessly go from local Compose to Kubernetes 

We know that developers love Docker Compose for managing local environments—it’s simple and easy to understand. We’re excited to introduce Compose Bridge to Docker Desktop. This new powerful feature helps you transform your local compose.yaml into Kubernetes configuration with a single command.

Translate Compose to Kubernetes in seconds

Compose Bridge gives you a streamlined, flexible way to bring your Compose application to Kubernetes. With smart defaults and options for customization, it’s designed to support both simple setups and complex microservice architectures.

All it takes is:

docker compose bridge convert

And just like that, Compose Bridge generates the following Kubernetes resources from your Compose file:

A Namespace to isolate your deployment

A ConfigMap for every Compose config entry

Deployments for running and scaling your services

Services for exposed and published ports—including LoadBalancer services for host access

Secrets for any secrets in your Compose file (encoded for local use)

NetworkPolicies that reflect your Compose network topology

PersistentVolumeClaims using Docker Desktop’s hostpath storage

This approach replicates your local dev environment in Kubernetes quickly and accurately, so you can test in production-like conditions, faster.

Built-in flexibility and upcoming enhancements

Need something more customized? Compose Bridge supports advanced transformation options so you can tweak how services are mapped or tailor the resulting configuration to your infrastructure.

And we’re not stopping here—upcoming releases will allow Compose Bridge to generate Kubernetes config based on your existing cluster setup, helping teams align development with production without rewriting manifests from scratch.

Get started

You can start using Compose Bridge today:

Download or update Docker Desktop

Open your terminal and run:

Review the documentation to explore customization options

docker compose bridge convert

Conclusion 

Docker Desktop 4.43 introduces practical updates for developers building at the intersection of AI and cloud-native apps. Whether you’re running local models, finding and running secure MCP servers, using Gordon for multi-threaded AI assistance, or converting Compose files to Kubernetes, this release cuts down on complexity so you can focus on shipping. From agentic AI projects to scaling workflows from local to production, you’ll get more control, smoother integration, and fewer manual steps throughout.

Learn more

Learn more about our new MCP Catalog. 

Submit your MCP servers to the MCP Catalog. 

Authenticate and update today to receive your subscription level’s newest Docker Desktop features.

Subscribe to the Docker Navigator Newsletter.

Learn about our sign-in enforcement options.

New to Docker? Create an account. 

Have questions? The Docker community is here to help.

Quelle: https://blog.docker.com/feed/

5 Best Practices for Building, Testing, and Packaging MCP Servers 

We recently launched a new, reimagined Docker MCP Catalog with improved discovery and a new submission process. Containerized MCP servers offer a secure way to run and scale agentic applications and minimize risks tied to host access and secret management. Developers can submit servers in two ways: Docker-built servers, which include our full security suite (signatures, SBOMs, attestations, and continuous scanning), or community-built servers, which are built and maintained by developers using their own Docker images.

In this blog, we’ll share 5 MCP server best practices for designing, testing, and packaging them for submission. These recommendations are based on our experience building and helping developers build over 100 MCP servers for the Docker MCP Catalog. They’ll help you streamline the submission process, reach over 20 million Docker developers, and deliver real utility to both agents and the developers who use them.

1. Manage your agent’s tool budget intentionally

“Tool Budget” is our internal term for the number of tools an agent can handle effectively. Like any budget, managing it well is key to a good user experience. As the creator of an MCP server, it’s important to consider that offering too many tools can make your server more complex and costly to use, potentially turning users away. Some AI agents now allow users to selectively enable tools, helping keep the experience streamlined. But the better strategy is to design your toolset around clear use cases and avoid mapping every API endpoint to a separate tool.

For example, when creating an MCP server to access your API, you might be tempted to make one tool for each of the API’s endpoints. While that’s a quick way to get started, it often results in an overloaded toolset that discourages adoption.

So, if one tool per endpoint isn’t ideal, how do you design a better MCP server?

This is where the MCP server prompts come in. Think of them like Macros. Instead of requiring users to call multiple tools, you can create a single prompt that chains multiple tools or endpoint calls behind the scenes. That way, a user can simply ask the agent to “fetch my user’s invoices,” and the agent can handle the complexity internally, calling two or three tools without exposing the overhead.

2. The end user of the tool is the agent/LLM

One important point often overlooked: it’s the agent or LLM, not the end user, that actually uses the tool. The user enables the tool, but the agent is the one calling it. Why does this matter? When you’re building an MCP server, you’re not interfacing directly with users. You’re building for the agent that acts on their behalf.

Error handling is one area where we’ve consistently seen developers run into issues. If your tool returns error messages meant for humans, you might not provide the user experience you think. The agent, not the user, is the one calling your tool, and there’s no guarantee it will pass the error message back to the user.

Agents are designed to complete tasks. When something fails, they’ll often try a different approach. That’s why your error handling should help the agent decide what to do next, not just flag what went wrong. Instead of “You don’t have access to this system”, return something along the lines of “To have access to this system, the MCP server needs to be configured with a valid API_TOKEN, the current API_TOKEN is not valid”. 

What you’re doing here is informing the agent that access to the third-party system isn’t possible due to a misconfiguration, not because access is denied outright. The distinction matters: the lack of access is a result of the user not properly configuring the MCP server, not a hard permission issue.

3. Document for humans and agents! 

This brings us to an equally important point: documentation!

When writing for your MCP server, remember you’re serving two audiences: the end users and the AI agent. As we saw with error handling, it’s critical to understand the needs of both.

Your documentation should address each audience clearly. End users want to know why they should use your MCP server, what problems it solves and how it fits into their workflow. Agents, on the other hand, rely on well-written tool names and descriptions to decide whether your server is the right fit for a given task.

Keep in mind: the agent is the one actually using the MCP server, but it’s the end user who decides which tools the agent has access to. Your documentation needs to support both!

4. Don’t just test functionality, test user interactions

One of the best ways to validate your documentation is to test your own MCP server. By far, the easiest way of interacting with your server when developing is to use the MCP inspector (type npx @modelcontextprotocol/inspector in your terminal and off you go!).

While it’s common to test whether your MCP server works, the inspector also helps you think from the end user’s perspective. It gives you a clearer sense of how users will interact with your server and whether your documentation supports that experience.

There are three key steps to testing a server:

Connecting to the MCP Server: This step will help you validate that your server is capturing all the necessary configuration to run properly.

List Tools: This is what AI agents see when they initialize your MCP server.

Tool Calling: Make sure that the tool behaves the way that it’s expected. This is where you can validate the failure modes.

One important design consideration is to think about the MCP Server lifecycle: Ask: What is necessary for the MCP Client to connect to the MCP Server?  How should tools be listed and discovered? And what’s the process for invoking a specific tool?

For example, when you’re writing an MCP server for your database. In a typical API, you’d establish the database connection when the server starts. However, when writing an MCP server, you should aim to make each tool call as self-contained as possible. This means creating a connection for every tool call, not on server start. By doing this, you will allow users to connect and list tools even if the server is not configured correctly. 

While this might feel like an anti-pattern at first, it actually makes more sense in this context. You’re trading a bit of latency for improved usability and reliability. In reality, the only moment your MCP will need a connection to a database (or a third-party system) is when a tool is invoked. The MCP Inspector is a great way to see this in action and gain a better understanding of how both users and agents will interact with your server.

If you are using the Docker MCP Toolkit, there are several ways to test whether your MCP server is behaving as expected. 

Run the following command to call your tool using the configuration you defined in Docker Desktop.

`docker mcp tools call my-tool`

To test what the MCP clients see, you can run the following command:

`docker mcp gateway run –verbose –dry-run`

This command simulates the call from an MCP client to your MCP server, assuming it’s enabled in the Docker MCP Catalog.

5. Packaging your MCP servers with containers

Excellent, we have written and tested our MCP server, what’s next? Packaging!

Packaging an MCP server is not so much about creating the artifact but thinking about how the artifact is going to be used. We might be a bit biased here, but we truly believe that packaging your MCP server as a Docker Image is the way to go.

MCP servers come in many different flavours: Python, TypeScript, Java… Packaging as a Docker image makes your server truly portable and because of the nature of Docker images. You can ensure that the end user will be able to run your MCP server regardless of how their system is configured. Using Docker containers is the easiest way to avoid dealing with dependencies on other people’s machines. If they can run Docker, they can run your MCP server.

There are many resources available about how to create a good Dockerfile, but if you’re not sure if you have done the right thing, you can always use Gordon or `docker ai` command to improve it. Just type `docker ai improve my Dockerfile` and Gordon, the Docker AI agent, will help you with optimizing a Dockerfile for your MCP server.

How to submit your MCP server 

Once you have a Dockerfile in your repository, we invite you to submit your MCP server to the Docker Official Registry! At the time of this writing, all submitted MCP servers must use the stdio transport mechanism, so be sure your server supports this when running as a container. We look forward to your submission!

Conclusion

The new Docker MCP Catalog makes it easier than ever to discover and scale MCP servers securely. Whether you’re submitting a Docker-built server with full security treatment or maintaining your own as a community contributor, following these five best practices for MCP servers; Managing tool budget, designing for the Agent, writing for both users and LLMs, thoroughly testing, and packaging with containers will help you create MCP servers that are reliable, easy to use, and ready for real-world agentic workloads. 

Ready to share yours with the Docker community? Submit it to the Docker MCP Catalog and get it in front of millions of developers! 

Learn more

Check out our new MCP Catalog announcement blog

Find documentation for Docker MCP Catalog and Toolkit.

Subscribe to the Docker Navigator Newsletter.

New to Docker? Create an account. 

Have questions? The Docker community is here to help.

Quelle: https://blog.docker.com/feed/