Hello,
I’m already deployed a .NET Core 3.1 console app only used by Hangfire in Windows Services with success.
Now, I’m trying with Docker but it is not working as I expected.
Below the code which is okay in a simple console app run with Win10.
static internal class Program
{
#region Constants
private const string AppSettingsName = "appsettings";
#endregion Constants
#region Static methods
public static async Task Main(string[] args)
{
IConfigurationRoot config = new ConfigurationBuilder().AddCommandLine(args).Build();
try
{
Console.WriteLine("Test1");
IHostBuilder hostBuilder = new HostBuilder()
.ConfigureHostConfiguration(configHost =>
{
configHost.SetBasePath(Directory.GetCurrentDirectory())
.AddEnvironmentVariables()
.AddCommandLine(args)
.AddConfiguration(config);
})
.ConfigureAppConfiguration((hostContext, configApp) =>
{
configApp.SetBasePath(Directory.GetCurrentDirectory())
.AddJsonFile($"{AppSettingsName}.json", optional: false)
.AddJsonFile($"{AppSettingsName}.{hostContext.HostingEnvironment.EnvironmentName}.json", optional: false);
})
.ConfigureServices((hostContext, services) =>
{
services.AddDbContext<IStorage, ClientAreaContext>(options => options.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)
.UseNpgsql(hostContext.Configuration.GetConnectionString("DefaultConnection")), ServiceLifetime.Transient);
services
.AddLocalization(hostContext.Configuration)
.AddJobSettings(hostContext.Configuration)
.AddJobs()
.AddHostedService<HangfireLaunchService>();
})
.ConfigureLogging((hostContext, logging) =>
{
logging.ClearProviders();
logging.AddConfiguration(hostContext.Configuration.GetSection("Logging"));
Console.WriteLine("Test2");
await hostBuilder.Build().RunAsync();
}
catch (Exception e)
{
using (var loggerFactory = new LoggerFactory())
{
ILogger logger = loggerFactory.CreateLogger("HangfireStart");
logger.LogError(e, "OH");
}
}
}
internal class HangfireLaunchService : IHostedService
{
#region Instance variables
private readonly IServiceProvider _serviceProvider;
private readonly HangfireSettings _settings;
private readonly ILogger _logger;
private BackgroundJobServer _hangfireServer;
#endregion Instance variables
#region Constructors
public HangfireLaunchService(
IOptions<HangfireSettings> hangfireSettings,
IServiceProvider serviceProvider,
ILogger<HangfireLaunchService> logger)
{
_settings = hangfireSettings.Value;
_serviceProvider = serviceProvider;
_logger = logger;
}
#endregion Constructors
#region Methods
/// <summary>
/// <see cref="IHostedService.StartAsync(CancellationToken)"/>
/// </summary>
public Task StartAsync(CancellationToken cancellationToken)
{
BackgroundJobServerOptions backgroundJobServerOptions = new BackgroundJobServerOptions
{
Activator = new HangfireActivator(_serviceProvider),
ServerName = "Batchs",
WorkerCount = 2
};
// Create an instance of Hangfire Server and start it.
_hangfireServer = new BackgroundJobServer(backgroundJobServerOptions, new PostgreSqlStorage(_settings.ConnectionString));
GlobalConfiguration.Configuration.UsePostgreSqlStorage(_settings.ConnectionString);
_logger.LogInformation("Hangfire started...");
Console.WriteLine("Hangfire Started...");
ConfigureRecurringTasks();
return Task.CompletedTask;
}
/// <summary>
/// <see cref="IHostedService.StopAsync(CancellationToken)"/>
/// </summary>
public Task StopAsync(CancellationToken cancellationToken)
{
_hangfireServer.Dispose();
_logger.LogWarning("Hangfire Server stoped.");
return Task.CompletedTask;
}
/// <summary>
/// Is used to configure recurring tasks in Hangfire.
/// </summary>
private void ConfigureRecurringTasks()
{
IEnumerable<IRecurringJob> recurringTasks = _serviceProvider.GetServices<IRecurringJob>();
IEnumerable<string> jobIds = recurringTasks.Select(x => x.Name).ToList();
using (IStorageConnection connection = JobStorage.Current.GetConnection())
{
foreach (RecurringJobDto recurringJob in connection.GetRecurringJobs().Where(recurringJob => !jobIds.Contains(recurringJob.Id)))
{
RecurringJob.RemoveIfExists(recurringJob.Id);
}
}
foreach (IRecurringJob task in recurringTasks)
{
if (task is ISynchronousJob synchronousTask)
{
RecurringJob.AddOrUpdate(
synchronousTask.Name,
() => synchronousTask.Execute(CancellationToken.None),
synchronousTask.CronExpression);
}
else if (task is IAsynchronousJob asynchronousTask)
{
RecurringJob.AddOrUpdate(
asynchronousTask.Name,
() => asynchronousTask.ExecuteAsync(CancellationToken.None),
asynchronousTask.CronExpression);
}
}
}
#endregion Methods
}
When I run docker run -i MyImage
, I can read “Test1” and “Test2”, that’s it.
Why the logger data are not displayed ?
Why the app exit with code 0 ?
Some usefull source :