Open Shippers in Limited Preview

For the past few months I’ve been working on Open Shippers (openshippers.io), a place for solo makers to build and ship projects in the open, publicly sharing their progress as they take their products from conception to launch and beyond. Makers will post daily standups, log decisions made, and provide general commentary about their projects in real-time while receiving support, feedback, and accountability from the community.

Open Shippers home page.

Yesterday I launched a limited preview of Open Shippers with a post on Indie Hackers:

Open Shippers post on Indie Hackers.

My goal for the next couple of weeks is to gain a handful of beta users on Open Shippers to provide feedback and validate (or invalidate) the idea.

The Story So Far

The Open Shippers story starts last summer…

I’d started getting up early in the morning to devote the first couple of hours before the workday starts to personal pursuits and side project work at the suggestion of a buddy and colleague of mine who was doing the same. Think of the financial aphorism “Pay yourself first,” except applied to time in a day.

Every weekday morning shortly after 5:00 AM I’d join him in a Slack channel. After the obligatory “good morning,” we’d each give our daily standup for our respective projects: what I did yesterday, what I plan to do today, and what’s getting in my way.

I found that this daily routine of sharing my standup with a like-minded individual yielded several benefits:

  • I felt accountable to someone else to ship. Every. Day.
  • I received valuable feedback on the features I was building.
  • I focused more on the things that mattered for MVP and less on those that didn’t.
  • I had a sounding board for things I was considering and decisions I was making.
  • My productivity increased.

Sometime around the beginning of November, it occurred to me that there might be value in a dedicated place for solo makers to post their daily standups and journal their project progress. There already exists a fantastic ecosystem of maker communities online, and, while I benefit from many of them, I hadn’t found a project-focused place to journal my day-to-day progress.

So I got to work.

From the point I first started working on Open Shippers I recorded my daily standups in a file (in addition to sharing them with my buddy on Slack). It was my intention to start using the application as soon as possible as I’m building it, eat my own dog food. Once the database was up I’d seed it with the prior standups from my file.

November turned into December, and my colleague got busy with work trips and other life priorities that prevented him from joining me in the mornings for a few weeks. I continued my routine of posting my daily standups, and I found that the practice was valuable despite his absence.

Fast-forward to today – I’ve finished the functionality needed to support more users than just myself. Open Shippers is in limited preview.

Next Steps

There are many features on the Open Shippers roadmap, which I’ll publish soon. I’ll continue to develop new features in the open, with daily standups and updates.

I’d welcome any feedback that my readers might have on the site, and, if you’re so inclined, I invite you to join me on Open Shippers in the limited preview to use and hopefully get value from posting your daily standups and interacting with other shippers.

Thanks for reading! What will you ship today?

-Jon


If you’d like to receive new posts via e-mail, consider joining the newsletter.

Setting Environment for EF Core Data Migrations

Most of my side project work is in ASP.NET Core lately, and my main side project uses EF Core for data access with data migrations. My application is deployed in Azure using Azure SQL as the database. When developing and running locally, I hit a LocalDB instance on my machine.

When I need to make changes to the data model, I make the code changes, run Add-Migration Update### and then Update-Database in package manager console, and my local database happily gets updated. But when I’m ready to make the changes to the SQL Azure database, how can I change the connection string that the EF database context is using?

The ASPNETCORE_ENVIRONMENT Variable

First let’s talk about how an ASP.NET Core application knows where it’s running.

ASP.NET Core uses an environment variable named ASPNETCORE_ENVIRONMENT to control how an application behaves in different environments. The framework supports three environment values out of the box: Development, Staging, and Production. When running locally, my app uses the environment variable set up for me by Visual Studio when I created the project on the Debug tab of my project’s properties:

The ASPNETCORE_ENVIRONMENT variable set on the Debug tab of Project Properties.
The ASPNETCORE_ENVIRONMENT variable in project properties.

On the Application settings tab for my App Service in Azure, this variable is defined and set to Production so the deployed instance of my application knows to use production settings and connection strings:

The ASPNETCORE_ENVIRONMENT variable set on the Application settings tab on the App Service in Azure.

The value of this environment variable can be accessed from within the Startup class by using a constructor that takes an instance of IHostingEnvironment:

public Startup(IConfiguration configuration, IHostingEnvironment environment)

You can then use convenience members, like environment.IsDevelopment or environment.IsProduction to switch based on the predefined environments, or access environment.EnvironmentName directly.

ASP.NET Core also supports the use of different appsettings.json files, depending on the value of the ASPNETCORE_ENVIRONMENT environment variable. For example, I have an appsettings.Development.json in my project with overrides for settings and connection strings specific to my development environment. When loading configuration options on startup, the framework knows to look for and use any settings defined in an appsettings.{EnvironmentName}.json file, where {EnvironmentName} matches the value of the ASPNETCORE_ENVIRONMENT environment variable.

Setting ASPNETCORE_ENVIRONMENT for Data Migrations

All of this is prelude to the point of this post. I’ve never really used package manager console for much more than, well, managing Nuget packages and running the occasional data migration commands. But as it turns out, the Package Manager Console window is a PowerShell shell that can do much more. For now, I just need it to help me target the correct database when running my data migrations.

I can see a list of my application’s DbContext types and where they’re pointing by issuing EF Core Tools command Get-DbContext in package manager console. Doing so yields the following output:

PM> Get-DbContext
Microsoft.EntityFrameworkCore.Infrastructure[10403]
      Entity Framework Core 2.2.1-servicing-10028 initialized 'ApplicationDbContext' using provider 'Microsoft.EntityFrameworkCore.SqlServer' with options: None

providerName                            databaseName  dataSource             options
------------                            ------------  ----------             -------
Microsoft.EntityFrameworkCore.SqlServer mydatabase    (localdb)\MSSQLLocalDB None   

I can then set the ASPNETCORE_ENVIRONMENT variable to Production for the context of the package manager window only by issuing the following command:

PM> $Env:ASPNETCORE_ENVIRONMENT = "Production"

All subsequent calls to Update-Database will be now run against the database configured for my Production environment. I can double-check to make sure, though, by issuing Get-DbContext again. This time it shows that I’m pointing to my deployed database:

PM> Get-DbContext

providerName                            databaseName dataSource                              options
------------                            ------------ ----------                              -------
Microsoft.EntityFrameworkCore.SqlServer mydatabase   tcp:acme.database.windows.net,1433      None

Thanks for reading!

–Jon


If you’d like to receive new posts via e-mail, consider joining the newsletter.