1

I have an MVC C# app that has a appsettings.json file that looks like this:

{
    "Logging": {
      "LogLevel": {
        "Default": "Warning"
      }
    },
    "AllowedHosts": "*",
    "ConnectionStrings": {
      "db": "Server=postgresql_MENTIONvlt_bg;Database=amaranth_vaultvid_tests;User Id=amaranth_vaultvid_test_user;Password=<PASSWORD HERE>"
    },
    "Kestrel": {
      "Endpoints": {
        "Http": {
          "Url":  "http://0.0.0.0:5000"
        },
        "Https": {
          "Url": "https://0.0.0.0:5001"
        }
      },
      "EndpointDefaults": {
        "Url": "https://0.0.0.0:5001",
        "Protocols": "Http1"
      }
    },
    "ApiEndpoints": {
      "TestNet": [
        "<LINK HERE>",
        "<LINK HERE>",
        "<API KEY HERE>"
      ],
      "MainNet": [
        "<LINK HERE>",
        "<LINK HERE>",
        "<API KEY HERE>"
      ]
    }
  }

I want to replace ApiEndpoints.MainNet[2] with a value that I pass in with docker. My docker-compose.yml file looks like this:

version: '3.8'

volumes:
  data:

services:
  postgresql_MENTIONvlt_bg:
    image: postgres
    # explicit container name
    container_name: postgresql_vlt_bg
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
    ports:
      - 5432:5432
    volumes:
      - data:/var/lib/postgresql_vlt_bg
  amaranth_main:
    container_name: amaranth_main
    links:
      - postgresql_MENTIONvlt_bg
    depends_on:
      - postgresql_MENTIONvlt_bg
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - 8000:5000
      - 8001:5001
    environment:
      - ASPNETCORE_ENVIRONMENT=Release
      - ASPNETCORE_Kestrel__Certificates__Default__Password=${Kestrel_Cert_Password}
      - ASPNETCORE_Kestrel__Certificates__Default__Path=${Kestrel_Cert_Rel_Path}
      - ApiEndpoints__MainNet=${<NEW API KEY HERE>}
    volumes:
      - ${Kestrel_Cert_Abs_Path}:/https:ro

All of the variables represented with ${...} are defined in an .env file.

When I try to print out ApiEndpoints.MainNet I get the old API key. How do I pass in the new API key?

This is the projects's Startup.cs file:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using amaranth.Data;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Identity.UI.Services;
using amaranth.Helpers;

namespace amaranth
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddHttpClient();

            services.Configure<ApiEndpoints>(Configuration.GetSection("ApiEndpoints"));

            services.Configure<CookiePolicyOptions>(options =>
            {
                // This lambda determines whether user consent for non-essential cookies is needed for a given request.
                options.CheckConsentNeeded = context => false;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });

            services.AddDbContext<ApplicationDbContext>(options =>
                options.UseNpgsql(Configuration.GetConnectionString("db")));

            services.AddDefaultIdentity<IdentityUser>(options => options.SignIn.RequireConfirmedAccount = true)
                .AddRoles<IdentityRole>()
                .AddEntityFrameworkStores<ApplicationDbContext>();

            services.AddAuthorization();

            services.AddControllersWithViews();
            services.AddRazorPages();

            services.AddSingleton<BitcoinHelper>();

            services.AddTransient<IEmailSender, EmailSender>();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            app.UseForwardedHeaders(new ForwardedHeadersOptions
            {
                ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
            });
            
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Home/Error");
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseCookiePolicy();
            app.UseStaticFiles();
            app.UseRouting();
            app.UseAuthentication();
            app.UseAuthorization();
            app.UseStatusCodePages();

            app.UseEndpoints(endpoints => {
                endpoints.MapControllers();
                endpoints.MapRazorPages();
                endpoints.MapDefaultControllerRoute();
            });
        }
    }
}

And this is the project's Program.cs file:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using amaranth.Data;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

namespace amaranth
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = CreateHostBuilder(args).Build();
            using (var scope = host.Services.CreateScope())
            {
                var db = scope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
                db.Database.Migrate();
            }
            host.Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.ConfigureKestrel(serverOptions =>
                    {
                        // Set properties and call methods on options
                    })
                    .UseStartup<Startup>();
                });
    }
}

And the Dockerfile referenced in docker-compose.yml:

FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build-env
WORKDIR /app

# Copy everything
COPY . ./
# Restore as distinct layers
RUN dotnet restore
RUN dotnet publish -c Release -o out

# Build runtime image
FROM mcr.microsoft.com/dotnet/aspnet:6.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "amaranth.dll"]

So again, just to reiterate, how do I pass in the new API key?

1
  • 1
    Have you isolated the problem to your ASP.NET Core code or Docker? Do environment variables set in the debug properties override the appSettings values? Commented Sep 27, 2022 at 5:21

1 Answer 1

3

Use ApiEndpoints__MainNet__2

Maybe this document can help you: Naming of environment variables

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.