contur 0.0.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 +7 -0
- data/.editorconfig +15 -0
- data/.gitignore +14 -0
- data/.rspec +2 -0
- data/.rubocop.yml +19 -0
- data/.travis.yml +5 -0
- data/CHANGELOG.md +17 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +5 -0
- data/LICENSE.txt +21 -0
- data/README.md +166 -0
- data/Rakefile +9 -0
- data/bin/console +8 -0
- data/bin/contur +172 -0
- data/bin/setup +8 -0
- data/contur-logo.png +0 -0
- data/contur.gemspec +40 -0
- data/lib/contur/bindable_hash.rb +16 -0
- data/lib/contur/config/before.rb +30 -0
- data/lib/contur/config/env.rb +29 -0
- data/lib/contur/config/errors.rb +7 -0
- data/lib/contur/config/use.rb +41 -0
- data/lib/contur/config/version.rb +34 -0
- data/lib/contur/config.rb +74 -0
- data/lib/contur/constants.rb +25 -0
- data/lib/contur/controller.rb +227 -0
- data/lib/contur/utils.rb +42 -0
- data/lib/contur/version.rb +4 -0
- data/lib/contur.rb +8 -0
- data/templates/base-docker-container.erb +104 -0
- data/templates/init.sh.erb +19 -0
- metadata +216 -0
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'contur/constants'
|
4
|
+
|
5
|
+
module Contur
|
6
|
+
class Config
|
7
|
+
# Use section
|
8
|
+
class Use < Hash
|
9
|
+
DEFAULTS ||= {
|
10
|
+
'php' => Contur::DEFAULT_PHP_VERSION,
|
11
|
+
'mysql' => Contur::DEFAULT_MYSQL_VERSION
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
ALLOWED_VALUES ||= DEFAULTS.keys
|
15
|
+
|
16
|
+
def initialize(using = {})
|
17
|
+
super
|
18
|
+
replace(DEFAULTS)
|
19
|
+
|
20
|
+
validate!(using)
|
21
|
+
|
22
|
+
merge!(using) unless using.nil?
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate!(using)
|
26
|
+
@errors = []
|
27
|
+
return unless using.respond_to? :keys
|
28
|
+
extra_keys = using.keys - ALLOWED_VALUES
|
29
|
+
extra_keys.each do |key|
|
30
|
+
@errors << "Unknown key: #{key}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
attr_reader :errors
|
35
|
+
|
36
|
+
def name
|
37
|
+
"Section 'use'"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Contur
|
3
|
+
class Config
|
4
|
+
# Version section
|
5
|
+
class Version
|
6
|
+
ALLOWED_VALUES ||= [1.0].freeze
|
7
|
+
|
8
|
+
# version is required so no default value
|
9
|
+
def initialize(version)
|
10
|
+
validate!(version)
|
11
|
+
@yaml_version = version
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
@yaml_version.to_s
|
16
|
+
end
|
17
|
+
|
18
|
+
def validate!(version)
|
19
|
+
@errors = []
|
20
|
+
if version.nil?
|
21
|
+
@errors << 'Required'
|
22
|
+
return
|
23
|
+
end
|
24
|
+
@errors << "Unknown value: '#{version}'" unless ALLOWED_VALUES.include? version
|
25
|
+
end
|
26
|
+
|
27
|
+
attr_reader :errors
|
28
|
+
|
29
|
+
def name
|
30
|
+
"Section 'version'"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'contur/config/before'
|
3
|
+
require 'contur/config/env'
|
4
|
+
require 'contur/config/errors'
|
5
|
+
require 'contur/config/use'
|
6
|
+
require 'contur/config/version'
|
7
|
+
|
8
|
+
require 'yaml'
|
9
|
+
|
10
|
+
module Contur
|
11
|
+
# Build configuration object
|
12
|
+
class Config
|
13
|
+
attr_reader :path, :raw, :version, :use, :env, :before
|
14
|
+
|
15
|
+
def initialize(path_to_config)
|
16
|
+
begin
|
17
|
+
@path = path_to_config
|
18
|
+
build_config = YAML.load_file(path_to_config)
|
19
|
+
rescue Errno::ENOENT
|
20
|
+
raise Contur::Config::NotFoundError, "'#{path_to_config}': file not found"
|
21
|
+
end
|
22
|
+
|
23
|
+
@errors = []
|
24
|
+
unless build_config
|
25
|
+
@errors << 'Build file is empty'
|
26
|
+
return
|
27
|
+
end
|
28
|
+
|
29
|
+
@raw = build_config
|
30
|
+
@version = Version.new(build_config['version'])
|
31
|
+
@use = Use.new(build_config['use'])
|
32
|
+
@env = Env.new(build_config['env'])
|
33
|
+
@before = Before.new(build_config['before'])
|
34
|
+
end
|
35
|
+
|
36
|
+
def init_script
|
37
|
+
unless @init_script
|
38
|
+
generation_time = "echo \"Generated at: [#{Time.now}]\"\n\n"
|
39
|
+
env_script = @env.to_bash_script
|
40
|
+
before_script = @before.to_bash_script
|
41
|
+
@init_script = generation_time + env_script + before_script
|
42
|
+
end
|
43
|
+
@init_script
|
44
|
+
end
|
45
|
+
|
46
|
+
def errors
|
47
|
+
all_errors = Array.new(@errors)
|
48
|
+
|
49
|
+
instance_variables.each do |var|
|
50
|
+
section = instance_variable_get(var)
|
51
|
+
next unless section.respond_to?(:name) && section.respond_to?(:errors)
|
52
|
+
section_name = section.send(:name)
|
53
|
+
section_errors = section.send(:errors)
|
54
|
+
section_errors.each do |err|
|
55
|
+
all_errors << "#{section_name}: #{err}"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
all_errors
|
60
|
+
end
|
61
|
+
|
62
|
+
def inspect
|
63
|
+
data = []
|
64
|
+
instance_variables.each do |var|
|
65
|
+
section = instance_variable_get(var)
|
66
|
+
if section.respond_to?(:name)
|
67
|
+
section_name = section.send(:name)
|
68
|
+
data << "#{section_name}: #{section.inspect}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
data.join("\n")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
# Contur main module
|
6
|
+
module Contur
|
7
|
+
GEM_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '../../'))
|
8
|
+
TEMPLATE_DIR = "#{Contur::GEM_ROOT}/templates"
|
9
|
+
DEFAULT_DOMAIN = 'cheppers.com'
|
10
|
+
|
11
|
+
IMAGE_NAME ||= 'contur'
|
12
|
+
DOCKER_DIR ||= 'docker'
|
13
|
+
DEFAULT_PHP_VERSION = '5.6'
|
14
|
+
DEFAULT_MYSQL_VERSION = 'latest'
|
15
|
+
|
16
|
+
DEFAULT_OPTS ||= {
|
17
|
+
refreshed_at_date: ::Date.today.strftime('%Y-%m-%d'),
|
18
|
+
php_timezone: 'Europe/Budapest',
|
19
|
+
php_memory_limit: '256M',
|
20
|
+
max_upload: '50M',
|
21
|
+
php_max_file_upload: 200,
|
22
|
+
php_max_post: '100M',
|
23
|
+
extra_files: Contur::TEMPLATE_DIR
|
24
|
+
}.freeze
|
25
|
+
end
|
@@ -0,0 +1,227 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'docker-api'
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
require 'contur/bindable_hash'
|
6
|
+
require 'contur/config'
|
7
|
+
require 'contur/utils'
|
8
|
+
|
9
|
+
# rubocop:disable Metrics/ClassLength, Lint/AssignmentInCondition
|
10
|
+
|
11
|
+
# Contur main module
|
12
|
+
module Contur
|
13
|
+
# Contur::Controller
|
14
|
+
class Controller
|
15
|
+
# rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity
|
16
|
+
def self.config(path_to_config = nil)
|
17
|
+
# rubocop:disable Style/ClassVars
|
18
|
+
@@config ||= nil
|
19
|
+
|
20
|
+
unless @@config
|
21
|
+
@@config = if path_to_config.nil?
|
22
|
+
config_file_name = Dir['.contur.y*ml'].first
|
23
|
+
Contur::Config.new(File.join(Dir.pwd, config_file_name))
|
24
|
+
else
|
25
|
+
Contur::Config.new(path_to_config)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
@@config
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.image_exist?
|
32
|
+
Docker::Image.exist? Contur::IMAGE_NAME
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.container?
|
36
|
+
Docker::Container.all(
|
37
|
+
'filters' => { 'ancestor' => [Contur::IMAGE_NAME] }.to_json, 'all' => true
|
38
|
+
).first
|
39
|
+
rescue
|
40
|
+
nil
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.promote
|
44
|
+
puts '!!! WIP !!!'
|
45
|
+
puts "FQDN: #{Contur::Utils.fqdn}"
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.build
|
49
|
+
template = load_docker_template(
|
50
|
+
'base-docker-container',
|
51
|
+
php_memory_limit: '128M'
|
52
|
+
)
|
53
|
+
|
54
|
+
docker_context = generate_docker_archive(template)
|
55
|
+
|
56
|
+
Docker::Image.build_from_tar(docker_context, t: Contur::IMAGE_NAME) do |r|
|
57
|
+
r.each_line do |log|
|
58
|
+
if (message = JSON.parse(log)) && message.key?('stream')
|
59
|
+
yield message['stream'] if block_given?
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# rubocop:disable Metrics/PerceivedComplexity, Lint/UnusedMethodArgument, Metrics/MethodLength
|
66
|
+
def self.run(config_path: nil, webroot: nil, initscripts: nil)
|
67
|
+
unless image_exist?
|
68
|
+
yield "Image doesn't exist" if block_given?
|
69
|
+
return false
|
70
|
+
end
|
71
|
+
|
72
|
+
bind_volumes = []
|
73
|
+
|
74
|
+
if !webroot.nil? && Dir.exist?(File.expand_path(webroot))
|
75
|
+
bind_volumes << "#{webroot}:/www"
|
76
|
+
end
|
77
|
+
if !initscripts.nil? && Dir.exist?(File.expand_path(initscripts))
|
78
|
+
bind_volumes << "#{initscripts}:/initscripts"
|
79
|
+
end
|
80
|
+
|
81
|
+
if c = container?
|
82
|
+
yield 'Removing existing contur container...' if block_given?
|
83
|
+
c.remove(force: true)
|
84
|
+
end
|
85
|
+
|
86
|
+
mysql_container_version = "mysql:#{config.use['mysql']}"
|
87
|
+
unless Docker::Image.exist? mysql_container_version
|
88
|
+
yield "Downloading #{mysql_container_version}..." if block_given?
|
89
|
+
Docker::Image.create('fromImage' => mysql_container_version)
|
90
|
+
end
|
91
|
+
|
92
|
+
mysql_container_name = mysql_container_version.tr(':.', '_')
|
93
|
+
|
94
|
+
stop_mysql_containers(except: mysql_container_version)
|
95
|
+
begin
|
96
|
+
mysql_container = Docker::Container.get(mysql_container_name)
|
97
|
+
rescue Docker::Error::NotFoundError
|
98
|
+
yield 'Creating MySQL container...' if block_given?
|
99
|
+
mysql_container = Docker::Container.create(
|
100
|
+
'name' => mysql_container_name,
|
101
|
+
'Image' => mysql_container_version,
|
102
|
+
'Env' => ['MYSQL_ROOT_PASSWORD=admin']
|
103
|
+
)
|
104
|
+
ensure
|
105
|
+
mysql_container_info = Docker::Container.get(mysql_container.id).info
|
106
|
+
unless mysql_container_info['State']['Running']
|
107
|
+
yield 'Starting MySQL container...' if block_given?
|
108
|
+
mysql_container.start!
|
109
|
+
sleep 10
|
110
|
+
end
|
111
|
+
end
|
112
|
+
mysql_container_info = Docker::Container.get(mysql_container.id).info
|
113
|
+
unless mysql_container_info['State']['Running']
|
114
|
+
yield "Couldn't start MySQL container" if block_given?
|
115
|
+
return false
|
116
|
+
end
|
117
|
+
yield "MySQL container: #{mysql_container.id[0, 10]}" if block_given?
|
118
|
+
|
119
|
+
yield 'Creating Contur container...' if block_given?
|
120
|
+
container = Docker::Container.create(
|
121
|
+
'name' => Contur::Utils.generate_conatiner_name,
|
122
|
+
'Image' => Contur::IMAGE_NAME,
|
123
|
+
'Cmd' => ['/init.sh'],
|
124
|
+
'Volumes' => {
|
125
|
+
"#{Dir.pwd}/webroot" => {},
|
126
|
+
"#{Dir.pwd}/initscripts" => {}
|
127
|
+
},
|
128
|
+
'ExposedPorts' => {
|
129
|
+
'80/tcp' => {}
|
130
|
+
},
|
131
|
+
'HostConfig' => {
|
132
|
+
'Links' => ["#{mysql_container_name}:mysql"],
|
133
|
+
'PortBindings' => {
|
134
|
+
'80/tcp' => [{ 'HostPort' => '8088' }]
|
135
|
+
},
|
136
|
+
'Binds' => bind_volumes
|
137
|
+
}
|
138
|
+
)
|
139
|
+
|
140
|
+
container.store_file('/init.sh', content: load_init_script, permissions: 0o777)
|
141
|
+
|
142
|
+
container.start!
|
143
|
+
end
|
144
|
+
|
145
|
+
def self.delete_container
|
146
|
+
if c = container?
|
147
|
+
c.delete(force: true)
|
148
|
+
true
|
149
|
+
else
|
150
|
+
false
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
def self.container_id
|
155
|
+
return nil unless c = container?
|
156
|
+
c.id[0, 10]
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.container_logs
|
160
|
+
return nil unless c = container?
|
161
|
+
c.logs(stdout: true)
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.delete_image
|
165
|
+
return nil unless image_exist?
|
166
|
+
image = Docker::Image.get Contur::IMAGE_NAME
|
167
|
+
image.remove(force: true)
|
168
|
+
end
|
169
|
+
|
170
|
+
def self.mysql_containers
|
171
|
+
Docker::Container.all.select { |c| c.info['Image'].start_with?('mysql') }
|
172
|
+
end
|
173
|
+
|
174
|
+
def self.delete_mysql_containers
|
175
|
+
if mysql_containers.empty?
|
176
|
+
false
|
177
|
+
else
|
178
|
+
mysql_containers.each { |c| c.delete(force: true) }
|
179
|
+
true
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def self.stop_mysql_containers(except: "\n")
|
184
|
+
mysql_containers.select { |c| !c.info['Image'].end_with?(except) }.each(&:stop)
|
185
|
+
end
|
186
|
+
|
187
|
+
private_class_method
|
188
|
+
|
189
|
+
def self.load_docker_template(template_name, opts = {})
|
190
|
+
opts = Contur::DEFAULT_OPTS.merge(opts)
|
191
|
+
|
192
|
+
context = BindableHash.new opts
|
193
|
+
::ERB.new(
|
194
|
+
File.read("#{Contur::TEMPLATE_DIR}/#{template_name}.erb")
|
195
|
+
).result(context.get_binding)
|
196
|
+
end
|
197
|
+
|
198
|
+
def self.load_init_script
|
199
|
+
context = BindableHash.new(before_script: config.init_script)
|
200
|
+
::ERB.new(
|
201
|
+
File.read("#{Contur::TEMPLATE_DIR}/init.sh.erb")
|
202
|
+
).result(context.get_binding)
|
203
|
+
end
|
204
|
+
|
205
|
+
def self.generate_docker_archive(dockerfile_content)
|
206
|
+
tar = StringIO.new
|
207
|
+
|
208
|
+
Gem::Package::TarWriter.new(tar) do |writer|
|
209
|
+
writer.add_file('Dockerfile', 0o644) { |f| f.write(dockerfile_content) }
|
210
|
+
end
|
211
|
+
|
212
|
+
compress_archive(tar)
|
213
|
+
end
|
214
|
+
|
215
|
+
def self.compress_archive(tar)
|
216
|
+
tar.seek(0)
|
217
|
+
gz = StringIO.new(String.new, 'r+b').set_encoding(Encoding::BINARY)
|
218
|
+
gz_writer = Zlib::GzipWriter.new(gz)
|
219
|
+
gz_writer.write(tar.read)
|
220
|
+
tar.close
|
221
|
+
gz_writer.finish
|
222
|
+
gz.rewind
|
223
|
+
|
224
|
+
gz
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
data/lib/contur/utils.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
module Contur
|
3
|
+
# Utils class
|
4
|
+
class Utils
|
5
|
+
def self.generate_conatiner_name(prefix: nil, job_name: nil, build_id: nil)
|
6
|
+
prefix ||= ENV['CONTAINER_PREFIX']
|
7
|
+
prefix = "#{prefix}-" unless prefix.nil? || prefix.empty?
|
8
|
+
|
9
|
+
job_name ||= ENV['JOB_NAME'] || random_string
|
10
|
+
build_id ||= ENV['BUILD_ID'] || "r#{Random.rand(1000)}"
|
11
|
+
|
12
|
+
"#{prefix}#{job_name}-#{build_id}"
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.virtual_hostname(prefix: nil, job_name: nil, branch_name: nil)
|
16
|
+
prefix ||= ENV['HOST_PREFIX']
|
17
|
+
prefix = "#{prefix}." unless prefix.nil? || prefix.empty?
|
18
|
+
|
19
|
+
job_name ||= ENV['JOB_NAME'] || random_string.downcase
|
20
|
+
branch_name ||= (ENV['BRANCH_NAME'] || 'master').gsub(%r{.*/}, '')
|
21
|
+
|
22
|
+
"#{prefix}#{branch_name}.#{job_name}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.fqdn(prefix: nil, job_name: nil, branch_name: nil)
|
26
|
+
vhost = virtual_hostname(
|
27
|
+
prefix: prefix,
|
28
|
+
job_name: job_name,
|
29
|
+
branch_name: branch_name
|
30
|
+
)
|
31
|
+
|
32
|
+
main_domain = ENV['DOMAIN'] || Contur::DEFAULT_DOMAIN
|
33
|
+
|
34
|
+
"#{vhost}.#{main_domain}"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.random_string(length: 8)
|
38
|
+
o = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
|
39
|
+
(0...length).map { o[rand(o.length)] }.join
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
data/lib/contur.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
FROM alpine:3.3
|
2
|
+
|
3
|
+
MAINTAINER 'Cheppers Ltd. <info@cheppers.com> (github:Cheppers)'
|
4
|
+
|
5
|
+
ENV REFRESHED_AT <%= refreshed_at_date %>
|
6
|
+
|
7
|
+
# PHP Configuration
|
8
|
+
ENV TIMEZONE <%= php_timezone %>
|
9
|
+
ENV PHP_MEMORY_LIMIT <%= php_memory_limit %>
|
10
|
+
ENV MAX_UPLOAD <%= max_upload %>
|
11
|
+
ENV PHP_MAX_FILE_UPLOAD <%= php_max_file_upload %>
|
12
|
+
ENV PHP_MAX_POST <%= php_max_post %>
|
13
|
+
ENV TERM dumb # for mysql-client
|
14
|
+
|
15
|
+
# Install packages
|
16
|
+
RUN apk add --no-cache \
|
17
|
+
bash \
|
18
|
+
apache2-proxy apache2-utils \
|
19
|
+
mysql-client \
|
20
|
+
tzdata \
|
21
|
+
php-mcrypt \
|
22
|
+
php-soap \
|
23
|
+
php-openssl \
|
24
|
+
php-gmp \
|
25
|
+
php-pdo_odbc \
|
26
|
+
php-json \
|
27
|
+
php-dom \
|
28
|
+
php-pdo \
|
29
|
+
php-zip \
|
30
|
+
php-mysql \
|
31
|
+
php-sqlite3 \
|
32
|
+
php-apcu \
|
33
|
+
php-pdo_pgsql \
|
34
|
+
php-bcmath \
|
35
|
+
php-gd \
|
36
|
+
php-xcache \
|
37
|
+
php-odbc \
|
38
|
+
php-pdo_mysql \
|
39
|
+
php-pdo_sqlite \
|
40
|
+
php-gettext \
|
41
|
+
php-xmlreader \
|
42
|
+
php-xmlrpc \
|
43
|
+
php-bz2 \
|
44
|
+
php-memcache \
|
45
|
+
php-mssql \
|
46
|
+
php-iconv \
|
47
|
+
php-pdo_dblib \
|
48
|
+
php-curl \
|
49
|
+
php-ctype \
|
50
|
+
php-phar \
|
51
|
+
php-fpm
|
52
|
+
|
53
|
+
# Configure apache proxy (apache because of `.ht` files)
|
54
|
+
RUN echo \
|
55
|
+
'ProxyPassMatch ^/(.*\.php(/.*)?)$ fcgi://127.0.0.1:9000/www/$1' >> /etc/apache2/httpd.conf && \
|
56
|
+
echo 'DirectoryIndex /index.php' >> /etc/apache2/httpd.conf && \
|
57
|
+
sed -ie 's/#ServerName .*/ServerName localhost/i' /etc/apache2/httpd.conf && \
|
58
|
+
sed -ie 's/#LoadModule slotmem_shm_module/LoadModule slotmem_shm_module/' \
|
59
|
+
/etc/apache2/httpd.conf && \
|
60
|
+
sed -ie 's#/var/www/localhost/htdocs#/www#g' /etc/apache2/httpd.conf && \
|
61
|
+
sed -ie 's#LoadModule proxy_fdpass_module modules/mod_proxy_fdpass.so##g' /etc/apache2/conf.d/proxy.conf && \
|
62
|
+
mkdir /run/apache2/
|
63
|
+
|
64
|
+
# Configure Timezone, important for php
|
65
|
+
RUN cp /usr/share/zoneinfo/${TIMEZONE} /etc/localtime && \
|
66
|
+
echo "${TIMEZONE}" > /etc/timezone
|
67
|
+
|
68
|
+
# Configure PHP-FPM
|
69
|
+
RUN sed -i "s|;*daemonize\s*=\s*yes|daemonize = no|g" /etc/php/php-fpm.conf && \
|
70
|
+
sed -ie 's#^listen\s*=\s*.*#listen = 9000#g' \
|
71
|
+
/etc/php/php-fpm.conf && \
|
72
|
+
sed -i "s|;*date.timezone =.*|date.timezone = ${TIMEZONE}|i" \
|
73
|
+
/etc/php/php.ini && \
|
74
|
+
sed -i "s|;*memory_limit =.*|memory_limit = ${PHP_MEMORY_LIMIT}|i" \
|
75
|
+
/etc/php/php.ini && \
|
76
|
+
sed -i "s|;*upload_max_filesize =.*|upload_max_filesize = ${MAX_UPLOAD}|i" \
|
77
|
+
/etc/php/php.ini && \
|
78
|
+
sed -i "s|;*max_file_uploads =.*|max_file_uploads = ${PHP_MAX_FILE_UPLOAD}|i" \
|
79
|
+
/etc/php/php.ini && \
|
80
|
+
sed -i "s|;*post_max_size =.*|post_max_size = ${PHP_MAX_POST}|i" \
|
81
|
+
/etc/php/php.ini && \
|
82
|
+
sed -i "s|;*cgi.fix_pathinfo=.*|cgi.fix_pathinfo= 0|i" /etc/php/php.ini
|
83
|
+
|
84
|
+
# Install Composer
|
85
|
+
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" && \
|
86
|
+
php -r "if (hash_file('SHA384', 'composer-setup.php') === 'e115a8dc7871f15d853148a7fbac7da27d6c0030b848d9b3dc09e2a0388afed865e6a3d6b3c0fad45c48e2b5fc1196ae') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;" && \
|
87
|
+
php composer-setup.php --install-dir /usr/bin --filename=composer composer && \
|
88
|
+
php -r "unlink('composer-setup.php');" && \
|
89
|
+
chmod +x /usr/bin/composer
|
90
|
+
|
91
|
+
# Install Drush
|
92
|
+
RUN php -r "readfile('http://files.drush.org/drush.phar');" > /usr/local/bin/drush && \
|
93
|
+
php /usr/local/bin/drush core-status && \
|
94
|
+
chmod +x /usr/local/bin/drush
|
95
|
+
|
96
|
+
# Codebase
|
97
|
+
RUN mkdir /www
|
98
|
+
VOLUME ["/www"]
|
99
|
+
|
100
|
+
RUN mkdir /initscripts
|
101
|
+
|
102
|
+
WORKDIR /www
|
103
|
+
|
104
|
+
EXPOSE 80
|
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# ========== GENERATED SCRIPT ==========
|
4
|
+
<%= before_script %>
|
5
|
+
# ========== GENERATED SCRIPT ==========
|
6
|
+
|
7
|
+
echo "Run InitScripts"
|
8
|
+
find /initscripts -type f -print -exec {} \;
|
9
|
+
|
10
|
+
echo "Start Apache2"
|
11
|
+
/usr/sbin/httpd -d . -f /etc/apache2/httpd.conf
|
12
|
+
|
13
|
+
if [ ! -f /www/index.php ]; then
|
14
|
+
echo "Populate '/www' because it's empty"
|
15
|
+
echo '<?php phpinfo(); ?>' > /www/index.php
|
16
|
+
fi
|
17
|
+
|
18
|
+
echo "Start PHP-FPM"
|
19
|
+
/usr/bin/php-fpm
|