-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Local Server extension for containers #525
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,246 @@ | ||
<?php | ||
/** | ||
* Local Server Docker Compose file generator. | ||
*/ | ||
|
||
namespace Altis\Enhanced_Search; | ||
|
||
use Altis; | ||
use Altis\Local_Server\Composer\Compose_Extension; | ||
use Altis\Local_Server\Composer\Docker_Compose_Generator; | ||
|
||
class Local_Server_Extension implements Compose_Extension { | ||
Check failure on line 12 in inc/class-local-server-extension.php HM Linter / hmlinterinc/class-local-server-extension.php#L12
Raw output
|
||
protected Docker_Compose_Generator $generator; | ||
Check failure on line 13 in inc/class-local-server-extension.php HM Linter / hmlinterinc/class-local-server-extension.php#L13
Raw output
Check failure on line 13 in inc/class-local-server-extension.php HM Linter / hmlinterinc/class-local-server-extension.php#L13
Raw output
|
||
|
||
/** | ||
* Configure the extension. | ||
* | ||
* @param Docker_Compose_Generator $generator The root generator. | ||
* @param array $args An optional array of arguments to modify the behaviour of the generator. | ||
*/ | ||
public function set_config( Docker_Compose_Generator $generator, array $args ) : void { | ||
$this->generator = $generator; | ||
} | ||
|
||
/** | ||
* Filter the docker-compose.yml config. | ||
* | ||
* @param array $config Full docker-compose.yml configuration. | ||
* @return array Altered docker-compose.yml configuration. | ||
*/ | ||
public function filter_compose( array $config ) : array { | ||
// Skip entirely if the module is disabled. | ||
$full_config = Altis\get_config()['modules']; | ||
if ( ! ( $full_config['search']['enabled'] ?? true ) ) { | ||
return $config; | ||
} | ||
|
||
$local_config = $full_config['search']['local'] ?? []; | ||
if ( ! ( $local_config['enabled'] ?? true ) ) { | ||
return $config; | ||
} | ||
|
||
// Handle the main ES service. | ||
$config['volumes']['es-data'] = null; | ||
$config['services'] = array_merge( $config['services'], $this->get_service_elasticsearch() ); | ||
|
||
foreach ( [ 'php', 'cavalcade' ] as $php_svc ) { | ||
if ( empty( $config['services'][ $php_svc ] ) ) { | ||
continue; | ||
} | ||
|
||
$config['services'][ $php_svc ]['external_links'][] = "proxy:elasticsearch-{$this->generator->hostname}"; | ||
$config['services'][ $php_svc ]['environment']['ELASTICSEARCH_HOST'] = 'elasticsearch'; | ||
$config['services'][ $php_svc ]['environment']['ELASTICSEARCH_PORT'] = 9200; | ||
$config['services'][ $php_svc ]['depends_on']['elasticsearch'] = [ | ||
'condition' => 'service_healthy', | ||
]; | ||
} | ||
|
||
// Enable Kibana. (Defaults to true, but supports new + old style.) | ||
Check failure on line 60 in inc/class-local-server-extension.php HM Linter / hmlinterinc/class-local-server-extension.php#L60
Raw output
|
||
$has_kibana = $local_config['kibana'] ?? $full_config['local-server']['kibana'] ?? true; | ||
if ( $has_kibana ) { | ||
if ( ! empty( $full_config['local-server']['kibana'] ) ) { | ||
trigger_error( | ||
'extra.altis.modules.local-server.kibana is deprecated, use extra.altis.modules.search.kibana instead.', | ||
E_USER_DEPRECATED | ||
); | ||
} | ||
|
||
$config['services'] = array_merge( $config['services'], $this->get_service_kibana() ); | ||
} | ||
|
||
return $config; | ||
} | ||
|
||
/** | ||
* Get the Elasticsearch service. | ||
* | ||
* @return array | ||
*/ | ||
protected function get_service_elasticsearch() : array { | ||
$mem_limit = getenv( 'ES_MEM_LIMIT' ) ?: '1g'; | ||
|
||
$version_map = [ | ||
'7.10' => 'humanmade/altis-local-server-elasticsearch:4.1.0', | ||
'7' => 'humanmade/altis-local-server-elasticsearch:4.1.0', | ||
'6.8' => 'humanmade/altis-local-server-elasticsearch:3.1.0', | ||
'6' => 'humanmade/altis-local-server-elasticsearch:3.1.0', | ||
'6.3' => 'humanmade/altis-local-server-elasticsearch:3.0.0', | ||
]; | ||
|
||
$this->check_elasticsearch_version( array_keys( $version_map ) ); | ||
|
||
$image = $version_map[ $this->get_elasticsearch_version() ]; | ||
|
||
return [ | ||
'elasticsearch' => [ | ||
'image' => $image, | ||
'restart' => 'unless-stopped', | ||
'container_name' => "{$this->generator->project_name}-es", | ||
'ulimits' => [ | ||
'memlock' => [ | ||
'soft' => -1, | ||
'hard' => -1, | ||
], | ||
], | ||
'mem_limit' => $mem_limit, | ||
'volumes' => [ | ||
'es-data:/usr/share/elasticsearch/data', | ||
"{$this->generator->root_dir}/content/uploads/es-packages:/usr/share/elasticsearch/config/packages", | ||
], | ||
'ports' => [ | ||
'9200', | ||
], | ||
'networks' => [ | ||
'proxy', | ||
'default', | ||
], | ||
'healthcheck' => [ | ||
'test' => [ | ||
'CMD-SHELL', | ||
'curl --silent --fail localhost:9200/_cluster/health || exit 1', | ||
], | ||
'interval' => '5s', | ||
'timeout' => '5s', | ||
'retries' => 25, | ||
], | ||
'labels' => [ | ||
'traefik.port=9200', | ||
'traefik.protocol=http', | ||
'traefik.docker.network=proxy', | ||
"traefik.frontend.rule=HostRegexp:elasticsearch-{$this->generator->hostname}", | ||
"traefik.domain=elasticsearch-{$this->generator->hostname}", | ||
], | ||
'environment' => [ | ||
'http.max_content_length=10mb', | ||
// Force ES into single-node mode (otherwise defaults to zen discovery as | ||
// network.host is set in the default config). | ||
'discovery.type=single-node', | ||
// Use max container memory limit as the max JVM heap allocation value. | ||
"ES_JAVA_OPTS=-Xms512m -Xmx{$mem_limit}", | ||
], | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* Get the Kibana service. | ||
* | ||
* @return array | ||
*/ | ||
protected function get_service_kibana() : array { | ||
$version_map = [ | ||
'7.10' => 'humanmade/altis-local-server-kibana:1.1.1', | ||
'7' => 'humanmade/altis-local-server-kibana:1.1.1', | ||
'6.8' => 'blacktop/kibana:6.8', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A thought. Why are we still supporting so many old versions? Is this just for clients who haven't upgraded? Or is there a technical reason someone would want to use an old version? |
||
'6' => 'blacktop/kibana:6.8', | ||
'6.3' => 'blacktop/kibana:6.3', | ||
]; | ||
|
||
$this->check_elasticsearch_version( array_keys( $version_map ) ); | ||
|
||
$image = $version_map[ $this->get_elasticsearch_version() ]; | ||
|
||
$yml_file = 'kibana.yml'; | ||
if ( version_compare( $this->get_elasticsearch_version(), '7', '>=' ) ) { | ||
$yml_file = 'kibana-7.yml'; | ||
} | ||
|
||
return [ | ||
'kibana' => [ | ||
'image' => $image, | ||
'container_name' => "{$this->generator->project_name}-kibana", | ||
'networks' => [ | ||
'proxy', | ||
'default', | ||
], | ||
'ports' => [ | ||
'5601', | ||
], | ||
'labels' => [ | ||
'traefik.port=5601', | ||
'traefik.protocol=http', | ||
'traefik.docker.network=proxy', | ||
"traefik.frontend.rule=Host:{$this->generator->hostname};PathPrefix:/kibana", | ||
], | ||
'depends_on' => [ | ||
'elasticsearch' => [ | ||
'condition' => 'service_healthy', | ||
], | ||
], | ||
'volumes' => [ | ||
"{$this->generator->config_dir}/{$yml_file}:/usr/share/kibana/config/kibana.yml", | ||
], | ||
], | ||
]; | ||
} | ||
|
||
/** | ||
* Get the configured Elasticsearch version. | ||
* | ||
* @return int | ||
*/ | ||
protected function get_elasticsearch_version() : string { | ||
$full_config = Altis\get_config(); | ||
|
||
// Try new config first. | ||
if ( ! empty( $full_config['modules']['search']['local']['version'] ) ) { | ||
return (string) $full_config['modules']['search']['local']['version']; | ||
} | ||
|
||
// Try legacy, and warn if it's still used. | ||
if ( ! empty( $full_config['modules']['local-server']['elasticsearch'] ) ) { | ||
trigger_error( | ||
'extra.altis.modules.local-server.elasticsearch is deprecated, use extra.altis.modules.search.version instead.', | ||
E_USER_DEPRECATED | ||
); | ||
return (string) $full_config['modules']['local-server']['elasticsearch']; | ||
} | ||
|
||
return '7'; | ||
} | ||
|
||
/** | ||
* Check the configured Elasticsearch version in config. | ||
* | ||
* @param array $versions List of available version numbers. | ||
* @return void | ||
*/ | ||
protected function check_elasticsearch_version( array $versions ) { | ||
$versions = array_map( 'strval', $versions ); | ||
rsort( $versions ); | ||
if ( in_array( $this->get_elasticsearch_version(), $versions, true ) ) { | ||
return; | ||
} | ||
|
||
echo sprintf( | ||
"The configured elasticsearch version \"%s\" is not supported.\nTry one of the following:\n - %s\n", | ||
// phpcs:ignore HM.Security.EscapeOutput.OutputNotEscaped | ||
$this->get_elasticsearch_version(), | ||
// phpcs:ignore HM.Security.EscapeOutput.OutputNotEscaped | ||
implode( "\n - ", $versions ) | ||
); | ||
exit( 1 ); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't like the similarity between the different "config" var names.
Two are the composer config, and one is a docker-compose config. Could they be called
full/local_composer_config
anddocker_config
?