diff --git a/app/Filament/App/Resources/DomainResource/ContainerRestarter.php b/app/Filament/App/Resources/DomainResource/ContainerRestarter.php index f95ddb54..1996c9f5 100644 --- a/app/Filament/App/Resources/DomainResource/ContainerRestarter.php +++ b/app/Filament/App/Resources/DomainResource/ContainerRestarter.php @@ -2,13 +2,19 @@ namespace App\Filament\Admin\Resources\DomainResource; -class DomainContainerRestarter +use Symfony\Component\Process\Process; + +class ContainerRestarter { - public function restart(string $domainName): void + public function restart(): void { - // Restart necessary containers for the given domain - $process = new Process(['docker-compose', 'restart', $domainName]); + // Restart Postfix and Dovecot containers + $process = new Process(['docker-compose', 'restart', 'postfix', 'dovecot']); $process->setWorkingDirectory(base_path()); $process->run(); + + if (!$process->isSuccessful()) { + throw new \RuntimeException('Failed to restart containers: ' . $process->getErrorOutput()); + } } } \ No newline at end of file diff --git a/app/Filament/App/Resources/DomainResource/DovecotConfigGenerator.php b/app/Filament/App/Resources/DomainResource/DovecotConfigGenerator.php index 2da748bc..1589c7fe 100644 --- a/app/Filament/App/Resources/DomainResource/DovecotConfigGenerator.php +++ b/app/Filament/App/Resources/DomainResource/DovecotConfigGenerator.php @@ -6,6 +6,33 @@ class DovecotConfigGenerator { public function generate(string $email, string $password): string { - return "user $email {\n password = $password\n}\n"; + $domain = explode('@', $email)[1]; + $hashedPassword = password_hash($password, PASSWORD_DEFAULT); + + return <<generateDovecotConfig($email->email, $email->password); - Storage::disk('dovecot')->put($email->email, $dovecotConfig); - + Storage::disk('dovecot_config')->put($email->email . '.conf', $dovecotConfig); + // Generate Postfix configuration $postfixConfig = $this->generatePostfixConfig($email->email, $email->password); - Storage::disk('postfix')->put($email->email, $postfixConfig); - + Storage::disk('postfix_config')->put($email->email . '.cf', $postfixConfig); + + // Create mailbox directory + Storage::disk('dovecot_data')->makeDirectory($email->email); + // Update Dovecot and Postfix Docker instances - $this->callSilent('email-servers:update'); - + $this->updateEmailServers(); + return $email; } @@ -85,15 +88,15 @@ protected function handleRecordUpdate(Email $email, array $data): Email $email->update($data); // Update Dovecot configuration - $dovecotConfig = $this->generateDovecotConfig($email); - Storage::disk('dovecot')->put($email->email, $dovecotConfig); + $dovecotConfig = $this->generateDovecotConfig($email->email, $email->password); + Storage::disk('dovecot_config')->put($email->email . '.conf', $dovecotConfig); // Update Postfix configuration - $postfixConfig = $this->generatePostfixConfig($email); - Storage::disk('postfix')->put($email->email, $postfixConfig); + $postfixConfig = $this->generatePostfixConfig($email->email, $email->password); + Storage::disk('postfix_config')->put($email->email . '.cf', $postfixConfig); - // Restart Dovecot and Postfix containers - $this->restartContainers(); + // Update Dovecot and Postfix Docker instances + $this->updateEmailServers(); return $email; } @@ -101,17 +104,25 @@ protected function handleRecordUpdate(Email $email, array $data): Email protected function handleRecordDeletion(Email $email) { // Remove Dovecot configuration - Storage::disk('dovecot')->delete($email->email); + Storage::disk('dovecot_config')->delete($email->email . '.conf'); - // Remove Postfix configuration - Storage::disk('postfix')->delete($email->email); + // Remove Postfix configuration + Storage::disk('postfix_config')->delete($email->email . '.cf'); - // Restart Dovecot and Postfix containers - $this->restartContainers(); + // Remove mailbox directory + Storage::disk('dovecot_data')->deleteDirectory($email->email); + + // Update Dovecot and Postfix Docker instances + $this->updateEmailServers(); $email->delete(); } + protected function updateEmailServers() + { + $this->callSilent('email-servers:update'); + } + protected function generateDovecotConfig(string $email, string $password): string { return (new DovecotConfigGenerator)->generate($email, $password); diff --git a/docker-compose.yml b/docker-compose.yml index d16d50cc..269953e1 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -25,27 +25,36 @@ services: environment: - NGINX_PROXY_CONTAINER=nginx-proxy - postfix: - image: boky/postfix - restart: always - environment: - - SMTP_SERVER=example.com - - SMTP_USERNAME=user@example.com - - SMTP_PASSWORD=password - ports: - - "25:25" - - "587:587" + version: '3' - dovecot: - image: dovecot/dovecot - restart: always - ports: - - "110:110" - - "143:143" - - "993:993" - - "995:995" - volumes: - - ./mail:/var/mail + services: + postfix: + image: postfix:latest + volumes: + - ./postfix_data:/var/spool/postfix + - ./postfix_config:/etc/postfix + environment: + - MAILNAME=example.com + ports: + - "25:25" + - "587:587" + + dovecot: + image: dovecot:latest + volumes: + - ./dovecot_data:/var/mail + - ./dovecot_config:/etc/dovecot + ports: + - "110:110" + - "143:143" + - "993:993" + - "995:995" + + volumes: + postfix_data: + postfix_config: + dovecot_data: + dovecot_config: bind9: image: internetsystemsconsortium/bind9:9.16