Skip to content

Commit deec6dc

Browse files
Merge pull request #12 from creode/feature/64-custom-webroot
WIP: Add custom webroot config variable for PHP container
2 parents 4bb14fb + 947651f commit deec6dc

5 files changed

Lines changed: 265 additions & 9 deletions

File tree

cdev.services.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
<argument type="service" id="symfony.filesystem" />
1818
</service>
1919

20-
<service id="cdev.docker_container_php"
21-
class="Cdev\Docker\Environment\Command\Container\Php">
20+
<service id="cdev.docker_container_php" class="Cdev\Docker\Environment\Command\Container\Php">
21+
<argument type="service" id="symfony.filesystem" />
2222
</service>
2323

2424
<service id="cdev.docker_container_mailcatcher"

src/Environment/Command/Container/Php.php

Lines changed: 91 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
<?php
22
namespace Cdev\Docker\Environment\Command\Container;
33

4+
use Symfony\Component\Filesystem\Filesystem;
5+
46
class Php extends Container
57
{
68
const COMMAND_NAME = 'container:php:configure';
@@ -12,6 +14,9 @@ class Php extends Container
1214
[
1315
'active' => true,
1416
'container_name' => 'project_php',
17+
'config-only' => [
18+
'relative_webroot_dir' => ''
19+
],
1520
'ports' => [
1621
'80:80'
1722
],
@@ -51,6 +56,13 @@ class Php extends Container
5156
]
5257
];
5358

59+
public function __construct(Filesystem $fs)
60+
{
61+
$this->_fs = $fs;
62+
63+
parent::__construct();
64+
}
65+
5466
protected function askQuestions()
5567
{
5668
$path = $this->_input->getOption('path');
@@ -89,6 +101,28 @@ protected function askQuestions()
89101

90102
$this->_config['environment']['VIRTUAL_HOST'] = '.' . $dockername . '.docker';
91103

104+
if ($volumeName) {
105+
$this->_config['volumes'] = [$volumeName . ':/var/www/html:nocopy'];
106+
} else {
107+
$this->_config['volumes'] = ['../' . $src . ':/var/www/html'];
108+
}
109+
110+
$useCustomWebroot = isset($this->_config['config-only']['relative_webroot_dir'])
111+
&& strlen($this->_config['config-only']['relative_webroot_dir']) > 0
112+
? true
113+
: false;
114+
115+
$this->askYesNoQuestion(
116+
'Use custom webroot',
117+
$useCustomWebroot
118+
);
119+
120+
if ($useCustomWebroot) {
121+
$this->_editCustomWebroot();
122+
} else {
123+
$this->_config['config-only']['relative_webroot_dir'] = '';
124+
}
125+
92126
$editEnvironmentVariables = false;
93127

94128
$this->askYesNoQuestion(
@@ -101,12 +135,6 @@ protected function askQuestions()
101135
}
102136

103137
$this->_config['links'] = [];
104-
105-
if ($volumeName) {
106-
$this->_config['volumes'] = [$volumeName . ':/var/www/html:nocopy'];
107-
} else {
108-
$this->_config['volumes'] = ['../' . $src . ':/var/www/html'];
109-
}
110138
}
111139

