---
title: 'I Replaced Docker Compose With Aspire (Here''s Why)'
source: 'https://youtube.com/watch?v=eszmPLzxjc0'
video_id: 'eszmPLzxjc0'
date: 2026-08-08
duration_sec: 796
---

# I Replaced Docker Compose With Aspire (Here's Why)

> Source: [I Replaced Docker Compose With Aspire (Here's Why)](https://youtube.com/watch?v=eszmPLzxjc0)

## Summary

This video demonstrates how to migrate an existing .NET application from Docker Compose to .NET Aspire for local orchestration, then generate a Docker Compose file for deployment. The presenter walks through adding Aspire support, configuring PostgreSQL and Seq dependencies, and using the Aspire dashboard for observability.

### Key Points

- **Adding Aspire Orchestrator Support** [01:13] — In Visual Studio 2026, right-click the project and select 'Add .NET Aspire Orchestrator Support' to create App Host and Service Defaults projects.
- **Service Defaults Configuration** [07:13] — The Service Defaults project configures OpenTelemetry, health checks, service discovery, and HTTP client defaults.
- **Adding PostgreSQL Database** [05:08] — Use `builder.AddPostgres("name")` and `postgres.AddDatabase("dbname")` to add a PostgreSQL database with a persistent volume.
- **Service Dependencies** [05:37] — Use `WithReference` and `WaitFor` to ensure the web API waits for the database and Seq to be ready.
- **Generating Docker Compose** [10:34] — Install the Aspire.Hosting.Docker (preview) package and run `aspire publish` to generate a Docker Compose file.

## Transcript

been happening there and particularly when it comes to deploying your Aspire app using Docker Compose. I'm going to show you how I take an existing application that's using Docker Compose for orchestration, rewriting it to use
Aspire, and then using the support in Aspire to generate a Docker Compose file. So, we're basically going full circle, but I think it's going to be an interesting example. So, what I have here is a .NET 10 application that's
implementing architecture. The is just a to-do app, so it's nothing too grab the source code, it's going to be available from the pinned comment right and maybe even go through the video together with me. I'm orchestrating this
using Docker Compose, so the web API is run as a Docker container. There's a Docker file here controlling how this image gets built. We're also using Postgres as our database and Seq for structured logging and possibly also
tracing when we introduce Aspire. Currently, this project doesn't have open telemetry. So, how can we move from using Docker Compose for orchestration to using Aspire? Well, in Visual Studio 2026, when you right-click your project,
there's an option here that shows up called add .NET Aspire orchestrator support. Now, what annoys me is that the option for adding orchestration using containers, basically Docker Compose, sometimes shows up and sometimes it
showing up because I have Docker Compose already, but I did run into situations Nonetheless, let's introduce our .NET Aspire orchestrator. So, let's call it to-do list. I have the latest version of the Aspire templates installed, which
we're going to use version 13.1. Now, regardless, we have to do some tinkering with the two Aspire projects that get created. One is the app host, which controls how our application starts and what services it runs. Right now,
there's one service, the web API, and there's also this extensions project concerns such as open telemetry, health checks, service discovery, and it comes with some sane default values that you can introduce into your projects.
Another thing that happens is your web API, or the project that you started to reference to the service defaults project, and it also gets two additional lines of code in the program file adding the service defaults, which configures
and service discovery, but also introduces the default endpoints, which are related to exposing the health checks. We'll go over exactly what's introduced in a moment, but I want to take your attention to the fact that
within this solution, I'm using central package management, and the scaffolded service defaults project doesn't respect this. So, this is something that I unfortunately will have to fix manually. So, let me add a comment here, and I'm
going to add an explanation here that these are going to be the Aspire packages. Now, because this is central package management, we aren't allowed to have package references. Instead, we use package versions. So, now that I have
this fixed, I can go back to the service defaults project and just get rid of the package versions. Now, from what I can see here, and I might be mistaken, but we're going to double-check, the versions aren't the latest versions of
these packages, so that's not a problem to update. So, you just right-click your project, you say manage NuGet packages, and you go to the updates tab, and here you get a list of any packages you can update. I want to update all of them, so
this completes, we can consider our initial setup done. So, let me close this down. I'm going to also close this down. The app host doesn't have any NuGet packages. It does this through an SDK reference, and it pulls in
everything it needs to function. So, let's take a look first at the app host. What's going on here? We are creating a distributed application, and it's very similar to what we are doing in our web application. So, here we have our web
application builder, and in the app host, we have a distributed application builder. Now, I have some code analysis warnings that I have to fix, but once those are done, we can run this, and it will spin up our web API. However, what
is missing is support for running our database and our Seq instance for structured logs and traces. So, I'm going to add an Aspire package by right-clicking the project, and you go add, and you say .NET Aspire package.
Aspire hosting packages, and what I want to install is first of all Postgres, so once this completes, I'm going to look for Seq, and I'm going to install Aspire
hosting Seq. Now, what's interesting about these packages is that they also come with some useful examples in the package readme, which you can use for a quick getting started guide. So, we've got our two hosting packages installed.
Let me close down everything, and let's start with adding our Postgres instance. So, we'll say builder add Postgres, and we give our resource a name, and then you can configure some other options. For example, we want a data volume. We
lifetime, and I recommend using container lifetime persistent because Postgres instance every time you restart Aspire. Now, other than the database resource, we also want to add an actual database inside. So, let me call this
DB, and I want to say Postgres add database. Let's call it to-do list. And now, how we're going to use this is we add a reference to our resource from our web API. So, I'm going to say with reference and wait for, and I'll specify
two things. First, it's going to make sure that the database is up and available before starting my .NET application. And secondly, it's going to database, so I can connect to it directly from my .NET code. We can do
the same for Seq. So, we're going to say builder add Seq. Let's give it a name. And in our web API, we're going to say with reference and pass in the Seq resource. And then we're going to say wait for and also pass in Seq. So, this
takes care of the hosting side, but we also need to take care of our client side. Now, when it comes to the database, this part is quite simple. All string. So, instead of using the connection string called database, I'll
use the connection string called to-do list, which matches the name of my resource as defined in the Aspire app host. I'll show you what this looks like also from the Aspire dashboard when we start this project. Now, another thing
is how do we integrate Seq? Well, in the app host, we were using hosting packages, but there are also client-side packages that you can use. And if I look for Seq, I'm going to find the Aspire Seq package that also has a useful
readme for how to integrate this. And with the NuGet package installed, I'm going to say builder add Seq endpoint, and we have to give it the name of our resource. This also again looks for the respective connection string that is
populated by Aspire. So, now we have the equivalent setup with a database and our Seq resource. They are connected to our application the same as they were with the Docker Compose file. And now, let's take a look at this service defaults
what this does is it configures open telemetry, health checks, service discovery, some HTTP client defaults. Within open telemetry, it's setting up logging, traces, metrics, and traces. And then the health check stuff isn't
too interesting. Now, what I do want to do here is add a bit more support for tracing with our Postgres instance. So, I'll say Npgsql open telemetry, and I'm looking for the Npgsql open telemetry
package. Let me install the latest version. And what this allows me to do is say add Npgsql when we are configuring the distributed traces, and this will take care of setting up tracing support for our database. So,
finally, I'm going to start my application, and notice that now the app host is the startup application. What's going to happen now is we'll get an like this, where you can see your services slowly starting up. So, you can
see our Postgres resources up. The respective database, which is nested within our Postgres resource, is also up. Our Seq instance is here, and our web API. A couple more things you can do is check out the graph to see how your
services are connected. You can also confirm that your web API resource has here is the Seq connection string, and then here is our database connection string, and all of this is managed by Aspire for you. You can take a look at
the console logs for your services, the structured logs, if there are any, currently not. Then you can also see your traces and metrics. Now, if we go back to the resources and I jump into the Swagger UI for my API instance, we
can test this out by sending a request. So, let's start by registering a user. I'll say test@test.com, so just creating a dummy user and some password. And if I execute this, we are able to get back a successful response.
Let me try to authenticate using this user's credentials. So, I'll drop in the email and password, and you can see we get back an access token, and we can also use this access token to authenticate with the API. So, this
should have generated at least some logs and traces. So, let's go back to the Aspire dashboard, and if you take a look at the structured logs, they are empty. The traces do exist, and we can see our two requests to create a user and to
authenticate, and they both involve a database query, but I also want to see if they are present in the Seq instance. So, I'll go to the Seq UI, and here you can see our structured logs as well as our traces. So, if I go into a specific
trace, I can find the logs for that trace, which contain the structured information. The database logs also contain the respective SQL query. So, you can see a select exists query here, and then an insert statement in the
second example here, which creates our user. And with this, you've already got a pretty decent setup with an API, a database, and OpenTelemetry integrated with Seq. Now, at the beginning of the video, I mentioned that we were going to
go full circle, so migrating from Docker Compose to Aspire, but then being able to generate a Docker Compose file. And how we can do this is with an Aspire hosting integration. So, look for an Aspire package, and I'm going to look
for Docker. I may have to get rid of these tags, but with Aspire Docker, I do to find it. And you will have to tick on include pre-release because this is currently still in preview. Nonetheless, let's install the latest version. And
what this allows you to do is to use the Aspire publisher that uses Docker Compose. So, how you integrate this is you say builder at Docker Compose environment, you give it a name, then you can jump into the console at the
root of your Aspire project, which I'm going to do now, and you type in the command Aspire publish, and you specify your output folder. Let's call this the Docker Compose artifacts. And this is in fact how it's represented in the readme
of this NuGet package. So, if I go ahead and run this now, it's going to look for an Aspire app host project within my folder, and once it finds it, it's going to build it. And based on the contents of my Aspire app host, it's going to
publish the respective Docker Compose file. Now, you can see that this was entire process and what's happening here. And now, if we go into our Docker Compose artifacts folder, which I'm going to open in VS Code, and we can see
two files inside. The main one being our Docker Compose YAML file that contains our Aspire dashboard instance running, and we have our Postgres service configured to use the respective image, and it also pulls a password from the
configures a volume and a network. Then respective image, setting some environment variables, exposing the default ports, and again connecting to our network. And finally, we have our
web API service, the image that we should be using, a bunch of environment variables configuring OpenTelemetry, connection strings like you can see here and here, and then some other values for connecting to your database instance or
Seq. Finally, it's going to also connect this to the same network. And when I navigate to this folder and run Docker Compose up, assuming my image is built locally, Docker Compose will be able to spin up our entire application. In the
environment file, you can specify a couple of variables like the password, the web API image, and the default port from which this should run. So, you can see how we went full circle from a Docker Compose file back to one, except
now we are using Aspire for orchestrating our application locally, and we can deploy it as a Docker Compose application by uploading our Compose file to a VPS and running Docker Compose up. Of course, we'll have to make sure
that the respective image is present in some container registry, but we can said at the beginning of the video, feel free to grab the source code for this be right below. If you want to learn more about how you could go about
deploying this Docker Compose setup to a VPS, take a look at this video next where I walk you through my self-hosting setup. If you like this video, consider smashing the like button right below. Thanks a lot for watching, and until
Thanks a lot for watching, and until next time, stay awesome.
