Errors pushing an image to a new ECR repo on AWS

Hey everyone,

I normally use DigitalOcean or Azure for docker and kubernetes but have decided to give AWS a go this time around. I was following a guide on deploying an image to a new ECR repo and hit a couple of issues.

The first was that running the login command output help options instead of the password I was expecting:

aws ecr get-login --no-include-email --region us-east-2

usage: aws [options] <command> <subcommand> [<subcommand> ...] [parameters]
To see help text, you can run:

  aws help
  aws <command> help
  aws <command> <subcommand> help

aws: error: argument operation: Invalid choice, valid choices are:

batch-check-layer-availability           | batch-delete-image                      
batch-get-image                          | batch-get-repository-scanning-configuration
complete-layer-upload                    | create-pull-through-cache-rule          
create-repository                        | delete-lifecycle-policy                 
delete-pull-through-cache-rule           | delete-registry-policy                  
delete-repository                        | delete-repository-policy                
describe-image-replication-status        | describe-image-scan-findings            
describe-images                          | describe-pull-through-cache-rules       
...

This turned out to be an issue because the command had been deprecated. Instead, use the following:

aws ecr get-login-password | docker login --username AWS --password-stdin "$(aws sts get-caller-identity --query Account --output text).dkr.ecr.<REGION_ID>.amazonaws.com"

There’s a pretty detailed thread on github here: https://github.com/aws/aws-cli/issues/5014

The second issue I ran into was an error while trying to run the new command:

An error occurred (AccessDeniedException) when calling the GetAuthorizationToken operation: User: arn:aws:iam::<ACCOUNT_ID>:user/<USER> is not authorized to perform: ecr:GetAuthorizationToken on resource: * because no identity-based policy allows the ecr:GetAuthorizationToken action

Adding the following role to my user resolved the issue: AmazonEC2ContainerRegistryPowerUser

Once I was passed this, I hit another issue using the command from the github link above:

Error response from daemon: login attempt to https://<ACCOUNT_ID>.dkr.ecr.us-east-2.amazonaws.com/v2/ failed with status: 400 Bad Request

This took a bit of digging, but eventually I came across a thread where someone was using the same command and had hit the same issue. Adding the region to the get-login-password call seemed to fix it:

aws ecr get-login-password --region <REGION_ID> | docker login --username AWS --password-stdin "$(aws sts get-caller-identity --query Account --output text).dkr.ecr.<REGION_ID>.amazonaws.com"

I was finally getting a login succeeded message and my push was working. This was the thread mentioning the region id just in case you need a bit more info: https://github.com/aws/aws-cli/issues/5317#issuecomment-835645395

Container Registry Template for Azure Bicep

Hi everyone,

Just another Bicep template I’m using – this one is for a basic container registry:

param namePrefix string
param location string = resourceGroup().location
param tier string = 'Basic'

var registryName = '${namePrefix}${uniqueString(resourceGroup().id)}'

resource container_registry 'Microsoft.ContainerRegistry/registries@2020-11-01-preview' = {
  name: registryName
  location: location
  sku: {
    name: tier
  }
  properties: {
    adminUserEnabled: false
    policies: {
      quarantinePolicy: {
        status: 'disabled'
      }
      trustPolicy: {
        type: 'Notary'
        status: 'disabled'
      }
      retentionPolicy: {
        days: 7
        status: 'disabled'
      }
    }
    encryption: {
      status: 'disabled'
    }
    dataEndpointEnabled: false
    publicNetworkAccess: 'Enabled'
    networkRuleBypassOptions: 'AzureServices'
    zoneRedundancy: 'Disabled'
    anonymousPullEnabled: false
  }
}

output id string = container_registry.id

See the following definition if you need more info on some of the properties: https://docs.microsoft.com/en-us/azure/templates/microsoft.containerregistry/2019-12-01-preview/registries?tabs=json