112140
private function _editEnvironmentVariables()
@@ -178,4 +206,61 @@ private function _addEnvironmentVariables()
178206
// offer to add another
179207
$this->_addEnvironmentVariables();
180208
}
209+
210+
private function _editCustomWebroot()
211+
{
212+
$path = $this->_input->getOption('path');
213+
214+
$this->askQuestion(
215+
'What is the webroot directory, relative to `src` directory (e.g. web)',
216+
$this->_config['config-only']['relative_webroot_dir'],
217+
''
218+
);
219+
220+
$apacheConfigDirPath = 'config/apache';
221+
$absoluteApacheConfigDirPath = $path . '/' . $apacheConfigDirPath;
222+
223+
// generate apache config file
224+
if (!$this->_fs->exists($absoluteApacheConfigDirPath)) {
225+
$this->_fs->mkdir($absoluteApacheConfigDirPath, 0740);
226+
}
227+
228+
$this->_copyApacheTemplateFiles(
229+
['000-default.conf', 'default-ssl.conf'],
230+
$absoluteApacheConfigDirPath,
231+
["[CUSTOM_WEBROOT]" => $this->_config['config-only']['relative_webroot_dir']]
232+
);
233+
234+
// add volume to config
235+
$this->_config['volumes'][] = '../' . $apacheConfigDirPath . ':/etc/apache2/sites-available';
236+
}
237+
238+
/**
239+
* Copies apache templates to config dir, replaces config placeholders
240+
* with the configured details
241+
* @param array $filenames names of the files to copy
242+
* @param type $targetDirPath the location to copy the files to
243+
* @param array $stringReplacements the replacement text, using placeholder as the key
244+
* @return void
245+
*/
246+
private function _copyApacheTemplateFiles(
247+
array $filenames,
248+
$targetDirPath,
249+
array $stringReplacements
250+
) {
251+
foreach ($filenames as $filename) {
252+
$targetFilename = $targetDirPath . '/' . $filename;
253+
254+
$this->_fs->copy(__DIR__ . '/php/templates/' . $filename, $targetFilename);
255+
256+
$fileContents = file_get_contents($targetFilename);
257+
258+
foreach($stringReplacements as $original => $replacement) {
259+
$fileContents = str_replace($original, $replacement, $fileContents);
260+
}
261+
262+
file_put_contents($targetFilename, $fileContents);
263+
}
264+
}
265+
181266
}
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<VirtualHost *:80>
2+
# The ServerName directive sets the request scheme, hostname and port that
3+
# the server uses to identify itself. This is used when creating
4+
# redirection URLs. In the context of virtual hosts, the ServerName
5+
# specifies what hostname must appear in the request's Host: header to
6+
# match this virtual host. For the default virtual host (this file) this
7+
# value is not decisive as it is used as a last resort host regardless.
8+
# However, you must set it for any further virtual host explicitly.
9+
#ServerName www.example.com
10+
11+
ServerAdmin webmaster@localhost
12+
DocumentRoot /var/www/html/[CUSTOM_WEBROOT]
13+
14+
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
15+
# error, crit, alert, emerg.
16+
# It is also possible to configure the loglevel for particular
17+
# modules, e.g.
18+
#LogLevel info ssl:warn
19+
20+
ErrorLog ${APACHE_LOG_DIR}/error.log
21+
CustomLog ${APACHE_LOG_DIR}/access.log combined
22+
23+
# For most configuration files from conf-available/, which are
24+
# enabled or disabled at a global level, it is possible to
25+
# include a line for only one particular virtual host. For example the
26+
# following line enables the CGI configuration for this host only
27+
# after it has been globally disabled with "a2disconf".
28+
#Include conf-available/serve-cgi-bin.conf
29+
</VirtualHost>
30+
31+
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
<IfModule mod_ssl.c>
2+
<VirtualHost _default_:443>
3+
ServerAdmin webmaster@localhost
4+
5+
DocumentRoot /var/www/html/[CUSTOM_WEBROOT]
6+
7+
# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
8+
# error, crit, alert, emerg.
9+
# It is also possible to configure the loglevel for particular
10+
# modules, e.g.
11+
#LogLevel info ssl:warn
12+
13+
ErrorLog ${APACHE_LOG_DIR}/error.log
14+
CustomLog ${APACHE_LOG_DIR}/access.log combined
15+
16+
# For most configuration files from conf-available/, which are
17+
# enabled or disabled at a global level, it is possible to
18+
# include a line for only one particular virtual host. For example the
19+
# following line enables the CGI configuration for this host only
20+
# after it has been globally disabled with "a2disconf".
21+
#Include conf-available/serve-cgi-bin.conf
22+
23+
# SSL Engine Switch:
24+
# Enable/Disable SSL for this virtual host.
25+
SSLEngine on
26+
27+
# A self-signed (snakeoil) certificate can be created by installing
28+
# the ssl-cert package. See
29+
# /usr/share/doc/apache2/README.Debian.gz for more info.
30+
# If both key and certificate are stored in the same file, only the
31+
# SSLCertificateFile directive is needed.
32+
SSLCertificateFile /etc/ssl/certs/ssl-cert-snakeoil.pem
33+
SSLCertificateKeyFile /etc/ssl/private/ssl-cert-snakeoil.key
34+
35+
# Server Certificate Chain:
36+
# Point SSLCertificateChainFile at a file containing the
37+
# concatenation of PEM encoded CA certificates which form the
38+
# certificate chain for the server certificate. Alternatively
39+
# the referenced file can be the same as SSLCertificateFile
40+
# when the CA certificates are directly appended to the server
41+
# certificate for convinience.
42+
#SSLCertificateChainFile /etc/apache2/ssl.crt/server-ca.crt
43+
44+
# Certificate Authority (CA):
45+
# Set the CA certificate verification path where to find CA
46+
# certificates for client authentication or alternatively one
47+
# huge file containing all of them (file must be PEM encoded)
48+
# Note: Inside SSLCACertificatePath you need hash symlinks
49+
# to point to the certificate files. Use the provided
50+
# Makefile to update the hash symlinks after changes.
51+
#SSLCACertificatePath /etc/ssl/certs/
52+
#SSLCACertificateFile /etc/apache2/ssl.crt/ca-bundle.crt
53+
54+
# Certificate Revocation Lists (CRL):
55+
# Set the CA revocation path where to find CA CRLs for client
56+
# authentication or alternatively one huge file containing all
57+
# of them (file must be PEM encoded)
58+
# Note: Inside SSLCARevocationPath you need hash symlinks
59+
# to point to the certificate files. Use the provided
60+
# Makefile to update the hash symlinks after changes.
61+
#SSLCARevocationPath /etc/apache2/ssl.crl/
62+
#SSLCARevocationFile /etc/apache2/ssl.crl/ca-bundle.crl
63+
64+
# Client Authentication (Type):
65+
# Client certificate verification type and depth. Types are
66+
# none, optional, require and optional_no_ca. Depth is a
67+
# number which specifies how deeply to verify the certificate
68+
# issuer chain before deciding the certificate is not valid.
69+
#SSLVerifyClient require
70+
#SSLVerifyDepth 10
71+
72+
# SSL Engine Options:
73+
# Set various options for the SSL engine.
74+
# o FakeBasicAuth:
75+
# Translate the client X.509 into a Basic Authorisation. This means that
76+
# the standard Auth/DBMAuth methods can be used for access control. The
77+
# user name is the `one line' version of the client's X.509 certificate.
78+
# Note that no password is obtained from the user. Every entry in the user
79+
# file needs this password: `xxj31ZMTZzkVA'.
80+
# o ExportCertData:
81+
# This exports two additional environment variables: SSL_CLIENT_CERT and
82+
# SSL_SERVER_CERT. These contain the PEM-encoded certificates of the
83+
# server (always existing) and the client (only existing when client
84+
# authentication is used). This can be used to import the certificates
85+
# into CGI scripts.
86+
# o StdEnvVars:
87+
# This exports the standard SSL/TLS related `SSL_*' environment variables.
88+
# Per default this exportation is switched off for performance reasons,
89+
# because the extraction step is an expensive operation and is usually
90+
# useless for serving static content. So one usually enables the
91+
# exportation for CGI and SSI requests only.
92+
# o OptRenegotiate:
93+
# This enables optimized SSL connection renegotiation handling when SSL
94+
# directives are used in per-directory context.
95+
#SSLOptions +FakeBasicAuth +ExportCertData +StrictRequire
96+
97+
<FilesMatch "\.(cgi|shtml|phtml|php)$">
98+
SSLOptions +StdEnvVars
99+
</FilesMatch>
100+
<Directory /usr/lib/cgi-bin>
101+
SSLOptions +StdEnvVars
102+
</Directory>
103+
104+
# SSL Protocol Adjustments:
105+
# The safe and default but still SSL/TLS standard compliant shutdown
106+
# approach is that mod_ssl sends the close notify alert but doesn't wait for
107+
# the close notify alert from client. When you need a different shutdown
108+
# approach you can use one of the following variables:
109+
# o ssl-unclean-shutdown:
110+
# This forces an unclean shutdown when the connection is closed, i.e. no
111+
# SSL close notify alert is send or allowed to received. This violates
112+
# the SSL/TLS standard but is needed for some brain-dead browsers. Use
113+
# this when you receive I/O errors because of the standard approach where
114+
# mod_ssl sends the close notify alert.
115+
# o ssl-accurate-shutdown:
116+
# This forces an accurate shutdown when the connection is closed, i.e. a
117+
# SSL close notify alert is send and mod_ssl waits for the close notify
118+
# alert of the client. This is 100% SSL/TLS standard compliant, but in
119+
# practice often causes hanging connections with brain-dead browsers. Use
120+
# this only for browsers where you know that their SSL implementation
121+
# works correctly.
122+
# Notice: Most problems of broken clients are also related to the HTTP
123+
# keep-alive facility, so you usually additionally want to disable
124+
# keep-alive for those clients, too. Use variable "nokeepalive" for this.
125+
# Similarly, one has to force some clients to use HTTP/1.0 to workaround
126+
# their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and
127+
# "force-response-1.0" for this.
128+
BrowserMatch "MSIE [2-6]" \
129+
nokeepalive ssl-unclean-shutdown \
130+
downgrade-1.0 force-response-1.0
131+
# MSIE 7 and newer should be able to use keepalive
132+
BrowserMatch "MSIE [17-9]" ssl-unclean-shutdown
133+
134+
</VirtualHost>
135+
</IfModule>
136+
137+
# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

src/Environment/Command/SetupEnvCommand.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,9 @@ private function saveDockerComposeConfig()
491491
$configFile = Config::CONFIG_DIR . $values['config'];
492492
$config = Yaml::parse(file_get_contents($configFile));
493493
unset($config['active']);
494+
if (isset($config['config-only'])) {
495+
unset($config['config-only']);
496+
}
494497

495498
$links = $this->getContainerLinks($values['node']);
496499
if ($links) {
@@ -506,7 +509,7 @@ private function saveDockerComposeConfig()
506509
$configArray['services'] = $activeServices;
507510

508511

509-
//check if volumes var is null. If is dont add to config file
512+
// check if volumes var is null. If is dont add to config file
510513
$volumes = isset($this->_config['config']['docker']['compose']['volumes']) ? $this->_config['config']['docker']['compose']['volumes'] : null;
511514
if(!is_null($volumes)){
512515
$configArray['volumes'] = $volumes;

0 commit comments

Comments
 (0)