vps 0.1.1 → 0.2.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +25 -0
- data/VERSION +1 -1
- data/lib/vps.rb +1 -0
- data/lib/vps/cli.rb +1 -0
- data/lib/vps/cli/domain.rb +1 -1
- data/lib/vps/cli/playbook/state.rb +1 -1
- data/lib/vps/cli/upstream.rb +37 -21
- data/lib/vps/core_ext/ostruct.rb +17 -0
- data/lib/vps/version.rb +2 -2
- data/playbooks/deploy/docker.yml +2 -2
- data/templates/docker/data/nginx/app.conf.erb +21 -4
- data/templates/docker/docker-compose.yml.erb +15 -12
- data/templates/docker/upstream/Dockerfile.node.erb +15 -0
- data/templates/docker/upstream/Dockerfile.phoenix.erb +4 -1
- data/templates/docker/upstream/Dockerfile.plug.erb +4 -1
- data/templates/docker/upstream/Dockerfile.rack.erb +6 -2
- data/templates/docker/upstream/Dockerfile.rails.erb +8 -1
- data/templates/docker/upstream/init-letsencrypt.sh.erb +3 -3
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0715c15db0c61c43f427cde770c38cde3f65e677
|
4
|
+
data.tar.gz: 62fbbc6d56af47c025031dd5125ab7a4072d546d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0850d9d9a5888d1162e7cb491906f0afea445f82535a68ae03014b6304cb594c7c81f765f14325bf0b1d295a1a88a7e07ac009859f6d5c0ba727d3fee34988a8
|
7
|
+
data.tar.gz: 7c6dfffa4ce37dc82012bf13865cc03f9feb6367c1565305f5a7461f88fe73d951fccd502fbfc6544df7505f50fb1de15feabdef5ec29bffd682cfc0a768f1be
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,30 @@
|
|
1
1
|
## VPS CHANGELOG
|
2
2
|
|
3
|
+
### Version 0.2.3 (January 2, 2020)
|
4
|
+
|
5
|
+
* Support upstreams without domains
|
6
|
+
|
7
|
+
### Version 0.2.2 (January 2, 2020)
|
8
|
+
|
9
|
+
* Automatically add container names for upstreams and services
|
10
|
+
* Add opportunity to add lines to the generated Dockerfile
|
11
|
+
|
12
|
+
### Version 0.2.1 (January 2, 2020)
|
13
|
+
|
14
|
+
* Support NodeJS based applications
|
15
|
+
* Clean up default upstream specs
|
16
|
+
* Set container name when adding upstream
|
17
|
+
|
18
|
+
### Version 0.2.0 (December 31, 2019)
|
19
|
+
|
20
|
+
* Provide ability to add both custom HTTP and HTTPS Nginx configs
|
21
|
+
|
22
|
+
### Version 0.1.2 (September 29, 2019)
|
23
|
+
|
24
|
+
* Run postload tasks at the end of deployment
|
25
|
+
* Fix generating Rails and Rack Dockerfile (installing the correct Bundler version)
|
26
|
+
* Include configured :services in the generated docker-compose.yml file
|
27
|
+
|
3
28
|
### Version 0.1.1 (August 12, 2019)
|
4
29
|
|
5
30
|
* Initial release
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.2.3
|
data/lib/vps.rb
CHANGED
data/lib/vps/cli.rb
CHANGED
data/lib/vps/cli/domain.rb
CHANGED
@@ -11,7 +11,7 @@ module VPS
|
|
11
11
|
|
12
12
|
if (upstream = config[:upstreams].detect{|upstream| upstream[:name] == name})
|
13
13
|
upstream[:email] = email if email
|
14
|
-
upstream[:domains].push(domain).uniq!
|
14
|
+
(upstream[:domains] ||= []).push(domain).uniq!
|
15
15
|
VPS.write_config(host, config)
|
16
16
|
end
|
17
17
|
end
|
data/lib/vps/cli/upstream.rb
CHANGED
@@ -9,18 +9,11 @@ module VPS
|
|
9
9
|
path = File.expand_path(path)
|
10
10
|
|
11
11
|
unless config[:upstreams].any?{|upstream| upstream[:name] == name}
|
12
|
-
|
13
|
-
config[:upstreams].push({
|
12
|
+
spec = derive_upstream(path)
|
13
|
+
config[:upstreams].push(spec.merge({
|
14
14
|
:name => name || File.basename(path),
|
15
|
-
:path => path
|
16
|
-
|
17
|
-
:tool_version => tool_version,
|
18
|
-
:port => port,
|
19
|
-
:domains => [],
|
20
|
-
:email => nil,
|
21
|
-
:compose => nil,
|
22
|
-
:nginx => nil
|
23
|
-
})
|
15
|
+
:path => path
|
16
|
+
}))
|
24
17
|
VPS.write_config(host, config)
|
25
18
|
end
|
26
19
|
end
|
@@ -65,19 +58,42 @@ module VPS
|
|
65
58
|
|> IO.puts()
|
66
59
|
ELIXIR
|
67
60
|
type = `cd #{path} && mix run -e "#{elixir.strip.gsub(/\n\s+/, " ")}" | tail -n 1`.strip
|
68
|
-
|
69
|
-
type,
|
70
|
-
`cd #{path} && mix run -e "System.version() |> IO.puts()" | tail -n 1`.strip,
|
71
|
-
(type == "phoenix") ? 4000 : `cd #{path} && mix run -e ":ranch.info |> hd() |> elem(0) |> :ranch.get_port() |> IO.puts()" | tail -n 1`.strip.to_i
|
72
|
-
|
61
|
+
{
|
62
|
+
type: type,
|
63
|
+
elixir_version: `cd #{path} && mix run -e "System.version() |> IO.puts()" | tail -n 1`.strip,
|
64
|
+
port: (type == "phoenix") ? 4000 : `cd #{path} && mix run -e ":ranch.info |> hd() |> elem(0) |> :ranch.get_port() |> IO.puts()" | tail -n 1`.strip.to_i
|
65
|
+
}
|
73
66
|
elsif Dir["#{path}/Gemfile"].any?
|
74
67
|
lines = `cd #{path} && BUNDLE_GEMFILE=#{path}/Gemfile bundle list`.split("\n")
|
75
68
|
type = %w(rails rack).detect{|gem| lines.any?{|line| line.include?("* #{gem} (")}}
|
76
|
-
|
77
|
-
type,
|
78
|
-
`$SHELL -l -c 'cd #{path} && ruby -e "puts RUBY_VERSION"'`.strip,
|
79
|
-
|
80
|
-
|
69
|
+
{
|
70
|
+
type: type,
|
71
|
+
ruby_version: `$SHELL -l -c 'cd #{path} && ruby -e "puts RUBY_VERSION"'`.strip,
|
72
|
+
bundler_version: `$SHELL -l -c 'cd #{path} && bundle -v'`.split.last,
|
73
|
+
port: (type == "rails" ? 3000 : 9292) # :'(
|
74
|
+
}.tap do |spec|
|
75
|
+
if type == "rails"
|
76
|
+
spec[:nginx] = {
|
77
|
+
root: "/opt/app/public",
|
78
|
+
try_files: true,
|
79
|
+
proxy_redirect: "off"
|
80
|
+
}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
elsif Dir["#{path}/package.json"].any?
|
84
|
+
tmpfile = "#{Dir.tmpdir}/vps-debug.log"
|
85
|
+
pid = spawn("cd #{path} && npm start", :out => tmpfile, :err => "/dev/null")
|
86
|
+
Process.detach(pid)
|
87
|
+
sleep 5
|
88
|
+
`ps aux | grep -e "no[d]e #{path}"`.strip.split("\n").collect do |line|
|
89
|
+
`kill -9 #{line.split(" ")[1]}`
|
90
|
+
end
|
91
|
+
port = File.read(tmpfile).match(/on port (\d+)/).captures.first.to_i
|
92
|
+
{
|
93
|
+
type: "node",
|
94
|
+
node_version: `$SHELL -l -c 'cd #{path} && node -v'`.match(/[\d\.?]+/).to_s,
|
95
|
+
port: port
|
96
|
+
}
|
81
97
|
end
|
82
98
|
end
|
83
99
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class OpenStruct
|
2
|
+
def self.to_hash(object, hash = {})
|
3
|
+
case object
|
4
|
+
when OpenStruct then
|
5
|
+
object.each_pair do |key, value|
|
6
|
+
hash[key.to_s] = to_hash(value)
|
7
|
+
end
|
8
|
+
hash
|
9
|
+
when Array then
|
10
|
+
object.collect do |value|
|
11
|
+
to_hash(value)
|
12
|
+
end
|
13
|
+
else
|
14
|
+
object
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/vps/version.rb
CHANGED
data/playbooks/deploy/docker.yml
CHANGED
@@ -86,11 +86,11 @@ tasks:
|
|
86
86
|
command:
|
87
87
|
- chmod +x {{ release_path }}/init-letsencrypt/{{ upstream.name }}.sh
|
88
88
|
- cd {{ release_path }} && if [ ! -d "data/certbot/conf/live/{{ domain:upstream }}" ]; then yes Y | sudo ./init-letsencrypt/{{ upstream.name }}.sh; fi
|
89
|
-
- task: run_tasks
|
90
|
-
tasks: << postload >>
|
91
89
|
- description: Starting containers
|
92
90
|
task: remote_execute
|
93
91
|
command: cd {{ release_path }} && docker-compose up {{ up }} -d
|
94
92
|
- description: Checking running docker images
|
95
93
|
task: remote_execute
|
96
94
|
command: docker ps
|
95
|
+
- task: run_tasks
|
96
|
+
tasks: << postload >>
|
@@ -3,19 +3,26 @@
|
|
3
3
|
upstream <%= upstream[:name] %> {
|
4
4
|
server <%= upstream[:name] %>:<%= upstream[:port] %>;
|
5
5
|
}
|
6
|
-
<%- upstream[:domains].partition{|domain| domain.include?("http://")}.reject(&:empty?).each do |domains| %>
|
6
|
+
<%- (upstream[:domains] || []).partition{|domain| domain.include?("http://")}.reject(&:empty?).each do |domains| %>
|
7
7
|
<%-
|
8
8
|
https = domains.first.include?("https://")
|
9
9
|
domains = domains.collect{|domain| domain.gsub(/https?:\/\//, "")}.join(" ")
|
10
10
|
domain = domains.split(" ")[0]
|
11
|
+
nginx = upstream[:nginx] || {}
|
11
12
|
proxy_pass = "http://#{ upstream[:name] }"
|
12
13
|
%>
|
13
14
|
|
14
15
|
server {
|
16
|
+
<%- unless domains.empty? %>
|
15
17
|
listen 80;
|
16
18
|
server_name <%= domains %>;
|
17
19
|
server_tokens off;
|
18
20
|
|
21
|
+
<%- end %>
|
22
|
+
<%- if nginx[:http] %>
|
23
|
+
<%= nginx[:http].gsub("PROXY_PASS", proxy_pass).indent(2) %>
|
24
|
+
|
25
|
+
<%- end %>
|
19
26
|
<%- if https %>
|
20
27
|
location /.well-known/acme-challenge/ {
|
21
28
|
root /var/www/certbot;
|
@@ -37,15 +44,25 @@ server {
|
|
37
44
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
|
38
45
|
|
39
46
|
<%- end %>
|
40
|
-
<%- if
|
41
|
-
<%=
|
47
|
+
<%- if nginx[:root] %>
|
48
|
+
root <%= nginx[:root] %>;
|
49
|
+
<%- end %>
|
50
|
+
<%- if nginx[:try_files] %>
|
51
|
+
try_files $uri @app;
|
42
52
|
|
43
53
|
<%- end %>
|
44
|
-
|
54
|
+
<%- if nginx[:https] %>
|
55
|
+
<%= nginx[:https].gsub("PROXY_PASS", proxy_pass).indent(2) %>
|
56
|
+
|
57
|
+
<%- end %>
|
58
|
+
location <%= nginx[:try_files] ? "@app" : "/" %> {
|
45
59
|
proxy_pass <%= proxy_pass %>;
|
46
60
|
proxy_set_header Host $http_host;
|
47
61
|
proxy_set_header X-Real-IP $remote_addr;
|
48
62
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
63
|
+
<%- if nginx[:proxy_redirect] %>
|
64
|
+
proxy_redirect <%= nginx[:proxy_redirect] %>;
|
65
|
+
<%- end %>
|
49
66
|
}
|
50
67
|
}
|
51
68
|
<%- end %>
|
@@ -1,10 +1,5 @@
|
|
1
1
|
version: "3"
|
2
|
-
<%
|
3
|
-
https = upstreams.any?{|upstream| upstream[:domains].any?{|domain| domain.include?("https://")}}
|
4
|
-
to_yaml = proc do |struct|
|
5
|
-
struct.to_h.inject({}){|h, (k, v)| h[k.to_s] = v; h}.to_yaml
|
6
|
-
end
|
7
|
-
%>
|
2
|
+
<% https = upstreams.any?{|upstream| upstream[:domains].any?{|domain| domain.include?("https://")}} %>
|
8
3
|
services:
|
9
4
|
|
10
5
|
nginx:
|
@@ -28,7 +23,7 @@ services:
|
|
28
23
|
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
|
29
24
|
|
30
25
|
certbot:
|
31
|
-
image: certbot/certbot
|
26
|
+
image: certbot/certbot:v0.27.1
|
32
27
|
container_name: certbot
|
33
28
|
restart: unless-stopped
|
34
29
|
volumes:
|
@@ -36,21 +31,29 @@ services:
|
|
36
31
|
- ./data/certbot/www:/var/www/certbot
|
37
32
|
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
|
38
33
|
<%- end %>
|
34
|
+
<%- services.to_h.each do |name, spec| %>
|
35
|
+
|
36
|
+
<%= name %>:
|
37
|
+
<%= OpenStruct.to_hash(spec).to_yaml.sub(/^.*?\n/, "").sub("\n", "\ncontainer_name: #{name}\n").indent(4) %>
|
38
|
+
<%- end %>
|
39
39
|
<%- upstreams.each do |upstream| %>
|
40
40
|
|
41
41
|
<%= upstream.name %>:
|
42
42
|
image: <%= upstream.name %>
|
43
|
+
container_name: <%= upstream.name %>
|
43
44
|
restart: always
|
44
45
|
<%- unless upstream[:compose].inspect.match(/\bports\b/) %>
|
45
46
|
ports:
|
46
47
|
- <%= upstream.port %>
|
47
48
|
<%- end %>
|
48
49
|
<%- if upstream[:compose] %>
|
49
|
-
<%=
|
50
|
+
<%= OpenStruct.to_hash(upstream[:compose]).to_yaml.sub(/^.*?\n/, "").indent(4) %>
|
50
51
|
<%- end %>
|
51
52
|
<%- end %>
|
52
|
-
|
53
|
+
<%- unless (volumes || []).empty? %>
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
55
|
+
volumes:
|
56
|
+
<%- volumes.each do |volume| %>
|
57
|
+
<%= volume %>:
|
58
|
+
<%- end %>
|
59
|
+
<%- end %>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
FROM node:<%= upstream.node_version %>-alpine
|
2
|
+
|
3
|
+
RUN apk update \
|
4
|
+
&& apk --no-cache --update add \
|
5
|
+
build-base nodejs tzdata
|
6
|
+
|
7
|
+
WORKDIR /opt/app
|
8
|
+
COPY . .
|
9
|
+
|
10
|
+
ENV NODE_ENV=production
|
11
|
+
<%- if upstream.dockerfile %>
|
12
|
+
<%= upstream.dockerfile.strip %>
|
13
|
+
<%- end %>
|
14
|
+
RUN npm install
|
15
|
+
CMD ["npm", "start"]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
FROM elixir:<%= upstream.
|
1
|
+
FROM elixir:<%= upstream.elixir_version %>-alpine
|
2
2
|
|
3
3
|
RUN apk update \
|
4
4
|
&& apk --no-cache --update add alpine-sdk \
|
@@ -9,5 +9,8 @@ WORKDIR /opt/app
|
|
9
9
|
COPY . .
|
10
10
|
|
11
11
|
ENV MIX_ENV=prod
|
12
|
+
<%- if upstream.dockerfile %>
|
13
|
+
<%= upstream.dockerfile.strip %>
|
14
|
+
<%- end %>
|
12
15
|
RUN mix do deps.get --only prod, deps.compile
|
13
16
|
CMD ["sh", "-c", "mix phx.server"]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
FROM elixir:<%= upstream.
|
1
|
+
FROM elixir:<%= upstream.elixir_version %>-alpine
|
2
2
|
|
3
3
|
RUN apk update \
|
4
4
|
&& apk --no-cache --update add alpine-sdk \
|
@@ -9,5 +9,8 @@ WORKDIR /opt/app
|
|
9
9
|
COPY . .
|
10
10
|
|
11
11
|
ENV MIX_ENV=prod
|
12
|
+
<%- if upstream.dockerfile %>
|
13
|
+
<%= upstream.dockerfile.strip %>
|
14
|
+
<%- end %>
|
12
15
|
RUN mix do deps.get --only prod, deps.compile
|
13
16
|
CMD ["sh", "-c", "mix run --no-halt"]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
FROM ruby:<%= upstream.
|
1
|
+
FROM ruby:<%= upstream.ruby_version %>-alpine
|
2
2
|
|
3
3
|
RUN apk update \
|
4
4
|
&& apk --no-cache --update add \
|
@@ -11,5 +11,9 @@ WORKDIR /opt/app
|
|
11
11
|
COPY . .
|
12
12
|
|
13
13
|
ENV RACK_ENV=production
|
14
|
+
<%- if upstream.dockerfile %>
|
15
|
+
<%= upstream.dockerfile.strip %>
|
16
|
+
<%- end %>
|
17
|
+
RUN gem install bundler -v <%= upstream.bundler_version %>
|
14
18
|
RUN bundle install --without development test
|
15
|
-
CMD ["rackup", "config.ru", "-o", "0.0.0.0"]
|
19
|
+
CMD ["bundle", "exec", "rackup", "config.ru", "-o", "0.0.0.0"]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
FROM ruby:<%= upstream.
|
1
|
+
FROM ruby:<%= upstream.ruby_version %>-alpine
|
2
2
|
|
3
3
|
RUN apk update \
|
4
4
|
&& apk --no-cache --update add \
|
@@ -10,6 +10,13 @@ RUN apk update \
|
|
10
10
|
WORKDIR /opt/app
|
11
11
|
COPY . .
|
12
12
|
|
13
|
+
EXPOSE <%= upstream.port %>
|
14
|
+
|
13
15
|
ENV RAILS_ENV=production
|
16
|
+
<%- if upstream.dockerfile %>
|
17
|
+
<%= upstream.dockerfile.strip %>
|
18
|
+
<%- end %>
|
19
|
+
RUN gem install bundler -v <%= upstream.bundler_version %>
|
14
20
|
RUN bundle install --without development test
|
21
|
+
CMD ["rm", "-f", "tmp/pids/server.pid"]
|
15
22
|
CMD ["rails", "server", "-b", "0.0.0.0"]
|
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/bin/bash
|
2
2
|
|
3
|
-
<%- if (domains = upstream[:domains].collect{|domain| domain.dup.gsub!("https://", "")}.compact).any? %>
|
3
|
+
<%- if (domains = (upstream[:domains] || []).collect{|domain| domain.dup.gsub!("https://", "")}.compact).any? %>
|
4
4
|
domains=(<%= domains.join(" ") %>)
|
5
5
|
email="<%= upstream[:email] || "noreply@#{domains.first}" %>" # Adding a valid address is strongly recommended
|
6
6
|
data_path="./data/certbot"
|
@@ -17,8 +17,8 @@ fi
|
|
17
17
|
if [ ! -e "$data_path/conf/options-ssl-nginx.conf" ] || [ ! -e "$data_path/conf/ssl-dhparams.pem" ]; then
|
18
18
|
echo "### Downloading recommended TLS parameters ..."
|
19
19
|
mkdir -p "$data_path/conf"
|
20
|
-
curl -s https://raw.githubusercontent.com/certbot/certbot/
|
21
|
-
curl -s https://raw.githubusercontent.com/certbot/certbot/
|
20
|
+
curl -s https://raw.githubusercontent.com/certbot/certbot/v0.40.1/certbot-nginx/certbot_nginx/tls_configs/options-ssl-nginx.conf > "$data_path/conf/options-ssl-nginx.conf"
|
21
|
+
curl -s https://raw.githubusercontent.com/certbot/certbot/v0.40.1/certbot/ssl-dhparams.pem > "$data_path/conf/ssl-dhparams.pem"
|
22
22
|
echo
|
23
23
|
fi
|
24
24
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: vps
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Paul Engel
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: thor
|
@@ -162,6 +162,7 @@ files:
|
|
162
162
|
- lib/vps/cli/playbook/tasks.rb
|
163
163
|
- lib/vps/cli/service.rb
|
164
164
|
- lib/vps/cli/upstream.rb
|
165
|
+
- lib/vps/core_ext/ostruct.rb
|
165
166
|
- lib/vps/core_ext/string.rb
|
166
167
|
- lib/vps/version.rb
|
167
168
|
- playbooks/deploy.yml
|
@@ -173,6 +174,7 @@ files:
|
|
173
174
|
- script/console
|
174
175
|
- templates/docker/data/nginx/app.conf.erb
|
175
176
|
- templates/docker/docker-compose.yml.erb
|
177
|
+
- templates/docker/upstream/Dockerfile.node.erb
|
176
178
|
- templates/docker/upstream/Dockerfile.phoenix.erb
|
177
179
|
- templates/docker/upstream/Dockerfile.plug.erb
|
178
180
|
- templates/docker/upstream/Dockerfile.rack.erb
|