Skip to main content

Using Postgres on Docker with EF7 and ASP.NET 5

In an effort to get a better understanding of the ASP.NET framework, I've started a simple toy project from scratch.  I've really been enjoying how easy it is to plug everything together with Microsoft's reboot of the framework.  Just spin up a project.json file and get going, it's pretty impressive how much you can get done with so few files.
I think the community has been doing a great job with blog posts, so I've not had many opportunities to contribute any unique content that isn't already covered.

While working through things today however, I thought it might be nice to try and prove out how Entity Framework 7 can work with non-Microsoft databases and containers.  The most appealing at the time of writing being postgres thanks to the awesome work by the people over at npgsql.
Because I've been developing in Windows using Visual Studio, the first thing that would be nice is to not have to spoil my system with a database installation.  No surprise, docker seems like it would make a great ally for that!

So, for this blog post, I'd like to take you through setting up a docker container running postgres and then adding support to your ASP.NET 5 project to run migrations against it.

Docker & Database Setup

It's easy to get started with Docker Toolbox, just download and run the installer.  One snag I encountered was that I had Hyper-V enabled on my machine.  This resulted in the docker quickstart terminal giving me some errors about virtualization not being enabled on my machine.
Under the hood, docker toolbox uses VirtualBox which cannot run with Hyper-V.  It's not much at the moment, but I have taken the time to ask that they make docker machine's Hyper-V support a little more user friendly.  I encourage you to head over there and give it a +1 if you agree.

With toolbox downloaded, create a file called local-development.yml at the root of your project.  Take a copy of this code which defines a container configuration based on the official postgres docker image.

If you're running on OSX or Windows and are like me, you'll probably also want the server to behave as though it was on localhost.  You can run this to forward all traffic destined for 5432 on your machine to the docker vm:

docker-machine stop default
VBoxManage modifyvm "default" --natpf1 "app,tcp,,5432,,5432"
docker-machine start default

(Note: VBoxManage may not be on your path in Windows, but it is in the program's installation folder in Program Files.)

Finally, you can try starting the database server by simply typing the following in a docker-enabled terminal at the root of your project:

docker-compose -f local-development.yml up

After which point, you should be able to use any postgres client to connect to the database.  I suggest DataGrip - formerly 0xdbe - made by the folks over at JetBrains.

Project Setup

So far, you've got a database, but now what steps need to be taken to get ASP.NET talking to the containerized database?

Really, things couldn't be any simpler.  First off, you'll want to open up project.json and ensure you have the lines from this gist present.

Make sure you get a package restore done automatically via your tooling or manually by running dnu restore.

Next, you're going to want to make sure you've enabled EF7 in your project's Startup.cs file.  Here's a copy of the method and what you have to call to get that done.  Mix in what I have with what you've got as needed.

The last step, which I've left to this point deliberately is to add the configuration for postgres to your DbContext.
This file is usually going to be heavily tailored to your project.  So I'm going to try and avoid anything to do with your schema.  The file I've shared with you is just barebones enough to have identity and a crude configuration string.  Once you've mixed in my example code with your working DbContext, you should have everything you need to try generating a migration and running it.

Migrating

When I started learning about frameworks, running my first migrations was an oddly rewarding experience.  For me, it completed the circle of understanding and represented the moment that I felt I was able to apply what I had learned to create real solutions.

My hope with this blog post is that you'll feel the same about ASP.NET today as I do.  These next steps are easy.  All you need is a terminal with dnx working at the root of your project:

dnx ef migrations add Initial
dnx ef database update

Which, in my case, got me a new file in my project, as well as this:


And that's it!  You now have access to all the functionality of EF7 and ASP.NET 5.

Keep in mind that while ASP.NET 5 is now RC, there's always some remote chance that something could change.  The one thing I can easily predict now is that any use of dnx will be changing to dotnet.
Beyond that though, this should be a fairly safe blog post.  Most of it concentrates on getting you going with a postgres container.

Final Thoughts

There are a few more things when it comes to containerization that I'd like to get working, mainly adding an entry in local-development.yml for my ASP.NET app.  Although simulating a live environment locally is something that can easily swallow days of effort.  It's usually enough to say that ASP.NET takes care of a lot of environment abstraction for you.
Over time, I feel like if I need to containerize the app itself, I'll just make that a deployment detail and not concern my development workflow with it.
We'll see though, as using containers for actual development can sometimes be quite useful when onboarding new team members.

Hopefully I haven't accidentally left anything out, but if you have any issues getting to a point where you've got your migration generated, let me know in a comment!

Comments

Popular posts from this blog

Laravel Project Architecture: The Missing Guide

At my job, we've been doing a lot of learning and development using Taylor Otwell 's Laravel 4 PHP framework.  As we've become more familiar with it, we've had to come up with better ways to structure our projects outside of what the documentation indicates and the default distribution that is provided. If you've been working with Laravel 4 for any amount of time or come with experience from another framework and are just getting started, you've probably noticed that there are a lot of different ways to cut up your projects. Choice is nice, but sometimes it can be paralysing or misleading. Concrete Advice This post is done in such a way that you can just skim the headings, but if you want a detailed explanation in each section, feel free to read in where necessary. While I can't say the entirety of my advice is in practice throughout the community, I can say that we are starting to use it, and to very good effect at my job.  Especially consider...

Building .NET Core Nuget Packages

My last blog post was on building and publishing npm packages, specifically for typescript projects. In my opinion, packages are an important fundamental unit in software development. They sit at the confluence of technical competence and collaboration, and represent something the software community should be proud of. Most of the time, you're going to be creating software packages once you're comfortable with some essential pillars: Coding Project structure Software architecture Building Delivery Community Licensing After I got my npm package up and running, my next task was to do the same thing with my C# libraries. Similar to protoculture, I have made a library called praxis .  This is done by leveraging the services and tooling known in the .NET ecosystem as nuget. In this case, praxis abstracts many of the concepts and functionality I require when producing server projects. It builds on top of ASP.NET Core, so in that sense you can almost think of it as ...

Laravel is Good, Facades Aren't

I've been working on some Laravel 4 based packages lately which inevitably results in me also looking at other packages. I've noticed sometimes that people use facades at times that give me pause. The most troubling being from inside their model classes. A quick google turned up this video which assures people "there's still an instance behind everything, we're fine" .  Everything mentioned in the video is true except that there is a very glaring omission. Scope What usually goes out the door at the start of a long series of mishaps in software design is scope . When the desire to obtain a solution is stronger than the desire to consider the implications of a firm approach, mistakes are sure to follow.  Sacrifices like this are made due to the assumption of a high cost to developing carefully. What really is happening however is a false dilemma , being responded to with a convenience decision . It's very easy to write model code like ...