An open API service indexing awesome lists of open source software.

https://github.com/joncloud/dotnet-compose

Sample dotnet core application running in Docker using Compose.
https://github.com/joncloud/dotnet-compose

Last synced: 7 months ago
JSON representation

Sample dotnet core application running in Docker using Compose.

Awesome Lists containing this project

README

          

# Quickstart: Docker Compose and .NET Core
This Quickstart guide will show you how to use Docker Compose to set up and run a .NET Core/PostgreSQL app. Before starting, you’ll need to have [Compose installed][].

[Compose installed]: https://docs.docker.com/compose/install/

## Define the project
Start by setting up the three files you’ll need to build the app. First, since your app is going to run inside a Docker container containing all of its dependencies, you’ll need to define exactly what needs to be included in the container. This is done using a file called `Dockerfile`. To begin with, the Dockerfile consists of:

```dockerfile
FROM microsoft/dotnet

RUN mkdir /myapp
WORKDIR /myapp

ADD . /myapp
```
That’ll put your application code inside an image that will build a container with .NET Core and all your dependencies inside it. For more information on how to write Dockerfiles, see the [Docker user guide][] and the [Dockerfile reference][].

[Docker user guide]: https://docs.docker.com/engine/tutorials/dockerimages/#building-an-image-from-a-dockerfile
[Dockerfile reference]: https://docs.docker.com/engine/reference/builder/

`docker-compose.yml` is where the magic happens. This file describes the services that comprise your app (a database and a web app), how to get each one’s Docker image (the database just runs on a pre-made PostgreSQL image, and the web app is built from the current directory), and the configuration needed to link them together and expose the web app’s port.

```yaml
version: '2'
services:
db:
image: postgres
web:
build: .
command: dotnet run
volumes:
- .:/myapp
ports:
- "5000:5000"
depends_on:
- db
environment:
ASPNETCORE_ENVIRONMENT: Development
ASPNETCORE_URLS: http://*:5000
```
## Build the project
With those three files in place, you can now generate the .NET Core skeleton app using `docker-compose run`:

```bash
$ docker-compose run web dotnet new -t Web
```

Update the Dockerfile to include `project.json`, because the `dotnet new` command does not have the ability to force generate. Including this step will cache any packages that have been restored.

```dockerfile
FROM microsoft/dotnet

RUN mkdir /myapp
WORKDIR /myapp

ADD project.json /myapp/project.json
ADD project.lock.json /myapp/project.lock.json
RUN dotnet restore

ADD . /myapp
```
First, Compose will build the image for the `web` service using the `Dockerfile`. Then it’ll run `dotnet new` inside a new container, using that image. Once it’s done, you should have generated a fresh app:

```bash
$ ls -l
total 56
total 88
drwxr-xr-x 5 user staff 170 Sep 9 13:07 Controllers
drwxr-xr-x 4 user staff 136 Sep 9 13:07 Data
-rw-r--r-- 1 user staff 68 Sep 9 13:06 Dockerfile
drwxr-xr-x 5 user staff 170 Sep 9 13:07 Models
-rwxr--r-- 1 user staff 550 Jun 21 20:31 Program.cs
-rwxr--r-- 1 user staff 2190 Jun 21 20:31 README.md
drwxr-xr-x 5 user staff 170 Sep 9 13:07 Services
-rwxr--r-- 1 user staff 3105 Jun 21 20:31 Startup.cs
drwxr-xr-x 8 user staff 272 Sep 9 13:07 Views
-rwxr--r-- 1 user staff 252 Jun 21 20:31 appsettings.json
-rwxr--r-- 1 user staff 204 Jun 21 20:31 bower.json
-rw-r--r-- 1 user staff 338 Sep 9 13:07 docker-compose.yml
-rwxr--r-- 1 user staff 1148 Jun 21 20:31 gulpfile.js
-rwxr--r-- 1 user staff 227 Jun 21 20:31 package.json
-rwxr--r-- 1 user staff 3211 Jun 21 20:31 project.json
-rwxr--r-- 1 user staff 549 Jun 21 20:31 web.config
drwxr-xr-x 6 user staff 204 Sep 9 13:07 wwwroot
```
If you are running Docker on Linux, the files `dotnet new` created are owned by root. This happens because the container runs as the root user. Change the ownership of the the new files.

```bash
sudo chown -R $USER:$USER .
```

If you are running Docker on Mac or Windows, you should already have ownership of all files, including those generated by `dotnet new`. List the files just to verify this.

In order to connect the application to PostgreSQL a couple more changes will be necessary.

Update `project.json` to include references to PostgreSQL's .NET Core packages:

```json
"dependencies": {
...
"Npgsql.EntityFrameworkCore.PostgreSQL": "1.0.1",
"Npgsql.EntityFrameworkCore.PostgreSQL.Design": "1.0.1"
...
}
```

Update `Startup.cs` to change the database connection to use PostgreSQL instead of SQLite:

```csharp
public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddDbContext(options =>
options.UseNpgsql(Configuration.GetConnectionString("DefaultConnection")));

...
}
```

Create `project.lock.json` as a simple json file:

```json
{}
```

Now that you’ve got a new `project.json`, you need to build the image again. (This, and changes to the Dockerfile itself, should be the only times you’ll need to rebuild.)

```bash
$ docker-compose build
```

To ensure that the lock file gets updated with restored packages run `dotnet restore`:

```bash
$ docker-compose run web dotnet restore
```

## Connect the database
The app is now bootable, but you’re not quite there yet. By default, .NET Core expects a database to be running on `localhost` - so you need to point it at the `db` container instead. You also need to change the database and username to align with the defaults set by the `postgres` image.

Create a new configuration file `appsettings.Development.json` with the following:

```json
{
"ConnectionStrings": {
"DefaultConnection": "User ID=postgres;Host=db;Database=postgres"
}
}
```

You can now boot the app with:

```bash
$ docker-compose up
```

If all’s well, you should see some PostgreSQL output, and then—after a few seconds—the familiar refrain:

```bash
web_1 | Project myapp (.NETCoreApp,Version=v1.0) will be compiled because expected outputs are missing
web_1 | Compiling myapp for .NETCoreApp,Version=v1.0
web_1 |
web_1 | Compilation succeeded.
web_1 | 0 Warning(s)
web_1 | 0 Error(s)
web_1 |
web_1 | Time elapsed 00:00:04.6780194
web_1 |
web_1 |
web_1 | info: Microsoft.Extensions.DependencyInjection.DataProtectionServices[0]
web_1 | User profile is available. Using '/root/.aspnet/DataProtection-Keys' as key repository; keys will not be encrypted at rest.
web_1 | Hosting environment: Development
web_1 | Content root path: /myapp
web_1 | Now listening on: http://*:5000
web_1 | Application started. Press Ctrl+C to shut down.
```

Finally, you need to create the database. In another terminal, run:

```bash
$ docker-compose run web dotnet ef database update
```

That’s it. Your app should now be running on port 5000 on your Docker daemon. If you’re using [Docker Machine][], then `docker-machine ip MACHINE_VM` returns the Docker host IP address.

[Docker Machine]: https://docs.docker.com/machine/overview/