Skip to content
Snippets Groups Projects
Commit 41326fe3 authored by jurgenhaas's avatar jurgenhaas
Browse files

Update Traefik to 2.9

Update Portainer to 2.17.1
Update Hub to 1.0.1
Add support for automatic cert renewal with http or dns challenge
parent af048bc5
No related branches found
Tags v3.0.6
1 merge request!8Merging develop into main [MINOR_VERSION]
Pipeline #783431 passed
......@@ -17,42 +17,67 @@ class Traefik {
*
* @var string
*/
protected $name;
protected string $name;
/**
* @var string
*/
protected $domain;
protected string $domain;
/**
* @var int
*/
protected $http_port;
protected int $http_port;
/**
* @var int
*/
protected $https_port;
protected int $https_port;
/**
* @var string
*/
protected $cert_filename;
protected string $cert_filename;
/**
* @var string
*/
protected $key_filename;
protected string $key_filename;
/**
* @var bool
*/
protected $addon_portainer = FALSE;
protected bool $addon_portainer = FALSE;
/**
* @var string
*/
protected $hub_token = '';
protected string $hub_token = '';
/**
* @var array
*/
protected array $env;
/**
* @var bool
*/
protected bool $tls;
/**
* @var bool
*/
protected bool $dns_challenge;
/**
* @var string
*/
protected string $dns_challenge_provider;
/**
* @var string
*/
protected string $dns_challenge_resolver;
/**
* Traefik constructor.
......@@ -70,14 +95,45 @@ class Traefik {
* Filename of the SSL certificate.
* @param string $key_filename
* Filename of the private key for the SSL certificate.
* @param array $env
* A list of environment variables for the Traefik container.
* @param bool $tls
* Whether TLS should be supported.
* @param bool $dns_challenge
* If TLS is supported, it uses the http challenge by default. Set to TRUE
* to use the DNS challenge.
* @param string $dns_challenge_provider
* If DNS challenge should be used, a provider is required. For a list of
* supported providers:
* @see https://doc.traefik.io/traefik/https/acme/#providers
* @param string $dns_challenge_resolver
* In some scenarios, the DNS resolver needs to be defined in order to
* prevent local or shadow DNS servers being used.
*/
public function __construct(string $name, $domain = 'docker.localhost', $http_port = 8000, $https_port = 8443, $cert_filename = 'fullchain.pem', $key_filename = 'privkey.pem') {
public function __construct(
string $name,
string $domain = 'docker.localhost',
int $http_port = 8000,
int $https_port = 8443,
string $cert_filename = '',
string $key_filename = '',
array $env = [],
bool $tls = FALSE,
bool $dns_challenge = FALSE,
string $dns_challenge_provider = '',
string $dns_challenge_resolver = ''
) {
$this->name = $name;
$this->domain = $domain;
$this->http_port = $http_port;
$this->https_port = $https_port;
$this->cert_filename = $cert_filename;
$this->key_filename = $key_filename;
$this->env = $env;
$this->tls = $tls;
$this->dns_challenge = $dns_challenge;
$this->dns_challenge_provider = $dns_challenge_provider;
$this->dns_challenge_resolver = $dns_challenge_resolver;
}
/**
......@@ -146,6 +202,13 @@ class Traefik {
* @return bool
*/
private function updateFile(string $filename, string $content): bool {
if ($content === '') {
if (file_exists($filename)) {
unlink($filename);
return TRUE;
}
return FALSE;
}
if (file_exists($filename) && file_get_contents($filename) === $content) {
return FALSE;
}
......@@ -162,15 +225,13 @@ class Traefik {
'services' => [
'traefik' => [
'container_name' => 'traefik',
'image' => 'traefik:2.7',
'image' => 'traefik:2.9',
'command' => [
'--api=true',
'--api.dashboard=true',
'--api.insecure=true',
'--log.level=warning',
'--entrypoints.web.address=:80',
'--entrypoints.websecure.address=:443',
'--entrypoints.websecure.http.tls.domains[0].main=' . $this->domain,
'--entrypoints.websecure.http.tls.domains[0].sans=.' . $this->domain,
'--providers.file.directory=/configuration/',
'--providers.file.watch=true',
'--providers.docker=true',
......@@ -182,7 +243,6 @@ class Traefik {
],
'ports' => [
$this->http_port . ':80',
$this->https_port . ':443',
],
'labels' => [
'traefik.enable=true',
......@@ -203,10 +263,13 @@ class Traefik {
],
],
];
if (!empty($this->env)) {
$config['services']['traefik']['environment'] = $this->env;
}
if ($this->addon_portainer) {
$config['services']['portainer'] = [
'container_name' => 'portainer',
'image' => 'portainer/portainer-ce:2.11.1',
'image' => 'portainer/portainer-ce:2.17.1',
'command' => '-H unix:///var/run/docker.sock',
'restart' => 'unless-stopped',
'networks' => [
......@@ -238,7 +301,7 @@ class Traefik {
$config['services']['traefik']['ports'][] = '9901:9901';
$config['services']['hub-agent'] = [
'container_name' => 'hub-agent',
'image' => 'ghcr.io/traefik/hub-agent-traefik:v0.7.0',
'image' => 'ghcr.io/traefik/hub-agent-traefik:v1.0.1',
'command' => [
'run',
'--hub.token=' . $this->hub_token,
......@@ -258,6 +321,33 @@ class Traefik {
],
];
}
if ($this->tls) {
$config['services']['traefik']['command'][] = '--entrypoints.websecure.address=:443';
$config['services']['traefik']['command'][] = '--entrypoints.web.http.redirections.entrypoint.to=websecure';
$config['services']['traefik']['command'][] = '--certificatesresolvers.lakedrops.acme.email=admin@' . $this->domain;
$config['services']['traefik']['ports'][] = $this->https_port . ':443';
$config['services']['traefik']['labels'][] = 'traefik.http.routers.traefik.tls=true';
$config['services']['traefik']['labels'][] = 'traefik.http.routers.traefik.tls.certresolver=lakedrops';
if ($this->addon_portainer) {
$config['services']['portainer']['labels'][] = 'traefik.http.routers.traefik.tls=true';
$config['services']['portainer']['labels'][] = 'traefik.http.routers.traefik.tls.certresolver=lakedrops';
}
if ($this->hub_token) {
$config['services']['hub-agent']['labels'][] = 'traefik.http.routers.traefik.tls=true';
$config['services']['hub-agent']['labels'][] = 'traefik.http.routers.traefik.tls.certresolver=lakedrops';
}
if ($this->dns_challenge && $this->dns_challenge_provider !== '') {
$config['services']['traefik']['command'][] = '--certificatesresolvers.lakedrops.acme.dnschallenge=true';
$config['services']['traefik']['command'][] = '--certificatesresolvers.lakedrops.acme.dnschallenge.provider=' . $this->dns_challenge_provider;
if ($this->dns_challenge_resolver !== '') {
$config['services']['traefik']['command'][] = '--certificatesresolvers.lakedrops.acme.dnschallenge.resolvers=' . $this->dns_challenge_resolver;
}
}
else {
$config['services']['traefik']['command'][] = '--certificatesresolvers.lakedrops.acme.storage=/etc/traefik/acme/acme.json';
$config['services']['traefik']['command'][] = '--certificatesresolvers.lakedrops.acme.httpchallenge.entrypoint=web';
}
}
return $config;
}
......@@ -265,6 +355,9 @@ class Traefik {
* @return string
*/
private function defaultCertificatesConfig(): string {
if ($this->cert_filename === '' || $this->key_filename === '') {
return '';
}
return <<<EOF
[[tls.certificates]]
certFile = "/certs/$this->cert_filename"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment