feat: support restart caddy docker container
This commit is contained in:
@@ -6,6 +6,7 @@
|
|||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
|
||||||
<LangVersion>13</LangVersion>
|
<LangVersion>13</LangVersion>
|
||||||
|
<ContainerRepository>ebolo/caddy-manager</ContainerRepository>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -22,7 +23,14 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Repositories\" />
|
<AdditionalFiles Include="Components\Pages\Caddy\CaddyfileEditor\CaddyfileEditor.razor" />
|
||||||
|
<AdditionalFiles Include="Components\Pages\Caddy\ReverseProxies\ReverseProxiesPage.razor" />
|
||||||
|
<AdditionalFiles Include="Components\Pages\Caddy\ReverseProxies\ReverseProxyItem.razor" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<_ContentIncludedByDefault Remove="Components\Pages\ReverseProxies\ReverseProxiesPage.razor" />
|
||||||
|
<_ContentIncludedByDefault Remove="Components\Pages\ReverseProxies\ReverseProxyItem.razor" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@_drawer.ToggleDrawer" />
|
<MudIconButton Icon="@Icons.Material.Filled.Menu" Color="Color.Inherit" Edge="Edge.Start" OnClick="@_drawer.ToggleDrawer" />
|
||||||
<MudText Typo="Typo.h6">Caddy Manager</MudText>
|
<MudText Typo="Typo.h6">Caddy Manager</MudText>
|
||||||
<MudSpacer />
|
<MudSpacer />
|
||||||
<MudIconButton Icon="@Icons.Custom.Brands.GitHub" Color="Color.Inherit" Href="https://github.com/MudBlazor/MudBlazor" Target="_blank" />
|
<MudIconButton Icon="@Icons.Custom.Brands.GitHub" Color="Color.Inherit" Href="https://pikachu-gitea.duydao.org/ebolo/CaddyManager" Target="_blank" />
|
||||||
</MudAppBar>
|
</MudAppBar>
|
||||||
<NavigationDrawer @ref="_drawer"/>
|
<NavigationDrawer @ref="_drawer"/>
|
||||||
<MudMainContent Class="pt-16 px-16">
|
<MudMainContent Class="pt-16 px-16">
|
||||||
|
|||||||
@@ -8,7 +8,5 @@
|
|||||||
</MudNavLink>
|
</MudNavLink>
|
||||||
<MudNavLink Match="NavLinkMatch.All" Href="/caddyfile" Icon="@Icons.Material.Filled.Language">Global Caddyfile
|
<MudNavLink Match="NavLinkMatch.All" Href="/caddyfile" Icon="@Icons.Material.Filled.Language">Global Caddyfile
|
||||||
</MudNavLink>
|
</MudNavLink>
|
||||||
<MudNavLink Match="NavLinkMatch.All" Href="/settings" Icon="@Icons.Material.Filled.Settings">Settings
|
|
||||||
</MudNavLink>
|
|
||||||
</MudNavMenu>
|
</MudNavMenu>
|
||||||
</MudDrawer>
|
</MudDrawer>
|
||||||
@@ -4,7 +4,7 @@ using CaddyManager.Models.Caddy;
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using MudBlazor;
|
using MudBlazor;
|
||||||
|
|
||||||
namespace CaddyManager.Components.Pages.CaddyfileEditor;
|
namespace CaddyManager.Components.Pages.Caddy.CaddyfileEditor;
|
||||||
|
|
||||||
public partial class CaddyfileEditor : ComponentBase
|
public partial class CaddyfileEditor : ComponentBase
|
||||||
{
|
{
|
||||||
@@ -3,7 +3,7 @@ using CaddyManager.Contracts.Caddy;
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using MudBlazor;
|
using MudBlazor;
|
||||||
|
|
||||||
namespace CaddyManager.Components.Pages;
|
namespace CaddyManager.Components.Pages.Caddy;
|
||||||
|
|
||||||
public partial class CaddyfilePage : ComponentBase
|
public partial class CaddyfilePage : ComponentBase
|
||||||
{
|
{
|
||||||
@@ -28,6 +28,7 @@ public partial class CaddyfilePage : ComponentBase
|
|||||||
AutomaticLayout = true,
|
AutomaticLayout = true,
|
||||||
Language = "plaintext",
|
Language = "plaintext",
|
||||||
Value = _caddyConfigurationContent,
|
Value = _caddyConfigurationContent,
|
||||||
|
Theme = "vs-dark",
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +48,6 @@ public partial class CaddyfilePage : ComponentBase
|
|||||||
|
|
||||||
private void Cancel()
|
private void Cancel()
|
||||||
{
|
{
|
||||||
// CaddyService.GetCaddyGlobalConfigurationContent();
|
_codeEditor.SetValue(_caddyConfigurationContent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
<PageTitle>Reverse proxy configurations</PageTitle>
|
<PageTitle>Reverse proxy configurations</PageTitle>
|
||||||
|
|
||||||
<MudContainer Class="d-flex flex-row flex-grow-1 gap-4">
|
<MudContainer Class="d-flex flex-row flex-grow-1 gap-4 align-center">
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Add"
|
<MudButton Variant="Variant.Filled" Color="Color.Primary" StartIcon="@Icons.Material.Filled.Add"
|
||||||
OnClick="NewReverseProxy">New...
|
OnClick="NewReverseProxy">New...
|
||||||
</MudButton>
|
</MudButton>
|
||||||
@@ -11,6 +11,13 @@
|
|||||||
Disabled="@(_selectedCaddyConfigurations.Count <= 0)"
|
Disabled="@(_selectedCaddyConfigurations.Count <= 0)"
|
||||||
OnClick="Delete">Delete
|
OnClick="Delete">Delete
|
||||||
</MudButton>
|
</MudButton>
|
||||||
|
<MudButton Variant="Variant.Filled" Color="Color.Default" StartIcon="@Icons.Material.Filled.Refresh"
|
||||||
|
OnClick="RestartCaddy">Restart Caddy
|
||||||
|
</MudButton>
|
||||||
|
@if (_isProcessing)
|
||||||
|
{
|
||||||
|
<MudProgressCircular Color="Color.Primary" Indeterminate="true" Size="Size.Small"/>
|
||||||
|
}
|
||||||
</MudContainer>
|
</MudContainer>
|
||||||
<MudList T="string" Style="padding-top: 16px;" SelectionMode="SelectionMode.MultiSelection"
|
<MudList T="string" Style="padding-top: 16px;" SelectionMode="SelectionMode.MultiSelection"
|
||||||
@bind-SelectedValues="_selectedCaddyConfigurations">
|
@bind-SelectedValues="_selectedCaddyConfigurations">
|
||||||
@@ -1,17 +1,22 @@
|
|||||||
using CaddyManager.Contracts.Caddy;
|
using CaddyManager.Contracts.Caddy;
|
||||||
|
using CaddyManager.Contracts.Docker;
|
||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using MudBlazor;
|
using MudBlazor;
|
||||||
|
|
||||||
namespace CaddyManager.Components.Pages.ReverseProxies;
|
namespace CaddyManager.Components.Pages.Caddy.ReverseProxies;
|
||||||
|
|
||||||
public partial class ReverseProxiesPage : ComponentBase
|
public partial class ReverseProxiesPage : ComponentBase
|
||||||
{
|
{
|
||||||
|
private bool _isProcessing;
|
||||||
private List<string> _availableCaddyConfigurations = [];
|
private List<string> _availableCaddyConfigurations = [];
|
||||||
private IReadOnlyCollection<string> _selectedCaddyConfigurations = [];
|
private IReadOnlyCollection<string> _selectedCaddyConfigurations = [];
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
private ICaddyService CaddyService { get; set; } = null!;
|
private ICaddyService CaddyService { get; set; } = null!;
|
||||||
|
|
||||||
|
[Inject]
|
||||||
|
private IDockerService DockerService { get; set; } = null!;
|
||||||
|
|
||||||
[Inject]
|
[Inject]
|
||||||
private IDialogService DialogService { get; set; } = null!;
|
private IDialogService DialogService { get; set; } = null!;
|
||||||
|
|
||||||
@@ -59,6 +64,9 @@ public partial class ReverseProxiesPage : ComponentBase
|
|||||||
StateHasChanged();
|
StateHasChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Have the selected configurations be deleted
|
||||||
|
/// </summary>
|
||||||
private void Delete()
|
private void Delete()
|
||||||
{
|
{
|
||||||
var response = CaddyService.DeleteCaddyConfigurations(_selectedCaddyConfigurations.ToList());
|
var response = CaddyService.DeleteCaddyConfigurations(_selectedCaddyConfigurations.ToList());
|
||||||
@@ -75,4 +83,26 @@ public partial class ReverseProxiesPage : ComponentBase
|
|||||||
Snackbar.Add(response.Message, Severity.Error);
|
Snackbar.Add(response.Message, Severity.Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Restart the Caddy container
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private async Task RestartCaddy()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_isProcessing = true;
|
||||||
|
StateHasChanged();
|
||||||
|
Snackbar.Add("Restarting Caddy container", Severity.Info);
|
||||||
|
await DockerService.RestartCaddyContainerAsync();
|
||||||
|
Snackbar.Add("Caddy container restarted successfully", Severity.Success);
|
||||||
|
_isProcessing = false;
|
||||||
|
StateHasChanged();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
Snackbar.Add("Failed to restart the Caddy container", Severity.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -2,7 +2,7 @@ using CaddyManager.Contracts.Caddy;
|
|||||||
using Microsoft.AspNetCore.Components;
|
using Microsoft.AspNetCore.Components;
|
||||||
using MudBlazor;
|
using MudBlazor;
|
||||||
|
|
||||||
namespace CaddyManager.Components.Pages.ReverseProxies;
|
namespace CaddyManager.Components.Pages.Caddy.ReverseProxies;
|
||||||
|
|
||||||
public partial class ReverseProxyItem : ComponentBase
|
public partial class ReverseProxyItem : ComponentBase
|
||||||
{
|
{
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
@page "/settings"
|
|
||||||
@using CaddyManager.Contracts.Caddy
|
|
||||||
@inject ICaddyService CaddyService
|
|
||||||
|
|
||||||
<PageTitle>Counter</PageTitle>
|
|
||||||
|
|
||||||
<h1>Counter</h1>
|
|
||||||
|
|
||||||
<p role="status">Current count: @currentCount</p>
|
|
||||||
|
|
||||||
<MudButton Variant="Variant.Filled" Color="Color.Primary" @onclick="IncrementCount">Click me</MudButton>
|
|
||||||
|
|
||||||
@code {
|
|
||||||
private int currentCount = 0;
|
|
||||||
|
|
||||||
private void IncrementCount()
|
|
||||||
{
|
|
||||||
Console.WriteLine(string.Join('\n', CaddyService.GetExistingCaddyConfigurations()));
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
namespace CaddyManager.Configurations.Docker;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configuration for the Docker service
|
||||||
|
/// </summary>
|
||||||
|
public class DockerServiceConfiguration
|
||||||
|
{
|
||||||
|
public const string Docker = "Docker";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Name of the Caddy container to be controlled (i.e restart)
|
||||||
|
/// </summary>
|
||||||
|
public string CaddyContainerName { get; set; } = "caddy";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Uri to the Docker host
|
||||||
|
/// </summary>
|
||||||
|
public string DockerHost { get; set; } = "unix:///var/run/docker.sock";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the Docker host with environment check. If the environment variable DOCKER_HOST is set, it will return
|
||||||
|
/// that value, otherwise it will return the value of DockerHost
|
||||||
|
/// </summary>
|
||||||
|
public string DockerHostWithEnvCheck => Environment.GetEnvironmentVariable("DOCKER_HOST") ?? DockerHost;
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using CaddyManager.Configurations.Caddy;
|
using CaddyManager.Configurations.Caddy;
|
||||||
|
using CaddyManager.Configurations.Docker;
|
||||||
|
|
||||||
namespace CaddyManager.Contracts.Configurations;
|
namespace CaddyManager.Contracts.Configurations;
|
||||||
|
|
||||||
@@ -11,4 +12,9 @@ public interface IConfigurationsService
|
|||||||
/// Configurations for Caddy service
|
/// Configurations for Caddy service
|
||||||
/// </summary>
|
/// </summary>
|
||||||
CaddyServiceConfigurations CaddyServiceConfigurations { get; }
|
CaddyServiceConfigurations CaddyServiceConfigurations { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Configurations for Docker service
|
||||||
|
/// </summary>
|
||||||
|
DockerServiceConfiguration DockerServiceConfiguration { get; }
|
||||||
}
|
}
|
||||||
13
CaddyManager/Contracts/Docker/IDockerService.cs
Normal file
13
CaddyManager/Contracts/Docker/IDockerService.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
namespace CaddyManager.Contracts.Docker;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Contract for the service to interact with Docker
|
||||||
|
/// </summary>
|
||||||
|
public interface IDockerService
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Method to help restart the Caddy container
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
Task RestartCaddyContainerAsync();
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ builder.Services
|
|||||||
|
|
||||||
// Auto register all the Services, Repositories that we have had within the code base
|
// Auto register all the Services, Repositories that we have had within the code base
|
||||||
builder.Services.RegisterAssemblyPublicNonGenericClasses()
|
builder.Services.RegisterAssemblyPublicNonGenericClasses()
|
||||||
.Where(t => t.Name.EndsWith("Service") || t.Name.EndsWith("Repository"))
|
.Where(t => t.Name.EndsWith("Service"))
|
||||||
.AsPublicImplementedInterfaces();
|
.AsPublicImplementedInterfaces();
|
||||||
|
|
||||||
builder.Services.AddSignalR(e => { e.MaximumReceiveMessageSize = 102400000; });
|
builder.Services.AddSignalR(e => { e.MaximumReceiveMessageSize = 102400000; });
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using CaddyManager.Contracts.Caddy;
|
|||||||
using CaddyManager.Contracts.Configurations;
|
using CaddyManager.Contracts.Configurations;
|
||||||
using CaddyManager.Models.Caddy;
|
using CaddyManager.Models.Caddy;
|
||||||
|
|
||||||
namespace CaddyManager.Services;
|
namespace CaddyManager.Services.Caddy;
|
||||||
|
|
||||||
/// <inheritdoc />
|
/// <inheritdoc />
|
||||||
public class CaddyService(IConfigurationsService configurationsService) : ICaddyService
|
public class CaddyService(IConfigurationsService configurationsService) : ICaddyService
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
using CaddyManager.Configurations.Caddy;
|
using CaddyManager.Configurations.Caddy;
|
||||||
|
using CaddyManager.Configurations.Docker;
|
||||||
using CaddyManager.Contracts.Configurations;
|
using CaddyManager.Contracts.Configurations;
|
||||||
using NetCore.AutoRegisterDi;
|
using NetCore.AutoRegisterDi;
|
||||||
|
|
||||||
@@ -12,4 +13,8 @@ public class ConfigurationsService(IConfiguration configuration) : IConfiguratio
|
|||||||
public CaddyServiceConfigurations CaddyServiceConfigurations =>
|
public CaddyServiceConfigurations CaddyServiceConfigurations =>
|
||||||
configuration.GetSection(CaddyServiceConfigurations.Caddy).Get<CaddyServiceConfigurations>() ??
|
configuration.GetSection(CaddyServiceConfigurations.Caddy).Get<CaddyServiceConfigurations>() ??
|
||||||
new CaddyServiceConfigurations();
|
new CaddyServiceConfigurations();
|
||||||
|
|
||||||
|
public DockerServiceConfiguration DockerServiceConfiguration =>
|
||||||
|
configuration.GetSection(DockerServiceConfiguration.Docker).Get<DockerServiceConfiguration>() ??
|
||||||
|
new DockerServiceConfiguration();
|
||||||
}
|
}
|
||||||
48
CaddyManager/Services/Docker/DockerService.cs
Normal file
48
CaddyManager/Services/Docker/DockerService.cs
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
using CaddyManager.Configurations.Docker;
|
||||||
|
using CaddyManager.Contracts.Configurations;
|
||||||
|
using CaddyManager.Contracts.Docker;
|
||||||
|
using Docker.DotNet;
|
||||||
|
using Docker.DotNet.Models;
|
||||||
|
|
||||||
|
namespace CaddyManager.Services.Docker;
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public class DockerService(IConfigurationsService configurationsService) : IDockerService
|
||||||
|
{
|
||||||
|
private DockerServiceConfiguration Configuration => configurationsService.DockerServiceConfiguration;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Method to get the container id of the Caddy container by the name configured
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private async Task<string> GetCaddyContainerId()
|
||||||
|
{
|
||||||
|
var client = new DockerClientConfiguration(new Uri(Configuration.DockerHostWithEnvCheck)).CreateClient();
|
||||||
|
|
||||||
|
if (client == null) return string.Empty;
|
||||||
|
|
||||||
|
var containers = await client.Containers.ListContainersAsync(new ContainersListParameters
|
||||||
|
{
|
||||||
|
All = true
|
||||||
|
});
|
||||||
|
|
||||||
|
return containers.FirstOrDefault(container => container.Names.Contains($"/{Configuration.CaddyContainerName}"))
|
||||||
|
?.ID ?? string.Empty;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc />
|
||||||
|
public async Task RestartCaddyContainerAsync()
|
||||||
|
{
|
||||||
|
var containerId = await GetCaddyContainerId();
|
||||||
|
|
||||||
|
if (string.IsNullOrEmpty(containerId)) return;
|
||||||
|
|
||||||
|
var client = new DockerClientConfiguration(new Uri(Configuration.DockerHostWithEnvCheck)).CreateClient();
|
||||||
|
|
||||||
|
if (client != null)
|
||||||
|
{
|
||||||
|
await client.Containers.RestartContainerAsync(containerId, new ContainerRestartParameters());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -8,5 +8,9 @@
|
|||||||
"AllowedHosts": "*",
|
"AllowedHosts": "*",
|
||||||
"Caddy": {
|
"Caddy": {
|
||||||
"ConfigDir": "/root/compose/caddy/config"
|
"ConfigDir": "/root/compose/caddy/config"
|
||||||
|
},
|
||||||
|
"Docker": {
|
||||||
|
"CaddyContainerName": "caddy",
|
||||||
|
"DockerHost": "unix:///var/run/docker.sock"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,4 +11,5 @@
|
|||||||
.caddy-file-editor .monaco-editor {
|
.caddy-file-editor .monaco-editor {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
border-radius: inherit;
|
border-radius: inherit;
|
||||||
|
padding: 8px;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user