Spins up basic PHP container
This commit is contained in:
parent
b8ad06cda3
commit
00b593d6d3
7 changed files with 129 additions and 62 deletions
|
@ -1,3 +1,6 @@
|
|||
PROJECT_DIRECTORY=%s
|
||||
PROJECT_NAME=%s
|
||||
PHP_VERSION=%s
|
||||
|
||||
# Ports
|
||||
PHP_PORT=%s
|
|
@ -1,26 +0,0 @@
|
|||
services:
|
||||
# nginx:
|
||||
# build:
|
||||
# context: ./nginx
|
||||
# ports:
|
||||
# - ${NGINX_PORT}:80
|
||||
# volumes:
|
||||
# - ${PROJECT_DIRECTORY}:/var/www/html:cached
|
||||
# - ./nginx/conf.d:/etc/nginx/conf.d
|
||||
# database:
|
||||
# image: mysql:8.0
|
||||
# command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci
|
||||
# ports:
|
||||
# - ${MYSQL_PORT}:3306
|
||||
# expose:
|
||||
# - "3306"
|
||||
# environment:
|
||||
# MYSQL_ROOT_PASSWORD: docker
|
||||
# volumes:
|
||||
# - ./data/${PROJECT_NAME}/mysql:/var/lib/mysql:cached
|
||||
# cache:
|
||||
# image: redis:latest
|
||||
# ports:
|
||||
# - ${REDIS_PORT}:6379
|
||||
# volumes:
|
||||
# - ./data/${PROJECT_NAME}/redis:/data:cached
|
|
@ -1,7 +1,3 @@
|
|||
ARG PHP_VERSION
|
||||
|
||||
ENV PHP_VERSION ${PHP_VERSION}
|
||||
|
||||
FROM php:${PHP_VERSION}-fpm
|
||||
|
||||
RUN mkdir -p /var/www/html
|
||||
|
@ -13,29 +9,29 @@ RUN apt-get -qq update && apt-get -qq install -y \
|
|||
zip \
|
||||
unzip \
|
||||
libicu-dev \
|
||||
imagick \
|
||||
nano \
|
||||
bash \
|
||||
dnsutils
|
||||
|
||||
ENV NVM_DIR /root/.nvm
|
||||
ENV NODE_VERSION 20
|
||||
|
||||
RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash \
|
||||
&& . "$NVM_DIR/nvm.sh" \
|
||||
&& nvm install $NODE_VERSION \
|
||||
&& nvm use $NODE_VERSION
|
||||
|
||||
COPY --from=node:20 /usr/local/bin/npx /usr/local/bin/npx
|
||||
#ENV NVM_DIR /root/.nvm
|
||||
#ENV NODE_VERSION 20
|
||||
#
|
||||
#RUN curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash \
|
||||
# && . "$NVM_DIR/nvm.sh" \
|
||||
# && nvm install $NODE_VERSION \
|
||||
# && nvm use $NODE_VERSION
|
||||
#
|
||||
#COPY --from=node:20 /usr/local/bin/npx /usr/local/bin/npx
|
||||
|
||||
RUN docker-php-ext-configure intl > /dev/null
|
||||
RUN docker-php-ext-install mysqli pdo pdo_mysql sockets intl exif bcmath opcache > /dev/null
|
||||
RUN docker-php-ext-install mysqli pdo pdo_mysql sockets intl exif bcmath > /dev/null
|
||||
|
||||
RUN pecl install xdebug redis \
|
||||
&& docker-php-ext-enable redis
|
||||
#RUN pecl install xdebug redis \
|
||||
# && docker-php-ext-enable redis
|
||||
|
||||
COPY ./xdebug.ini.tmp "${PHP_INI_DIR}/conf.d/xdebug.ini"
|
||||
COPY ./opcache.ini "${PHP_INI_DIR}/conf.d"
|
||||
#COPY ./xdebug.ini.tmp "${PHP_INI_DIR}/conf.d/xdebug.ini"
|
||||
#RUN docker-php-ext-install opcache > /dev/null
|
||||
#COPY ./opcache.ini "${PHP_INI_DIR}/conf.d"
|
||||
COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer
|
||||
|
||||
WORKDIR /var/www/html
|
|
@ -1,10 +1,13 @@
|
|||
php:
|
||||
build:
|
||||
context: ./php-fpm
|
||||
working_dir: /var/www/html
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
volumes:
|
||||
- ${PROJECT_DIRECTORY}:/var/www/html:cached
|
||||
ports:
|
||||
- ${PHP_PORT}:9003
|
||||
services:
|
||||
php:
|
||||
build:
|
||||
context: ./php-fpm
|
||||
args:
|
||||
PHP_VERSION: ${PHP_VERSION}
|
||||
working_dir: /var/www/html
|
||||
extra_hosts:
|
||||
- host.docker.internal:host-gateway
|
||||
volumes:
|
||||
- ${PROJECT_DIRECTORY}:/var/www/html:cached
|
||||
ports:
|
||||
- ${PHP_PORT}:9003
|
31
src/Classes/OS/PortGenerator.php
Normal file
31
src/Classes/OS/PortGenerator.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Loom\Spinner\Classes\OS;
|
||||
|
||||
class PortGenerator
|
||||
{
|
||||
public function generateRandomPort(): int
|
||||
{
|
||||
$port = 0;
|
||||
$portInUse = true;
|
||||
|
||||
while ($portInUse) {
|
||||
$port = rand(49152, 65535);
|
||||
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
|
||||
|
||||
if (!$socket) {
|
||||
throw new \RuntimeException('Failed to create socket: ' . socket_strerror(socket_last_error()));
|
||||
}
|
||||
|
||||
if (@socket_bind($socket, '127.0.0.1', $port)) {
|
||||
$portInUse = false;
|
||||
}
|
||||
|
||||
socket_close($socket);
|
||||
}
|
||||
|
||||
return $port;
|
||||
}
|
||||
}
|
|
@ -63,6 +63,10 @@ class AbstractSpinnerCommand extends Command implements ConsoleCommandInterface
|
|||
new SpinnerFilePath(sprintf('data/environments/%s/.env', $input->getArgument('name'))),
|
||||
'projectEnv'
|
||||
);
|
||||
$this->filePaths->add(
|
||||
new SpinnerFilePath(sprintf('data/environments/%s/docker-compose.yml', $input->getArgument('name'))),
|
||||
'projectDockerCompose'
|
||||
);
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
|
@ -83,11 +87,10 @@ class AbstractSpinnerCommand extends Command implements ConsoleCommandInterface
|
|||
protected function buildDockerComposeCommand(string $command, bool $daemon = true): string
|
||||
{
|
||||
return sprintf(
|
||||
'cd %s && docker compose %s --env-file=%s%s',
|
||||
$this->filePaths->get('config')->getAbsolutePath(),
|
||||
'cd %s && docker-compose --env-file=%s %s%s',
|
||||
$this->filePaths->get('projectData')->getAbsolutePath(),
|
||||
$this->filePaths->get('projectEnv')->getAbsolutePath(),
|
||||
$command,
|
||||
$this->filePaths->get('projectEnv')->getAbsolutePath()
|
||||
?? $this->filePaths->get('projectEnv')->getProvidedPath(),
|
||||
$daemon ? ' -d' : ''
|
||||
);
|
||||
}
|
||||
|
@ -118,6 +121,9 @@ class AbstractSpinnerCommand extends Command implements ConsoleCommandInterface
|
|||
'defaultSpinnerConfig' => new SpinnerFilePath('config/spinner.yaml'),
|
||||
'envTemplate' => new SpinnerFilePath('config/.template.env'),
|
||||
'data' => new SpinnerFilePath('data'),
|
||||
'phpYamlTemplate' => new SpinnerFilePath('config/php.yaml'),
|
||||
'phpFpmDockerfileTemplate' => new SpinnerFilePath('config/php-fpm/Dockerfile'),
|
||||
'phpFpmDataDirectory' => new SpinnerFilePath('config/php-fpm'),
|
||||
]);
|
||||
}
|
||||
}
|
|
@ -4,16 +4,31 @@ declare(strict_types=1);
|
|||
|
||||
namespace Loom\Spinner\Command;
|
||||
|
||||
use Loom\Spinner\Classes\OS\PortGenerator;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
#[AsCommand(name: 'spin:up', description: 'Spin up a new development environment')]
|
||||
class SpinCommand extends AbstractSpinnerCommand
|
||||
{
|
||||
private PortGenerator $portGenerator;
|
||||
private array $ports;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->portGenerator = new PortGenerator();
|
||||
$this->ports = [
|
||||
'php' => $this->portGenerator->generateRandomPort(),
|
||||
];
|
||||
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws \Exception
|
||||
*/
|
||||
|
@ -39,18 +54,57 @@ class SpinCommand extends AbstractSpinnerCommand
|
|||
|
||||
$this->style->success("Spinning up a new development environment...");
|
||||
|
||||
$this->createProjectData($input);
|
||||
|
||||
$command = $this->buildDockerComposeCommand(sprintf('-p %s up', $input->getArgument('name')));
|
||||
|
||||
passthru($command);
|
||||
|
||||
return Command::SUCCESS;
|
||||
}
|
||||
|
||||
private function createProjectData(InputInterface $input): void
|
||||
{
|
||||
mkdir($this->filePaths->get('projectData')->getProvidedPath(), 0777, true);
|
||||
|
||||
$this->createEnvironmentFile($input);
|
||||
$this->buildDockerComposeFile($input);
|
||||
}
|
||||
|
||||
private function createEnvironmentFile(InputInterface $input): void
|
||||
{
|
||||
file_put_contents(
|
||||
$this->filePaths->get('projectEnv')->getProvidedPath(),
|
||||
sprintf(
|
||||
file_get_contents($this->filePaths->get('envTemplate')->getAbsolutePath()),
|
||||
$this->filePaths->get('project')->getAbsolutePath(),
|
||||
$input->getArgument('name'),
|
||||
$input->getOption('php')
|
||||
$input->getOption('php'),
|
||||
$this->getPort('php'),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return Command::SUCCESS;
|
||||
private function buildDockerComposeFile(InputInterface $input): void
|
||||
{
|
||||
if (!file_exists($this->filePaths->get('projectData')->getProvidedPath() . '/php-fpm')) {
|
||||
mkdir($this->filePaths->get('projectData')->getProvidedPath() . '/php-fpm', 0777, true);
|
||||
}
|
||||
file_put_contents(
|
||||
$this->filePaths->get('projectDockerCompose')->getProvidedPath(),
|
||||
file_get_contents($this->filePaths->get('phpYamlTemplate')->getAbsolutePath())
|
||||
);
|
||||
$phpFpmDockerfileTemplate = file_get_contents($this->filePaths->get('phpFpmDockerfileTemplate')->getAbsolutePath());
|
||||
$phpFpmDockerfileTemplate = str_replace('${PHP_VERSION}', $input->getOption('php'), $phpFpmDockerfileTemplate);
|
||||
|
||||
file_put_contents(
|
||||
$this->filePaths->get('projectData')->getProvidedPath() . '/php-fpm/Dockerfile',
|
||||
$phpFpmDockerfileTemplate
|
||||
);
|
||||
}
|
||||
|
||||
private function getPort(string $service): int
|
||||
{
|
||||
return $this->ports[$service] ?? $this->portGenerator->generateRandomPort();
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue