diff options
Diffstat (limited to 'cmd/ship/deploy.go')
| -rw-r--r-- | cmd/ship/deploy.go | 124 |
1 files changed, 88 insertions, 36 deletions
diff --git a/cmd/ship/deploy.go b/cmd/ship/deploy.go index 86d4878..6894e21 100644 --- a/cmd/ship/deploy.go +++ b/cmd/ship/deploy.go | |||
| @@ -337,39 +337,65 @@ func deployApp(st *state.State, opts DeployOptions) error { | |||
| 337 | return fmt.Errorf("error setting env file ownership: %w", err) | 337 | return fmt.Errorf("error setting env file ownership: %w", err) |
| 338 | } | 338 | } |
| 339 | 339 | ||
| 340 | fmt.Println("-> Creating systemd service...") | 340 | // Create local .ship directory for deployment configs |
| 341 | serviceContent, err := templates.SystemdService(map[string]string{ | 341 | if !opts.IsUpdate { |
| 342 | "Name": opts.Name, | 342 | fmt.Println("-> Creating local .ship directory...") |
| 343 | "User": opts.Name, | 343 | if err := os.MkdirAll(".ship", 0755); err != nil { |
| 344 | "WorkDir": workDir, | 344 | return fmt.Errorf("error creating .ship directory: %w", err) |
| 345 | "BinaryPath": binaryDest, | 345 | } |
| 346 | "Port": strconv.Itoa(port), | 346 | |
| 347 | "EnvFile": envFilePath, | 347 | fmt.Println("-> Generating systemd service...") |
| 348 | "Args": opts.Args, | 348 | serviceContent, err := templates.SystemdService(map[string]string{ |
| 349 | "Memory": opts.Memory, | 349 | "Name": opts.Name, |
| 350 | "CPU": opts.CPU, | 350 | "User": opts.Name, |
| 351 | }) | 351 | "WorkDir": workDir, |
| 352 | if err != nil { | 352 | "BinaryPath": binaryDest, |
| 353 | return fmt.Errorf("error generating systemd unit: %w", err) | 353 | "Port": strconv.Itoa(port), |
| 354 | "EnvFile": envFilePath, | ||
| 355 | "Args": opts.Args, | ||
| 356 | "Memory": opts.Memory, | ||
| 357 | "CPU": opts.CPU, | ||
| 358 | }) | ||
| 359 | if err != nil { | ||
| 360 | return fmt.Errorf("error generating systemd unit: %w", err) | ||
| 361 | } | ||
| 362 | if err := os.WriteFile(".ship/service", []byte(serviceContent), 0644); err != nil { | ||
| 363 | return fmt.Errorf("error writing .ship/service: %w", err) | ||
| 364 | } | ||
| 365 | |||
| 366 | fmt.Println("-> Generating Caddyfile...") | ||
| 367 | caddyContent, err := templates.AppCaddy(map[string]string{ | ||
| 368 | "Domain": opts.Domain, | ||
| 369 | "Port": strconv.Itoa(port), | ||
| 370 | }) | ||
| 371 | if err != nil { | ||
| 372 | return fmt.Errorf("error generating Caddy config: %w", err) | ||
| 373 | } | ||
| 374 | if err := os.WriteFile(".ship/Caddyfile", []byte(caddyContent), 0644); err != nil { | ||
| 375 | return fmt.Errorf("error writing .ship/Caddyfile: %w", err) | ||
| 376 | } | ||
| 354 | } | 377 | } |
| 355 | 378 | ||
| 379 | // Upload systemd service from .ship/service | ||
| 380 | fmt.Println("-> Installing systemd service...") | ||
| 381 | serviceContent, err := os.ReadFile(".ship/service") | ||
| 382 | if err != nil { | ||
| 383 | return fmt.Errorf("error reading .ship/service: %w (run initial deployment first)", err) | ||
| 384 | } | ||
| 356 | servicePath := fmt.Sprintf("/etc/systemd/system/%s.service", opts.Name) | 385 | servicePath := fmt.Sprintf("/etc/systemd/system/%s.service", opts.Name) |
| 357 | if err := client.WriteSudoFile(servicePath, serviceContent); err != nil { | 386 | if err := client.WriteSudoFile(servicePath, string(serviceContent)); err != nil { |
| 358 | return fmt.Errorf("error creating systemd unit: %w", err) | 387 | return fmt.Errorf("error installing systemd unit: %w", err) |
| 359 | } | 388 | } |
| 360 | 389 | ||
| 361 | fmt.Println("-> Configuring Caddy...") | 390 | // Upload Caddyfile from .ship/Caddyfile |
| 362 | caddyContent, err := templates.AppCaddy(map[string]string{ | 391 | fmt.Println("-> Installing Caddy config...") |
| 363 | "Domain": opts.Domain, | 392 | caddyContent, err := os.ReadFile(".ship/Caddyfile") |
| 364 | "Port": strconv.Itoa(port), | ||
| 365 | }) | ||
| 366 | if err != nil { | 393 | if err != nil { |
| 367 | return fmt.Errorf("error generating Caddy config: %w", err) | 394 | return fmt.Errorf("error reading .ship/Caddyfile: %w (run initial deployment first)", err) |
| 368 | } | 395 | } |
| 369 | |||
| 370 | caddyPath := fmt.Sprintf("/etc/caddy/sites-enabled/%s.caddy", opts.Name) | 396 | caddyPath := fmt.Sprintf("/etc/caddy/sites-enabled/%s.caddy", opts.Name) |
| 371 | if err := client.WriteSudoFile(caddyPath, caddyContent); err != nil { | 397 | if err := client.WriteSudoFile(caddyPath, string(caddyContent)); err != nil { |
| 372 | return fmt.Errorf("error creating Caddy config: %w", err) | 398 | return fmt.Errorf("error installing Caddy config: %w", err) |
| 373 | } | 399 | } |
| 374 | 400 | ||
| 375 | fmt.Println("-> Reloading systemd...") | 401 | fmt.Println("-> Reloading systemd...") |
| @@ -447,7 +473,7 @@ func updateAppConfig(st *state.State, opts DeployOptions) error { | |||
| 447 | // For git-app, the systemd unit comes from .ship/service in the repo, | 473 | // For git-app, the systemd unit comes from .ship/service in the repo, |
| 448 | // so we only update the env file and restart. | 474 | // so we only update the env file and restart. |
| 449 | if existingApp.Type != "git-app" { | 475 | if existingApp.Type != "git-app" { |
| 450 | // Regenerate systemd unit | 476 | // Regenerate systemd unit to .ship/service (resource flags are being updated) |
| 451 | fmt.Println("-> Updating systemd service...") | 477 | fmt.Println("-> Updating systemd service...") |
| 452 | workDir := fmt.Sprintf("/var/lib/%s", opts.Name) | 478 | workDir := fmt.Sprintf("/var/lib/%s", opts.Name) |
| 453 | binaryDest := fmt.Sprintf("/usr/local/bin/%s", opts.Name) | 479 | binaryDest := fmt.Sprintf("/usr/local/bin/%s", opts.Name) |
| @@ -466,9 +492,18 @@ func updateAppConfig(st *state.State, opts DeployOptions) error { | |||
| 466 | return fmt.Errorf("error generating systemd unit: %w", err) | 492 | return fmt.Errorf("error generating systemd unit: %w", err) |
| 467 | } | 493 | } |
| 468 | 494 | ||
| 495 | // Write to local .ship/service | ||
| 496 | if err := os.MkdirAll(".ship", 0755); err != nil { | ||
| 497 | return fmt.Errorf("error creating .ship directory: %w", err) | ||
| 498 | } | ||
| 499 | if err := os.WriteFile(".ship/service", []byte(serviceContent), 0644); err != nil { | ||
| 500 | return fmt.Errorf("error writing .ship/service: %w", err) | ||
| 501 | } | ||
| 502 | |||
| 503 | // Upload to server | ||
| 469 | servicePath := fmt.Sprintf("/etc/systemd/system/%s.service", opts.Name) | 504 | servicePath := fmt.Sprintf("/etc/systemd/system/%s.service", opts.Name) |
| 470 | if err := client.WriteSudoFile(servicePath, serviceContent); err != nil { | 505 | if err := client.WriteSudoFile(servicePath, serviceContent); err != nil { |
| 471 | return fmt.Errorf("error creating systemd unit: %w", err) | 506 | return fmt.Errorf("error installing systemd unit: %w", err) |
| 472 | } | 507 | } |
| 473 | 508 | ||
| 474 | fmt.Println("-> Reloading systemd...") | 509 | fmt.Println("-> Reloading systemd...") |
| @@ -546,18 +581,35 @@ func deployStatic(st *state.State, opts DeployOptions) error { | |||
| 546 | return fmt.Errorf("error setting file permissions: %w", err) | 581 | return fmt.Errorf("error setting file permissions: %w", err) |
| 547 | } | 582 | } |
| 548 | 583 | ||
| 549 | fmt.Println("-> Configuring Caddy...") | 584 | // Create local .ship directory and Caddyfile for static sites |
| 550 | caddyContent, err := templates.StaticCaddy(map[string]string{ | 585 | if !opts.IsUpdate { |
| 551 | "Domain": opts.Domain, | 586 | fmt.Println("-> Creating local .ship directory...") |
| 552 | "RootDir": remoteDir, | 587 | if err := os.MkdirAll(".ship", 0755); err != nil { |
| 553 | }) | 588 | return fmt.Errorf("error creating .ship directory: %w", err) |
| 554 | if err != nil { | 589 | } |
| 555 | return fmt.Errorf("error generating Caddy config: %w", err) | 590 | |
| 591 | fmt.Println("-> Generating Caddyfile...") | ||
| 592 | caddyContent, err := templates.StaticCaddy(map[string]string{ | ||
| 593 | "Domain": opts.Domain, | ||
| 594 | "RootDir": remoteDir, | ||
| 595 | }) | ||
| 596 | if err != nil { | ||
| 597 | return fmt.Errorf("error generating Caddy config: %w", err) | ||
| 598 | } | ||
| 599 | if err := os.WriteFile(".ship/Caddyfile", []byte(caddyContent), 0644); err != nil { | ||
| 600 | return fmt.Errorf("error writing .ship/Caddyfile: %w", err) | ||
| 601 | } | ||
| 556 | } | 602 | } |
| 557 | 603 | ||
| 604 | // Upload Caddyfile from .ship/Caddyfile | ||
| 605 | fmt.Println("-> Installing Caddy config...") | ||
| 606 | caddyContent, err := os.ReadFile(".ship/Caddyfile") | ||
| 607 | if err != nil { | ||
| 608 | return fmt.Errorf("error reading .ship/Caddyfile: %w (run initial deployment first)", err) | ||
| 609 | } | ||
| 558 | caddyPath := fmt.Sprintf("/etc/caddy/sites-enabled/%s.caddy", opts.Name) | 610 | caddyPath := fmt.Sprintf("/etc/caddy/sites-enabled/%s.caddy", opts.Name) |
| 559 | if err := client.WriteSudoFile(caddyPath, caddyContent); err != nil { | 611 | if err := client.WriteSudoFile(caddyPath, string(caddyContent)); err != nil { |
| 560 | return fmt.Errorf("error creating Caddy config: %w", err) | 612 | return fmt.Errorf("error installing Caddy config: %w", err) |
| 561 | } | 613 | } |
| 562 | 614 | ||
| 563 | fmt.Println("-> Reloading Caddy...") | 615 | fmt.Println("-> Reloading Caddy...") |
