-
Notifications
You must be signed in to change notification settings - Fork 224
/
phoenix.go
154 lines (135 loc) · 4.41 KB
/
phoenix.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package scanner
import (
"fmt"
"os"
"os/exec"
"path/filepath"
"github.com/superfly/flyctl/helpers"
)
func configurePhoenix(sourceDir string, config *ScannerConfig) (*SourceInfo, error) {
// Not phoenix, move on
if !helpers.FileExists(filepath.Join(sourceDir, "mix.exs")) || !checksPass(sourceDir, dirContains("mix.exs", "phoenix")) {
return nil, nil
}
s := &SourceInfo{
Family: "Phoenix",
Callback: PhoenixCallback,
Concurrency: map[string]int{
"soft_limit": 1000,
"hard_limit": 1000,
},
Secrets: []Secret{
{
Key: "SECRET_KEY_BASE",
Help: "Phoenix needs a random, secret key. Use the random default we've generated, or generate your own.",
Generate: func() (string, error) {
return helpers.RandString(64)
},
},
},
}
// Detect if --copy-config and --now flags are set. If so, limited set of
// fly.toml file updates. Helpful for deploying PRs when the project is
// already setup and we only need fly.toml config changes.
if config.Mode == "clone" {
s.Env = map[string]string{
"PHX_HOST": "APP_FQDN",
"FLY_LAUNCH_MODE": "clone",
}
return s, nil
}
s.KillSignal = "SIGTERM"
s.Port = 8080
s.Env = map[string]string{
"PHX_HOST": "APP_FQDN",
"PORT": "8080",
}
s.InitCommands = []InitCommand{
{
Command: "mix",
Args: []string{"local.rebar", "--force"},
Description: "Preparing system for Elixir builds",
},
{
Command: "mix",
Args: []string{"deps.get"},
Description: "Installing application dependencies",
},
{
Command: "mix",
Args: []string{"phx.gen.release", "--docker"},
Description: "Running Docker release generator",
},
}
// We found Phoenix, so check if the Docker generator is present
cmd := exec.Command("mix", "do", "deps.get,", "compile,", "run", "-e", "\"true = Code.ensure_loaded?(Mix.Tasks.Phx.Gen.Release)\"")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
err := cmd.Run()
if err == nil {
s.DeployDocs = `
Your Phoenix app should be ready for deployment!.
If you need something else, post on our community forum at https://community.fly.io.
When you're ready to deploy, use 'fly deploy'.
`
} else {
s.SkipDeploy = true
s.DeployDocs = `
We recommend upgrading to Phoenix 1.6.3 which includes a release configuration for Docker-based deployment.
If you do upgrade, you can run 'fly launch' again to get the required deployment setup.
If you don't want to upgrade, you'll need to add a few files and configuration options manually.
We've placed a Dockerfile compatible with other Phoenix 1.6 apps in this directory. See
https://hexdocs.pm/phoenix/fly.html for details, including instructions for setting up
a Postgresql database.
`
}
// Add migration task if we find ecto
if checksPass(sourceDir, dirContains("mix.exs", "ecto")) {
s.ReleaseCmd = "/app/bin/migrate"
}
return s, nil
}
func PhoenixCallback(appName string, _ *SourceInfo, options map[string]bool) error {
envEExPath := "rel/env.sh.eex"
envEExContents := `
# configure node for distributed erlang with IPV6 support
export ERL_AFLAGS="-proto_dist inet6_tcp"
export ECTO_IPV6="true"
export DNS_CLUSTER_QUERY="${FLY_APP_NAME}.internal"
export RELEASE_DISTRIBUTION="name"
export RELEASE_NODE="${FLY_APP_NAME}-${FLY_IMAGE_REF##*-}@${FLY_PRIVATE_IP}"
# enable swap if not already enabled
if ! [ -f "/swapfile" ]; then
echo "Creating swapfile"
fallocate -l 512M /swapfile
chmod 0600 /swapfile
mkswap /swapfile
echo 10 > /proc/sys/vm/swappiness
swapon /swapfile
echo 1 > /proc/sys/vm/overcommit_memory
fi
`
_, err := os.Stat(envEExPath)
if os.IsNotExist(err) {
fmt.Fprintln(os.Stdout, "Generating rel/env.sh.eex for distributed Elixir support")
contents := fmt.Sprintf("#!/bin/sh\n%s", envEExContents)
if err := os.MkdirAll("rel", 0o755); err != nil { // skipcq: GSC-G301
return err
}
if err := os.WriteFile(envEExPath, []byte(contents), 0o755); err != nil { // skipcq: GSC-G302
return err
}
} else if !fileContains(envEExPath, "RELEASE_NODE") {
fmt.Fprintln(os.Stdout, "Updating rel/env.sh.eex for distributed Elixir support")
appendedContents := fmt.Sprintf("# appended by fly launch: configure erlang with IPV6 and enable swap\n%s", envEExContents)
f, err := os.OpenFile(envEExPath, os.O_APPEND|os.O_WRONLY, 0o755) // skipcq: GSC-G302
if err != nil {
return err
}
defer f.Close() // skipcq: GO-S2307
if _, err := f.WriteString(appendedContents); err != nil {
return err
}
}
return nil
}