-
Notifications
You must be signed in to change notification settings - Fork 190
/
Deploy.jl
170 lines (129 loc) · 6.06 KB
/
Deploy.jl
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
module Deploy
module Docker
import Genie, Genie.FileTemplates
const DOCKER = @static Sys.islinux() ? `sudo docker` : `docker`
"""
dockerfile(path::String = "."; user::String = "genie", env::String = "dev",
filename::String = "Dockerfile", port::Int = 8000, dockerport::Int = 80, force::Bool = false)
Generates a `Dockerfile` optimised for containerizing Genie apps.
# Arguments
- `path::String`: where to generate the file
- `filename::String`: the name of the file (default `Dockerfile`)
- `user::String`: the name of the system user under which the Genie app is run
- `env::String`: the environment in which the Genie app will run
- `host::String`: the local IP of the Genie app inside the container
- `port::Int`: the port of the Genie app inside the container
- `dockerport::Int`: the port to use on the host (used by the `EXPOSE` directive)
- `force::Bool`: if the file already exists, when `force` is `true`, it will be overwritten
"""
function dockerfile(path::String = "."; filename::String = "Dockerfile", user::String = "genie", env::String = "dev",
host = "127.0.0.1", port::Int = 8000, dockerport::Int = 80, force::Bool = false,
websockets_port::Int = port, websockets_dockerport::Int = dockerport)
filename = normpath(joinpath(path, filename))
isfile(filename) && force && rm(filename)
isfile(filename) && error("File $(filename) already exists. Use the `force = true` option to overwrite the existing file.")
open(filename, "w") do io
write(io, FileTemplates.dockerfile(user = user, env = env, filename = filename, host = host,
port = port, dockerport = dockerport,
websockets_port = websockets_port, websockets_dockerport = websockets_dockerport))
end
"Docker file successfully written at $(abspath(filename))" |> println
end
"""
build(path::String = "."; appname = "genie")
Builds the Docker image based on the `Dockerfile`
"""
function build(path::String = "."; appname::String = "genie")
`$DOCKER build -t "$appname" $path` |> Base.run
"Docker container successfully built" |> println
end
"""
run(; containername::String = "genieapp", hostport::Int = 80, containerport::Int = 8000, appdir::String = "/home/genie/app",
mountapp::Bool = false, image::String = "genie", command::String = "bin/server", rm::Bool = true, it::Bool = true)
Runs the Docker container named `containername`, binding `hostport` and `containerport`.
# Arguments
- `containername::String`: the name of the container of the Genie app
- `hostport::Int`: port to be used on the host for accessing the app
- `containerport::Int`: the port on which the app is running inside the container
- `appdir::String`: the folder where the app is stored within the container
- `mountapp::String`: if true the app from the host will be mounted so that changes on the host will be reflected when accessing the app in the container (to be used for dev)
- `image::String`: the name of the Docker image
- `command::String`: what command to run when starting the app
- `rm::Bool`: removes the container upon exit
- `it::Bool`: runs interactively
"""
function run(; containername::String = "genieapp", hostport::Int = 80, containerport::Int = 8000, appdir::String = "/home/genie/app",
mountapp::Bool = false, image::String = "genie", command::String = "bin/server", rm::Bool = true, it::Bool = true,
websockets_hostport::Int = hostport, websockets_containerport::Int = containerport)
options = []
it && push!(options, "-it")
rm && push!(options, "--rm")
push!(options, "-p")
push!(options, "$hostport:$containerport")
push!(options, "-p")
push!(options, "$websockets_hostport:$websockets_containerport")
push!(options, "--name")
push!(options, "$containername")
if mountapp
push!(options, "-v")
push!(options, "$(pwd()):$appdir")
end
push!(options, image)
isempty(command) || push!(options, command)
docker_command = replace(string(DOCKER), "`" => "")
"Starting docker container with `$docker_command run $(join(options, " "))`" |> println
`$DOCKER run $options` |> Base.run
end
end # end module Docker
########
module Heroku
"""
createapp(appname::String; region::String = "us")
Runs the `heroku create` command to create a new app in the indicated region.
See https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-apps-create-app
"""
function createapp(appname::String; region::String = "us")
`heroku create $(lowercase(appname)) --region $region` |> Base.run
end
"""
push(appname::String; apptype::String = "web")
Invokes the `heroku container:push` which builds, then pushes Docker images to deploy your Heroku app.
See https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-container-push
"""
function push(appname::String; apptype::String = "web")
`heroku container:push $apptype -a $appname` |> Base.run
end
"""
release(appname::String; apptype::String = "web")
Invokes the `keroku container:release` which releases previously pushed Docker images to your Heroku app.
See https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-container-push
"""
function release(appname::String; apptype::String = "web")
`heroku container:release $apptype -a $appname` |> Base.run
end
"""
open(appname::String)
Invokes the `heroku open` command which open the app in a web browser.
See https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-apps-open-path
"""
function open(appname::String)
`heroku open -a $appname` |> Base.run
end
"""
login()
Invokes the `heroku container:login` to log in to Heroku Container Registry,
See https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-container-login
"""
function login()
`heroku container:login` |> Base.run
end
"""
logs(appname::String; lines::Int = 1_000)
Display recent heroku log output.
https://devcenter.heroku.com/articles/heroku-cli-commands#heroku-logs
"""
function logs(appname::String; lines::Int = 1_000)
`heroku logs --tail -a $appname -n $lines` |> Base.run
end
end # end module Heroku
end # end module Deploy