Docker Volumes Mounting File as Folder on Windows

Hey everyone,

I ran into a small issue today using docker-compose. I had a config file I was trying to mount as a volume however running “docker-compose up” generated a folder instead.

ERROR: for grafana Cannot start service grafana: OCI runtime create failed: container_linux.go:349: starting container process caused “process_linux.go:449: container init caused \”rootfs_linux.go:58: mounting \\\”/host_mnt/e/repos/Sample-Twitch/grafana/datasources.yml\\\” to rootfs \\\”/var/lib/docker/overlay2/f5c9553407551b68dc5d5877d748ba2bf7d2f0dd2ad12c73e39be40af185c82d/merged\\\” at \\\”/var/lib/docker/overlay2/f5c9553407551b68dc5d5877d748ba2bf7d2f0dd2ad12c73e39be40af185c82d/merged/etc/grafana/provisioning/datasources/prometheus.yaml\\\” caused \\\”not a directory\\\”\””: unknown: Are you trying to mount a directory onto a file (or vice-versa)? Check if the specified host path exists and is the expected type ERROR: Encountered errors while bringing up the project.

The issue turned out to be an oversight on my part, I’d misspelled the config filename and docker was unable to find it. Consequently, it generated the missing file as a directory.

It took a bit of Googling to narrow this down, but eventually this stackoverflow post pointed me in the right direction: https://stackoverflow.com/a/44950494/522859

Thanks,
Chris

Failed to load the development https certificate using docker and ocelot

Hey everyone,

I randomly started encountering the following error while using docker to host my Ocelot gateway:

Failed to load the development https certificate at ‘/root/.aspnet/https/ContentGateway.pfx’.

The solution ended up being to clean out as many temp files as possible, especially the generated certs:

  • Delete the following files: Delete the C:\Users{USER}\AppData\Roaming\ASP.NET\Https folder
  • Clean the solution. Delete the bin and obj folders (I just did this for the gateway project)
  • Restart visual studio/visual code

I’ll add an update if I can narrow down what caused the initial issue but for now this seems to work.

Thanks to the following links for the info:
https://docs.microsoft.com/en-au/aspnet/core/security/enforcing-ssl?view=aspnetcore-3.1&tabs=visual-studio#trust-the-aspnet-core-https-development-certificate-on-windows-and-macos
https://stackoverflow.com/q/52457514/522859

Unable to find the target operating system for the project

Hi everyone,

I ran into the following error today after updating visual studio 2019 to version 16.6:

unable to find the target operating system for the project

I tried a fair few things to get this going again and I’m assuming they’re not all necessary, but I’ll list them just in case:
– Clean solution
– Close visual studio
– Delete .vs folder
– Ensure that docker-compose is set as startup project
– Edit each project’s .csproj file and ensure that the DockerDefaultTargetOS value is set: Linux
– Edit docker-compose.dcproj and ensure that DocketTargetOS is set
– Restart computer

If you’re able to narrow it down at all I’d be interested in hearing what the actual cause is!

Cheers,
Chris

Docker – Severity Code Description Project File Line Suppression State Error DT1001 Service service has neither an image nor a build context specified. At least one must be provided. docker-compose C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Sdks\Microsoft.Docker.Sdk\build\Microsoft.VisualStudio.Docker.Compose.targets 204

Hi everyone,

I ran into the following error while using docker compose and visual studio:

Severity Code Description Project File Line Suppression State
Error DT1001 Service has neither an image nor a build context specified. At least one must be provided. docker-compose C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Sdks\Microsoft.Docker.Sdk\build\Microsoft.VisualStudio.Docker.Compose.targets 204

It took a bit of poking around to find as the error seemed a bit ambiguous, but luckily this turned out to be a simple mistake on my part. I’d renamed my service from “servicename” to “service_name” in docker-compose.yml. Unfortunately, I hadn’t noticed the visual studio had automatically added an entry to docker-compose.override.yml. Because I hadn’t updated this entry it couldn’t find an image for the non-existent service.

