252
internal/proxy/nginx.go
Archivo normal
252
internal/proxy/nginx.go
Archivo normal
@@ -0,0 +1,252 @@
|
||||
package proxy
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/yourusername/buque/internal/docker"
|
||||
"github.com/yourusername/buque/internal/models"
|
||||
)
|
||||
|
||||
const (
|
||||
nginxProxyImage = "nginxproxy/nginx-proxy:latest"
|
||||
nginxProxyCompanionImage = "nginxproxy/acme-companion:latest"
|
||||
)
|
||||
|
||||
// NginxManager manages nginx-proxy deployment and configuration
|
||||
type NginxManager struct {
|
||||
config models.NginxProxyConfig
|
||||
dockerClient *docker.Client
|
||||
composeManager *docker.ComposeManager
|
||||
}
|
||||
|
||||
// NewNginxManager creates a new nginx-proxy manager
|
||||
func NewNginxManager(config models.NginxProxyConfig) (*NginxManager, error) {
|
||||
dockerClient, err := docker.NewClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
composeManager, err := docker.NewComposeManager()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &NginxManager{
|
||||
config: config,
|
||||
dockerClient: dockerClient,
|
||||
composeManager: composeManager,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Close closes the nginx manager
|
||||
func (nm *NginxManager) Close() error {
|
||||
return nm.dockerClient.Close()
|
||||
}
|
||||
|
||||
// Deploy deploys the nginx-proxy environment
|
||||
func (nm *NginxManager) Deploy(ctx context.Context) error {
|
||||
// Create nginx-proxy directory if it doesn't exist
|
||||
if err := os.MkdirAll(nm.config.Path, 0755); err != nil {
|
||||
return fmt.Errorf("failed to create nginx-proxy directory: %w", err)
|
||||
}
|
||||
|
||||
// Create docker-compose.yml
|
||||
composeContent := nm.generateComposeFile()
|
||||
composePath := filepath.Join(nm.config.Path, "docker-compose.yml")
|
||||
if err := os.WriteFile(composePath, []byte(composeContent), 0644); err != nil {
|
||||
return fmt.Errorf("failed to write compose file: %w", err)
|
||||
}
|
||||
|
||||
// Create network if it doesn't exist
|
||||
exists, err := nm.dockerClient.NetworkExists(ctx, nm.config.NetworkName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to check network: %w", err)
|
||||
}
|
||||
|
||||
if !exists {
|
||||
if err := nm.dockerClient.CreateNetwork(ctx, nm.config.NetworkName); err != nil {
|
||||
return fmt.Errorf("failed to create network: %w", err)
|
||||
}
|
||||
fmt.Printf("Created network: %s\n", nm.config.NetworkName)
|
||||
}
|
||||
|
||||
// Deploy using docker-compose
|
||||
env := models.Environment{
|
||||
Name: "nginx-proxy",
|
||||
Path: nm.config.Path,
|
||||
ComposeFile: "docker-compose.yml",
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
fmt.Println("Deploying nginx-proxy...")
|
||||
if err := nm.composeManager.Up(ctx, env, true); err != nil {
|
||||
return fmt.Errorf("failed to deploy nginx-proxy: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("Nginx-proxy deployed successfully!")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Remove removes the nginx-proxy environment
|
||||
func (nm *NginxManager) Remove(ctx context.Context) error {
|
||||
env := models.Environment{
|
||||
Name: "nginx-proxy",
|
||||
Path: nm.config.Path,
|
||||
ComposeFile: "docker-compose.yml",
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
fmt.Println("Removing nginx-proxy...")
|
||||
if err := nm.composeManager.Down(ctx, env, true); err != nil {
|
||||
return fmt.Errorf("failed to remove nginx-proxy: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("Nginx-proxy removed successfully!")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Status returns the status of nginx-proxy
|
||||
func (nm *NginxManager) Status(ctx context.Context) (string, error) {
|
||||
env := models.Environment{
|
||||
Name: "nginx-proxy",
|
||||
Path: nm.config.Path,
|
||||
ComposeFile: "docker-compose.yml",
|
||||
Enabled: true,
|
||||
}
|
||||
|
||||
return nm.composeManager.PS(ctx, env)
|
||||
}
|
||||
|
||||
// generateComposeFile generates the docker-compose.yml content for nginx-proxy
|
||||
func (nm *NginxManager) generateComposeFile() string {
|
||||
content := fmt.Sprintf(`version: '3.8'
|
||||
|
||||
services:
|
||||
nginx-proxy:
|
||||
image: %s
|
||||
container_name: %s
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "%d:80"`, nginxProxyImage, nm.config.ContainerName, nm.config.HTTPPort)
|
||||
|
||||
if nm.config.SSLEnabled {
|
||||
content += fmt.Sprintf(`
|
||||
- "%d:443"`, nm.config.HTTPSPort)
|
||||
}
|
||||
|
||||
content += `
|
||||
volumes:
|
||||
- /var/run/docker.sock:/tmp/docker.sock:ro`
|
||||
|
||||
if nm.config.SSLEnabled {
|
||||
content += `
|
||||
- certs:/etc/nginx/certs:ro
|
||||
- vhost:/etc/nginx/vhost.d
|
||||
- html:/usr/share/nginx/html`
|
||||
}
|
||||
|
||||
content += `
|
||||
environment:
|
||||
- DEFAULT_HOST=localhost
|
||||
networks:
|
||||
- ` + nm.config.NetworkName
|
||||
|
||||
content += `
|
||||
labels:
|
||||
- "buque.managed=true"
|
||||
- "buque.service=nginx-proxy"`
|
||||
|
||||
if nm.config.SSLEnabled {
|
||||
content += fmt.Sprintf(`
|
||||
|
||||
acme-companion:
|
||||
image: %s
|
||||
container_name: nginx-proxy-acme
|
||||
restart: unless-stopped
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- certs:/etc/nginx/certs
|
||||
- vhost:/etc/nginx/vhost.d
|
||||
- html:/usr/share/nginx/html
|
||||
- acme:/etc/acme.sh
|
||||
environment:
|
||||
- DEFAULT_EMAIL=admin@localhost
|
||||
- NGINX_PROXY_CONTAINER=%s
|
||||
networks:
|
||||
- %s
|
||||
depends_on:
|
||||
- nginx-proxy
|
||||
labels:
|
||||
- "buque.managed=true"
|
||||
- "buque.service=nginx-proxy-acme"`, nginxProxyCompanionImage, nm.config.ContainerName, nm.config.NetworkName)
|
||||
}
|
||||
|
||||
content += `
|
||||
|
||||
networks:
|
||||
` + nm.config.NetworkName + `:
|
||||
external: true`
|
||||
|
||||
if nm.config.SSLEnabled {
|
||||
content += `
|
||||
|
||||
volumes:
|
||||
certs:
|
||||
vhost:
|
||||
html:
|
||||
acme:`
|
||||
}
|
||||
|
||||
return content
|
||||
}
|
||||
|
||||
// GenerateServiceLabels generates labels for a service to work with nginx-proxy
|
||||
func (nm *NginxManager) GenerateServiceLabels(virtualHost string, virtualPort int, letsencryptHost string, letsencryptEmail string) map[string]string {
|
||||
labels := map[string]string{
|
||||
"VIRTUAL_HOST": virtualHost,
|
||||
}
|
||||
|
||||
if virtualPort > 0 {
|
||||
labels["VIRTUAL_PORT"] = fmt.Sprintf("%d", virtualPort)
|
||||
}
|
||||
|
||||
if nm.config.SSLEnabled && letsencryptHost != "" {
|
||||
labels["LETSENCRYPT_HOST"] = letsencryptHost
|
||||
if letsencryptEmail != "" {
|
||||
labels["LETSENCRYPT_EMAIL"] = letsencryptEmail
|
||||
}
|
||||
}
|
||||
|
||||
return labels
|
||||
}
|
||||
|
||||
// GetExampleServiceCompose returns an example docker-compose.yml for a service behind nginx-proxy
|
||||
func (nm *NginxManager) GetExampleServiceCompose(serviceName, virtualHost string) string {
|
||||
return fmt.Sprintf(`version: '3.8'
|
||||
|
||||
services:
|
||||
%s:
|
||||
image: your-image:latest
|
||||
container_name: %s
|
||||
restart: unless-stopped
|
||||
expose:
|
||||
- "80"
|
||||
environment:
|
||||
- VIRTUAL_HOST=%s
|
||||
- VIRTUAL_PORT=80
|
||||
- LETSENCRYPT_HOST=%s
|
||||
- LETSENCRYPT_EMAIL=admin@%s
|
||||
networks:
|
||||
- %s
|
||||
labels:
|
||||
- "buque.environment=%s"
|
||||
- "buque.managed=true"
|
||||
|
||||
networks:
|
||||
%s:
|
||||
external: true
|
||||
`, serviceName, serviceName, virtualHost, virtualHost, virtualHost, nm.config.NetworkName, serviceName, nm.config.NetworkName)
|
||||
}
|
||||
Referencia en una nueva incidencia
Block a user