mirror of
https://github.com/MAKS-IT-COM/maksit-certs-ui.git
synced 2025-12-31 04:00:03 +01:00
(feature): dependencies update, improved logging, allign naming to k8s deployment
This commit is contained in:
parent
399415c6b8
commit
d59ded5cde
@ -1,4 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace MaksIT.LetsEncrypt.Models.Responses;
|
namespace MaksIT.LetsEncrypt.Models.Responses;
|
||||||
public class AuthorizationChallengeChallenge
|
public class AuthorizationChallengeChallenge
|
||||||
@ -10,4 +11,13 @@ public class AuthorizationChallengeChallenge
|
|||||||
public string? Status { get; set; }
|
public string? Status { get; set; }
|
||||||
|
|
||||||
public string? Token { get; set; }
|
public string? Token { get; set; }
|
||||||
|
|
||||||
|
// New properties added to complete the model
|
||||||
|
public DateTime? Validated { get; set; }
|
||||||
|
|
||||||
|
public AuthorizationChallengeError? Error { get; set; }
|
||||||
|
|
||||||
|
public List<AuthorizationChallengeValidationRecord>? ValidationRecord { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MaksIT.LetsEncrypt.Models.Responses;
|
||||||
|
public class AuthorizationChallengeError {
|
||||||
|
public string Type { get; set; }
|
||||||
|
|
||||||
|
public string Detail { get; set; }
|
||||||
|
}
|
||||||
@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace MaksIT.LetsEncrypt.Models.Responses;
|
||||||
|
|
||||||
|
|
||||||
|
public class AuthorizationChallengeValidationRecord {
|
||||||
|
public Uri? Url { get; set; }
|
||||||
|
|
||||||
|
public string? Hostname { get; set; }
|
||||||
|
|
||||||
|
public string? Port { get; set; }
|
||||||
|
|
||||||
|
public List<string>? AddressesResolved { get; set; }
|
||||||
|
|
||||||
|
public string? AddressUsed { get; set; }
|
||||||
|
}
|
||||||
@ -391,7 +391,7 @@ public class LetsEncryptService : ILetsEncryptService {
|
|||||||
|
|
||||||
if (challenge?.Url == null) {
|
if (challenge?.Url == null) {
|
||||||
_logger.LogError("Challenge URL is null");
|
_logger.LogError("Challenge URL is null");
|
||||||
return Result.InternalServerError();
|
return Result.InternalServerError("Challenge URL is null");
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = new HttpRequestMessage(HttpMethod.Post, challenge.Url);
|
var request = new HttpRequestMessage(HttpMethod.Post, challenge.Url);
|
||||||
@ -712,6 +712,18 @@ public class LetsEncryptService : ILetsEncryptService {
|
|||||||
|
|
||||||
throw new LetsEncrytException(problem, response);
|
throw new LetsEncrytException(problem, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (response.Content.Headers.ContentType?.MediaType == GetContentType(ContentType.Json)) {
|
||||||
|
var authorizationChallengeChallenge = responseText.ToObject<AuthorizationChallengeChallenge>();
|
||||||
|
|
||||||
|
if (authorizationChallengeChallenge?.Status == "invalid") {
|
||||||
|
throw new LetsEncrytException(new Problem {
|
||||||
|
Type = authorizationChallengeChallenge.Error.Type,
|
||||||
|
Detail = authorizationChallengeChallenge.Error.Detail,
|
||||||
|
RawJson = responseText
|
||||||
|
}, response);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SendResult<TResult> ProcessResponseContent<TResult>(HttpResponseMessage response, string responseText) {
|
private SendResult<TResult> ProcessResponseContent<TResult>(HttpResponseMessage response, string responseText) {
|
||||||
@ -743,14 +755,14 @@ public class LetsEncryptService : ILetsEncryptService {
|
|||||||
private Result HandleUnhandledException(Exception ex, string defaultMessage = "Let's Encrypt client unhandled exception") {
|
private Result HandleUnhandledException(Exception ex, string defaultMessage = "Let's Encrypt client unhandled exception") {
|
||||||
List<string> messages = new() { defaultMessage };
|
List<string> messages = new() { defaultMessage };
|
||||||
_logger.LogError(ex, messages.FirstOrDefault());
|
_logger.LogError(ex, messages.FirstOrDefault());
|
||||||
messages.Add(ex.Message);
|
ex.ExtractMessages().ForEach(m => messages.Add(m));
|
||||||
return Result.InternalServerError([.. messages]);
|
return Result.InternalServerError([.. messages]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<T?> HandleUnhandledException<T>(Exception ex, T? defaultValue = default, string defaultMessage = "Let's Encrypt client unhandled exception") {
|
private Result<T?> HandleUnhandledException<T>(Exception ex, T? defaultValue = default, string defaultMessage = "Let's Encrypt client unhandled exception") {
|
||||||
List<string> messages = new() { defaultMessage };
|
List<string> messages = new() { defaultMessage };
|
||||||
_logger.LogError(ex, messages.FirstOrDefault());
|
_logger.LogError(ex, messages.FirstOrDefault());
|
||||||
messages.Add(ex.Message);
|
ex.ExtractMessages().ForEach(m => messages.Add(m));
|
||||||
return Result<T?>.InternalServerError(defaultValue, [.. messages]);
|
return Result<T?>.InternalServerError(defaultValue, [.. messages]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,32 +0,0 @@
|
|||||||
using System.Net;
|
|
||||||
|
|
||||||
namespace MaksIT.LetsEncryptServer.Middlewares {
|
|
||||||
public class GlobalExceptionMiddleware {
|
|
||||||
|
|
||||||
private readonly RequestDelegate _next;
|
|
||||||
private readonly ILogger<GlobalExceptionMiddleware> _logger;
|
|
||||||
|
|
||||||
public GlobalExceptionMiddleware(RequestDelegate next, ILogger<GlobalExceptionMiddleware> logger) {
|
|
||||||
_next = next;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async Task InvokeAsync(HttpContext context) {
|
|
||||||
try {
|
|
||||||
await _next(context);
|
|
||||||
}
|
|
||||||
catch (Exception ex) {
|
|
||||||
_logger.LogError(ex, "An unhandled exception occurred.");
|
|
||||||
await HandleExceptionAsync(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Task HandleExceptionAsync(HttpContext context) {
|
|
||||||
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
|
|
||||||
context.Response.ContentType = "application/json";
|
|
||||||
|
|
||||||
var response = new { message = "An error occurred while processing your request." };
|
|
||||||
return context.Response.WriteAsJsonAsync(response);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,9 +1,10 @@
|
|||||||
using MaksIT.LetsEncryptServer;
|
using MaksIT.Core.Webapi.Middlewares;
|
||||||
using MaksIT.LetsEncrypt.Services;
|
using MaksIT.Core.Logging;
|
||||||
using MaksIT.LetsEncryptServer.Services;
|
|
||||||
using MaksIT.LetsEncryptServer.BackgroundServices;
|
|
||||||
using MaksIT.LetsEncryptServer.Middlewares;
|
|
||||||
using MaksIT.LetsEncrypt.Extensions;
|
using MaksIT.LetsEncrypt.Extensions;
|
||||||
|
using MaksIT.LetsEncrypt.Services;
|
||||||
|
using MaksIT.LetsEncryptServer;
|
||||||
|
using MaksIT.LetsEncryptServer.BackgroundServices;
|
||||||
|
using MaksIT.LetsEncryptServer.Services;
|
||||||
|
|
||||||
var builder = WebApplication.CreateBuilder(args);
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
@ -24,6 +25,9 @@ if (File.Exists(secretsPath)) {
|
|||||||
var configurationSection = configuration.GetSection("Configuration");
|
var configurationSection = configuration.GetSection("Configuration");
|
||||||
var appSettings = configurationSection.Get<Configuration>() ?? throw new ArgumentNullException();
|
var appSettings = configurationSection.Get<Configuration>() ?? throw new ArgumentNullException();
|
||||||
|
|
||||||
|
// Add logging
|
||||||
|
builder.Logging.AddConsoleLogger();
|
||||||
|
|
||||||
// Allow configurations to be available through IOptions<Configuration>
|
// Allow configurations to be available through IOptions<Configuration>
|
||||||
builder.Services.Configure<Configuration>(configurationSection);
|
builder.Services.Configure<Configuration>(configurationSection);
|
||||||
|
|
||||||
@ -55,11 +59,8 @@ if (app.Environment.IsDevelopment()) {
|
|||||||
app.UseSwaggerUI();
|
app.UseSwaggerUI();
|
||||||
app.UseCors(builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
|
app.UseCors(builder => builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
// app.UseMiddleware<GlobalExceptionMiddleware>();
|
|
||||||
}
|
|
||||||
|
|
||||||
app.UseMiddleware<GlobalExceptionMiddleware>();
|
app.UseMiddleware<ErrorHandlingMiddleware>();
|
||||||
|
|
||||||
app.UseAuthorization();
|
app.UseAuthorization();
|
||||||
|
|
||||||
|
|||||||
@ -81,9 +81,11 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
#region Internal methods
|
#region Internal methods
|
||||||
public async Task<Result<Guid?>> ConfigureClientAsync(bool isStaging) {
|
public async Task<Result<Guid?>> ConfigureClientAsync(bool isStaging) {
|
||||||
var sessionId = Guid.NewGuid();
|
var sessionId = Guid.NewGuid();
|
||||||
|
|
||||||
var result = await _letsEncryptService.ConfigureClient(sessionId, isStaging);
|
var result = await _letsEncryptService.ConfigureClient(sessionId, isStaging);
|
||||||
if (!result.IsSuccess)
|
if (!result.IsSuccess)
|
||||||
return result.ToResultOfType<Guid?>(default);
|
return result.ToResultOfType<Guid?>(default);
|
||||||
|
|
||||||
return Result<Guid?>.Ok(sessionId);
|
return Result<Guid?>.Ok(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -91,17 +93,22 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
RegistrationCache? cache = null;
|
RegistrationCache? cache = null;
|
||||||
if (accountId == null) {
|
if (accountId == null) {
|
||||||
accountId = Guid.NewGuid();
|
accountId = Guid.NewGuid();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
var cacheResult = await _cacheService.LoadAccountFromCacheAsync(accountId.Value);
|
var cacheResult = await _cacheService.LoadAccountFromCacheAsync(accountId.Value);
|
||||||
|
|
||||||
if (!cacheResult.IsSuccess || cacheResult.Value == null) {
|
if (!cacheResult.IsSuccess || cacheResult.Value == null) {
|
||||||
accountId = Guid.NewGuid();
|
accountId = Guid.NewGuid();
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
cache = cacheResult.Value;
|
cache = cacheResult.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
var result = await _letsEncryptService.Init(sessionId, accountId.Value, description, contacts, cache);
|
var result = await _letsEncryptService.Init(sessionId, accountId.Value, description, contacts, cache);
|
||||||
if (!result.IsSuccess)
|
if (!result.IsSuccess)
|
||||||
return result.ToResultOfType<Guid?>(default);
|
return result.ToResultOfType<Guid?>(default);
|
||||||
|
|
||||||
return Result<Guid?>.Ok(accountId.Value);
|
return Result<Guid?>.Ok(accountId.Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -109,12 +116,15 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
var orderResult = await _letsEncryptService.NewOrder(sessionId, hostnames, challengeType);
|
var orderResult = await _letsEncryptService.NewOrder(sessionId, hostnames, challengeType);
|
||||||
if (!orderResult.IsSuccess || orderResult.Value == null)
|
if (!orderResult.IsSuccess || orderResult.Value == null)
|
||||||
return orderResult.ToResultOfType<List<string>?>(_ => null);
|
return orderResult.ToResultOfType<List<string>?>(_ => null);
|
||||||
|
|
||||||
var challenges = new List<string>();
|
var challenges = new List<string>();
|
||||||
|
|
||||||
foreach (var kvp in orderResult.Value) {
|
foreach (var kvp in orderResult.Value) {
|
||||||
string[] splitToken = kvp.Value.Split('.');
|
string[] splitToken = kvp.Value.Split('.');
|
||||||
File.WriteAllText(Path.Combine(_acmePath, splitToken[0]), kvp.Value);
|
File.WriteAllText(Path.Combine(_acmePath, splitToken[0]), kvp.Value);
|
||||||
challenges.Add(splitToken[0]);
|
challenges.Add(splitToken[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result<List<string>?>.Ok(challenges);
|
return Result<List<string>?>.Ok(challenges);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -125,12 +135,15 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
return result;
|
return result;
|
||||||
Thread.Sleep(1000);
|
Thread.Sleep(1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
var cacheResult = _letsEncryptService.GetRegistrationCache(sessionId);
|
var cacheResult = _letsEncryptService.GetRegistrationCache(sessionId);
|
||||||
if (!cacheResult.IsSuccess || cacheResult.Value == null)
|
if (!cacheResult.IsSuccess || cacheResult.Value == null)
|
||||||
return cacheResult;
|
return cacheResult;
|
||||||
|
|
||||||
var saveResult = await _cacheService.SaveToCacheAsync(cacheResult.Value.AccountId, cacheResult.Value);
|
var saveResult = await _cacheService.SaveToCacheAsync(cacheResult.Value.AccountId, cacheResult.Value);
|
||||||
if (!saveResult.IsSuccess)
|
if (!saveResult.IsSuccess)
|
||||||
return saveResult;
|
return saveResult;
|
||||||
|
|
||||||
return Result.Ok();
|
return Result.Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,20 +155,25 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
var cacheResult = _letsEncryptService.GetRegistrationCache(sessionId);
|
var cacheResult = _letsEncryptService.GetRegistrationCache(sessionId);
|
||||||
if (!cacheResult.IsSuccess || cacheResult.Value?.CachedCerts == null)
|
if (!cacheResult.IsSuccess || cacheResult.Value?.CachedCerts == null)
|
||||||
return cacheResult.ToResultOfType<Dictionary<string, string>?>(_ => null);
|
return cacheResult.ToResultOfType<Dictionary<string, string>?>(_ => null);
|
||||||
|
|
||||||
var results = new Dictionary<string, string>();
|
var results = new Dictionary<string, string>();
|
||||||
foreach (var hostname in hostnames) {
|
foreach (var hostname in hostnames) {
|
||||||
CertificateCache? cert;
|
CertificateCache? cert;
|
||||||
|
|
||||||
if (cacheResult.Value.TryGetCachedCertificate(hostname, out cert)) {
|
if (cacheResult.Value.TryGetCachedCertificate(hostname, out cert)) {
|
||||||
var content = $"{cert.Cert}\n{cert.PrivatePem}";
|
var content = $"{cert.Cert}\n{cert.PrivatePem}";
|
||||||
results.Add(hostname, content);
|
results.Add(hostname, content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var uploadResult = await _agentService.UploadCerts(results);
|
var uploadResult = await _agentService.UploadCerts(results);
|
||||||
if (!uploadResult.IsSuccess)
|
if (!uploadResult.IsSuccess)
|
||||||
return uploadResult.ToResultOfType<Dictionary<string, string>?>(default);
|
return uploadResult.ToResultOfType<Dictionary<string, string>?>(default);
|
||||||
|
|
||||||
var reloadResult = await _agentService.ReloadService(_appSettings.Agent.ServiceToReload);
|
var reloadResult = await _agentService.ReloadService(_appSettings.Agent.ServiceToReload);
|
||||||
if (!reloadResult.IsSuccess)
|
if (!reloadResult.IsSuccess)
|
||||||
return reloadResult.ToResultOfType<Dictionary<string, string>?>(default);
|
return reloadResult.ToResultOfType<Dictionary<string, string>?>(default);
|
||||||
|
|
||||||
return Result<Dictionary<string, string>?>.Ok(results);
|
return Result<Dictionary<string, string>?>.Ok(results);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,12 +183,15 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
if (!result.IsSuccess)
|
if (!result.IsSuccess)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
var cacheResult = _letsEncryptService.GetRegistrationCache(sessionId);
|
var cacheResult = _letsEncryptService.GetRegistrationCache(sessionId);
|
||||||
if (!cacheResult.IsSuccess || cacheResult.Value == null)
|
if (!cacheResult.IsSuccess || cacheResult.Value == null)
|
||||||
return cacheResult;
|
return cacheResult;
|
||||||
|
|
||||||
var saveResult = await _cacheService.SaveToCacheAsync(cacheResult.Value.AccountId, cacheResult.Value);
|
var saveResult = await _cacheService.SaveToCacheAsync(cacheResult.Value.AccountId, cacheResult.Value);
|
||||||
if (!saveResult.IsSuccess)
|
if (!saveResult.IsSuccess)
|
||||||
return saveResult;
|
return saveResult;
|
||||||
|
|
||||||
return Result.Ok();
|
return Result.Ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,6 +215,7 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
if (!challengeResult.IsSuccess)
|
if (!challengeResult.IsSuccess)
|
||||||
return challengeResult.ToResultOfType<Guid?>(default);
|
return challengeResult.ToResultOfType<Guid?>(default);
|
||||||
}
|
}
|
||||||
|
|
||||||
var getOrderResult = await GetOrderAsync(sessionId, hostnames);
|
var getOrderResult = await GetOrderAsync(sessionId, hostnames);
|
||||||
if (!getOrderResult.IsSuccess)
|
if (!getOrderResult.IsSuccess)
|
||||||
return getOrderResult.ToResultOfType<Guid?>(default);
|
return getOrderResult.ToResultOfType<Guid?>(default);
|
||||||
@ -222,9 +244,11 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
var initResult = await InitAsync(sessionId, accountId, description, contacts);
|
var initResult = await InitAsync(sessionId, accountId, description, contacts);
|
||||||
if (!initResult.IsSuccess)
|
if (!initResult.IsSuccess)
|
||||||
return initResult;
|
return initResult;
|
||||||
|
|
||||||
var revokeResult = await RevokeCertificatesAsync(sessionId, hostnames);
|
var revokeResult = await RevokeCertificatesAsync(sessionId, hostnames);
|
||||||
if (!revokeResult.IsSuccess)
|
if (!revokeResult.IsSuccess)
|
||||||
return revokeResult;
|
return revokeResult;
|
||||||
|
|
||||||
return Result.Ok();
|
return Result.Ok();
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
@ -255,9 +279,11 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
#region Acme Challenge REST methods
|
#region Acme Challenge REST methods
|
||||||
public Result<string?> AcmeChallenge(string fileName) {
|
public Result<string?> AcmeChallenge(string fileName) {
|
||||||
DeleteExporedChallenges();
|
DeleteExporedChallenges();
|
||||||
|
|
||||||
var challengePath = Path.Combine(_acmePath, fileName);
|
var challengePath = Path.Combine(_acmePath, fileName);
|
||||||
if(!File.Exists(challengePath))
|
if (!File.Exists(challengePath))
|
||||||
return Result<string?>.NotFound(null);
|
return Result<string?>.NotFound(null);
|
||||||
|
|
||||||
var fileContent = File.ReadAllText(Path.Combine(_acmePath, fileName));
|
var fileContent = File.ReadAllText(Path.Combine(_acmePath, fileName));
|
||||||
return Result<string?>.Ok(fileContent);
|
return Result<string?>.Ok(fileContent);
|
||||||
}
|
}
|
||||||
@ -268,6 +294,7 @@ public class CertsFlowService : ICertsFlowService {
|
|||||||
try {
|
try {
|
||||||
var creationTime = File.GetCreationTime(file);
|
var creationTime = File.GetCreationTime(file);
|
||||||
var timeDifference = currentDate - creationTime;
|
var timeDifference = currentDate - creationTime;
|
||||||
|
|
||||||
if (timeDifference.TotalDays > 1) {
|
if (timeDifference.TotalDays > 1) {
|
||||||
File.Delete(file);
|
File.Delete(file);
|
||||||
_logger.LogInformation($"Deleted file: {file}");
|
_logger.LogInformation($"Deleted file: {file}");
|
||||||
|
|||||||
@ -4,21 +4,21 @@ services:
|
|||||||
ports:
|
ports:
|
||||||
- "8080:8080"
|
- "8080:8080"
|
||||||
depends_on:
|
depends_on:
|
||||||
- letsencrypt-app
|
- certs-ui-client
|
||||||
- letsencrypt-server
|
- certs-ui-server
|
||||||
networks:
|
networks:
|
||||||
- maks-it
|
- maks-it
|
||||||
|
|
||||||
letsencrypt-app:
|
certs-ui-client:
|
||||||
container_name: letsencrypt-app
|
container_name: certs-ui-client
|
||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
- LETSENCRYPT_SERVER=http://localhost:8080
|
- LETSENCRYPT_SERVER=http://localhost:8080
|
||||||
networks:
|
networks:
|
||||||
- maks-it
|
- maks-it
|
||||||
|
|
||||||
letsencrypt-server:
|
certs-ui-server:
|
||||||
container_name: letsencrypt-server
|
container_name: certs-ui-server
|
||||||
environment:
|
environment:
|
||||||
- ASPNETCORE_ENVIRONMENT=Development
|
- ASPNETCORE_ENVIRONMENT=Development
|
||||||
- ASPNETCORE_HTTP_PORTS=5000
|
- ASPNETCORE_HTTP_PORTS=5000
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
services:
|
services:
|
||||||
letsencrypt-app:
|
|
||||||
image: ${DOCKER_REGISTRY-}letsencrypt-app
|
|
||||||
build:
|
|
||||||
context: .
|
|
||||||
dockerfile: ClientApp/Dockerfile
|
|
||||||
|
|
||||||
reverse-proxy:
|
reverse-proxy:
|
||||||
image: ${DOCKER_REGISTRY-}reverse-proxy
|
image: ${DOCKER_REGISTRY-}reverse-proxy
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: ReverseProxy/Dockerfile
|
dockerfile: ReverseProxy/Dockerfile
|
||||||
|
|
||||||
letsencrypt-server:
|
certs-ui-client:
|
||||||
image: ${DOCKER_REGISTRY-}letsencrypt-server
|
image: ${DOCKER_REGISTRY-}certs-ui-client
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: ClientApp/Dockerfile
|
||||||
|
|
||||||
|
certs-ui-server:
|
||||||
|
image: ${DOCKER_REGISTRY-}certs-ui-server
|
||||||
build:
|
build:
|
||||||
context: .
|
context: .
|
||||||
dockerfile: LetsEncryptServer/Dockerfile
|
dockerfile: LetsEncryptServer/Dockerfile
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user