A simple error on my part, but hopefully it’s able to save you a bit of time!

Cheers,
Chris

Http gRPC with .NET Core and Docker – Error starting gRPC call. System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.IO.IOException: The response ended prematurely.

Hi everyone,

I’ve been mucking around with gRPC today while using .NET Core and Docker. I have two Microservices in the setup, one server and one client. Because these services will only be communicating internally I intended to use HTTP instead of HTTPS. Unfortunately, I hit the following error while attempting to set this up:

Error starting gRPC call. System.Net.Http.HttpRequestException: An error occurred while sending the request. —> System.IO.IOException: The response ended prematurely.

According Microsoft’s eshoponcontainers documentation there are a few extra steps for getting this to work:

Using gRPC without TLS
gRPC works with HTTP/2 only. Usually when a client connects to a server, the connection is done using HTTP1.1 and promoted to HTTP/2 only if both, server and client, support HTTP/2. This promotion is performed using a protocol negotiation, usually implemented using ALPN protocol which requires TLS.

In order to get it to work you need to add the following to your server :

.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup()

.ConfigureKestrel(options =>
{
options.Listen(IPAddress.Any, 5001, listenOptions =>
{
listenOptions.Protocols = HttpProtocols.Http2;
});
});
});

You then need to explicitly allow HTTP/2 without TLS when creating the client:

AppContext.SetSwitch(“System.Net.Http.SocketsHttpHandler.Http2UnencryptedSupport”, true);
AppContext.SetSwitch(“System.Net.Http.SocketsHttpHandler.Http2Support”, true);

// The port number(5001) must match the port of the gRPC server.
var channel = GrpcChannel.ForAddress(endpoint, new GrpcChannelOptions { LoggerFactory = loggerFactory });
var client = new CatalogService.Catalog.CatalogClient(channel);

Note that the AppContext.SetSwitch statements need to appear before the client is created to work. There’s also a bit of an overview on the following page: https://github.com/dotnet-architecture/eShopOnContainers/wiki/gRPC

The following stackoverflow post also helped with the ordering issue: https://stackoverflow.com/a/58053460/522859

Current .NET SDK does not support targeting .NET Core 3.0 – Microservices

Hi everyone,

I’m currently learning microservices with .Net Core. As part of this I’ve been following one of Microsoft’s tutorials: https://dotnet.microsoft.com/learn/aspnet/microservice-tutorial

It has all been pretty straight forward, however I hit an error when attempting to run docker build:

RUN dotnet restore
—> Running in 734e82e92c23
/usr/share/dotnet/sdk/2.2.207/Sdks/Microsoft.NET.Sdk/targets/Microsoft.NET.TargetFrameworkInference.targets(137,5): error NETSDK1045: The current .NET SDK does not support targeting .NET Core 3.0. Either target .NET Core 2.2 or lower, or use a version of the .NET SDK that supports .NET Core 3.0. [/src/myMicroservice.csproj]
The command ‘/bin/sh -c dotnet restore’ returned a non-zero code: 1

Updating the Dockerfile references seems to have resolved the issue. I replaced each occurrence of 2.2 with 3.0 and re-ran the following command:

docker build -t microservice .

My complete docker file was as follows:

# https://dotnet.microsoft.com/learn/aspnet/microservice-tutorial/docker-file
FROM mcr.microsoft.com/dotnet/core/sdk:3.0 AS build
WORKDIR /src
COPY myMicroservice.csproj .
RUN dotnet restore
COPY . .
RUN dotnet publish -c release -o /app

FROM mcr.microsoft.com/dotnet/core/aspnet:3.0
WORKDIR /app
COPY –from=build /app .
ENTRYPOINT [“dotnet”, “myMicroservice.dll”]

Full source available here: https://github.com/Buzzology/myMicroservice