Newer
Older
<?php
namespace LakeDrops\DockerTraefik;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\Yaml\Yaml;
/**
* Class Traefik.
*
* @package LakeDrops\DockerTraefik
*/
/**
* The name of the project using Traefik.
*
* @var string
*/
/**
* @var string
*/
protected $domain;
/**
* @var int
*/
protected $http_port;
/**
* @var int
*/
protected $https_port;
/**
* @var string
*/
protected $cert_filename;
/**
* @var string
*/
protected $key_filename;
/**
* @var bool
*/
protected $addon_portainer = FALSE;
* Name of the network to be created which needs to match the container
* prefix of your project you would like to handle with Traefik.
* @param string $domain
* The domain name used for all local projects.
* @param int $http_port
* Port for non secure requests.
* @param int $https_port
* Port for secure requests.
* @param string $cert_filename
* Filename of the SSL certificate.
* @param string $key_filename
* Filename of the private key for the SSL certificate.
public function __construct(string $name, $domain = 'docker.localhost', $http_port = 8000, $https_port = 8443, $cert_filename = 'fullchain.pem', $key_filename = 'privkey.pem') {
$this->domain = $domain;
$this->http_port = $http_port;
$this->https_port = $https_port;
$this->cert_filename = $cert_filename;
$this->key_filename = $key_filename;
/**
* @param bool $addon_portainer
*/
public function setAddonPortainer(bool $addon_portainer): void {
$this->addon_portainer = $addon_portainer;
}

jurgenhaas
committed
public function update(): void {
// Update host wide traefik container.
$traefikCertPath = $_SERVER['HOME'] . '/.traefik/certs';
$traefikConfigPath = $_SERVER['HOME'] . '/.traefik/configuration';

jurgenhaas
committed
if (!$fs->exists($traefikPath)) {
if (!$fs->exists($traefikCertPath)) {
$fs->mkdir($traefikCertPath);
}
if (!$fs->exists($traefikConfigPath)) {
$fs->mkdir($traefikConfigPath);
}
file_put_contents($traefikConfigPath . '/certificates.toml', $this->defaultCertificatesConfig());

jurgenhaas
committed
file_put_contents($traefikFile, Yaml::dump($this->defaultDockerCompose(), 9, 2));
$cwd = getcwd();
chdir($traefikPath);
exec('docker network create traefik-public 2>/dev/null');
exec('docker compose --project-name traefik up -d');
chdir($cwd);
/**
* @return array
*/
private function defaultDockerCompose(): array {
$config = [
'version' => '3.3',
'services' => [
'traefik' => [

jurgenhaas
committed
'image' => 'traefik:2.6',
'command' => [
'--api=true',
'--api.dashboard=true',
'--api.insecure=true',
'--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',
'--providers.docker.exposedbydefault=false',
],
'restart' => 'unless-stopped',
'networks' => [

jurgenhaas
committed
'traefik-public',
],
'ports' => [
$this->http_port . ':80',
$this->https_port . ':443',
],
'labels' => [
'traefik.enable=true',

jurgenhaas
committed
'traefik.network=traefik-public',
'traefik.http.routers.traefik.service=api@internal',
'traefik.http.routers.traefik.rule=Host(`traefik.' . $this->domain . '`)',
],
'volumes' => [
'./certs:/certs/:ro',
'./configuration:/configuration/:ro',
'/var/run/docker.sock:/var/run/docker.sock:ro',
],
],
],
'networks' => [

jurgenhaas
committed
'traefik-public' => [
'external' => true,
],
],
];
if ($this->addon_portainer) {
$config['services']['portainer'] = [

jurgenhaas
committed
'image' => 'portainer/portainer-ce:2.11.1',
'command' => '-H unix:///var/run/docker.sock',
'restart' => 'unless-stopped',
'networks' => [

jurgenhaas
committed
'traefik-public',
],
'labels' => [
'traefik.enable=true',

jurgenhaas
committed
'traefik.network=traefik-public',
'traefik.http.routers.frontend.rule=Host(`portainer.' . $this->domain . '`)',
'traefik.http.routers.frontend.entrypoints=websecure',
'traefik.http.services.frontend.loadbalancer.server.port=9000',
'traefik.http.routers.frontend.service=frontend',
'traefik.http.routers.edge.rule=Host(`edge.' . $this->domain . '`)',
'traefik.http.routers.edge.entrypoints=websecure',
'traefik.http.services.edge.loadbalancer.server.port=8000',
'traefik.http.routers.edge.service=edge',
],
'volumes' => [
'./portainerdata:/data',
'/var/run/docker.sock:/var/run/docker.sock:ro',
],
];
}
return $config;
}
/**
* @return string
*/
private function defaultCertificatesConfig(): string {
return <<<EOF
[[tls.certificates]]
certFile = "/certs/$this->cert_filename"
keyFile = "/certs/$this->key_filename"
EOF;
}