From d3c740894804b69291c13a05cbe4d2fcb505225f Mon Sep 17 00:00:00 2001 From: IgorIlyaguev Date: Mon, 24 Mar 2025 15:43:12 +0300 Subject: [PATCH 01/10] fix README.md to add API description --- README.md | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/README.md b/README.md index c01046f..a1bf4c3 100644 --- a/README.md +++ b/README.md @@ -24,3 +24,29 @@ ### Run tests > `make test` + +### API requests +> Запрос кода подтверждения +> +> POST +> +> http://127.0.0.1:8000/api/user/request-code +> +> ```json +> { +> "phone_number": "+79157053551" +> } +> ``` + +> Проверка кода подтверждения +> +> POST +> +> http://127.0.0.1:8000/api/verify-code +> +> ```json +> { +> "phone_number": "+79157053551", +> "phone_code": "1234" +> } +> ``` From 453d6dec6826c1980730ff50653ef284e705efd5 Mon Sep 17 00:00:00 2001 From: IgorIlyaguev Date: Mon, 24 Mar 2025 15:43:27 +0300 Subject: [PATCH 02/10] add AuthDto.php --- src/Dto/Response/AuthDto.php | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/Dto/Response/AuthDto.php diff --git a/src/Dto/Response/AuthDto.php b/src/Dto/Response/AuthDto.php new file mode 100644 index 0000000..fb2cd62 --- /dev/null +++ b/src/Dto/Response/AuthDto.php @@ -0,0 +1,27 @@ +authText = $authText; + $this->userId = $userId; + } + + public function getAuthText(): string + { + return $this->authText; + } + + public function getUserId(): int + { + return $this->userId; + } +} From b1c5216571d96fd6de497dba3ce4cd1010696ffd Mon Sep 17 00:00:00 2001 From: IgorIlyaguev Date: Mon, 24 Mar 2025 15:44:33 +0300 Subject: [PATCH 03/10] fix User.php to rename table and add factory method --- src/Entity/User.php | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/Entity/User.php b/src/Entity/User.php index 3b813da..4a827e3 100644 --- a/src/Entity/User.php +++ b/src/Entity/User.php @@ -7,7 +7,7 @@ use Symfony\Component\Security\Core\User\UserInterface; #[ORM\Entity(repositoryClass: UserRepository::class)] -#[ORM\Table(name: '`user`')] +#[ORM\Table(name: '`users`')] #[ORM\UniqueConstraint(name: 'UNIQ_IDENTIFIER_PHONE_NUMBER', fields: ['phoneNumber'])] class User implements UserInterface { @@ -34,7 +34,7 @@ class User implements UserInterface #[ORM\Column] private \DateTimeImmutable $createdAt; - public function __construct() + private function __construct() { $this->createdAt = new \DateTimeImmutable(); } @@ -128,4 +128,20 @@ public function getCreatedAt(): \DateTimeImmutable { return $this->createdAt; } + + /** + * Фабричный метод в сущности, как написано в задании, если я правильно понял. + * + * @param list $roles + */ + public static function create( + string $phoneNumber, + array $roles = [], + ?string $name = null, + ): self { + return (new self()) + ->setPhoneNumber($phoneNumber) + ->setRoles($roles) + ->setName($name); + } } From e88e01bcfd3e06aa551d3ab3d542cb90b3cf8cff Mon Sep 17 00:00:00 2001 From: IgorIlyaguev Date: Mon, 24 Mar 2025 15:46:14 +0300 Subject: [PATCH 04/10] fix PhoneVerificationCode.php to add factory method --- src/Entity/PhoneVerificationCode.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/Entity/PhoneVerificationCode.php b/src/Entity/PhoneVerificationCode.php index c756148..2238280 100644 --- a/src/Entity/PhoneVerificationCode.php +++ b/src/Entity/PhoneVerificationCode.php @@ -31,7 +31,7 @@ class PhoneVerificationCode #[ORM\Column] private \DateTimeImmutable $createdAt; - public function __construct() + private function __construct() { $this->createdAt = new \DateTimeImmutable(); } @@ -93,4 +93,20 @@ public function getCreatedAt(): \DateTimeImmutable { return $this->createdAt; } + + /** + * Фабричный метод в сущности, как написано в задании, если я правильно понял. + */ + public static function create( + string $phoneNumber, + string $code, + int $attempts = 0, + bool $isUsed = false, + ): self { + return (new self()) + ->setPhoneNumber($phoneNumber) + ->setCode($code) + ->setAttempts($attempts) + ->setIsUsed($isUsed); + } } From c0d2b945c1df4e5b88117362d1be89895f447ce1 Mon Sep 17 00:00:00 2001 From: IgorIlyaguev Date: Mon, 24 Mar 2025 15:46:43 +0300 Subject: [PATCH 05/10] fix repositories to remove commented code --- .../PhoneVerificationCodeRepository.php | 25 ------------------- src/Repository/UserRepository.php | 25 ------------------- 2 files changed, 50 deletions(-) diff --git a/src/Repository/PhoneVerificationCodeRepository.php b/src/Repository/PhoneVerificationCodeRepository.php index 8888a1a..591e987 100644 --- a/src/Repository/PhoneVerificationCodeRepository.php +++ b/src/Repository/PhoneVerificationCodeRepository.php @@ -97,29 +97,4 @@ public function getLastCode(string $phoneNumber): false|array // ->getQuery() // ->getOneOrNullResult(); // } - - // /** - // * @return PhoneVerificationCode[] Returns an array of PhoneVerificationCode objects - // */ - // public function findByExampleField($value): array - // { - // return $this->createQueryBuilder('p') - // ->andWhere('p.exampleField = :val') - // ->setParameter('val', $value) - // ->orderBy('p.id', 'ASC') - // ->setMaxResults(10) - // ->getQuery() - // ->getResult() - // ; - // } - - // public function findOneBySomeField($value): ?PhoneVerificationCode - // { - // return $this->createQueryBuilder('p') - // ->andWhere('p.exampleField = :val') - // ->setParameter('val', $value) - // ->getQuery() - // ->getOneOrNullResult() - // ; - // } } diff --git a/src/Repository/UserRepository.php b/src/Repository/UserRepository.php index b29153b..da4b8be 100644 --- a/src/Repository/UserRepository.php +++ b/src/Repository/UserRepository.php @@ -15,29 +15,4 @@ public function __construct(ManagerRegistry $registry) { parent::__construct($registry, User::class); } - - // /** - // * @return User[] Returns an array of User objects - // */ - // public function findByExampleField($value): array - // { - // return $this->createQueryBuilder('u') - // ->andWhere('u.exampleField = :val') - // ->setParameter('val', $value) - // ->orderBy('u.id', 'ASC') - // ->setMaxResults(10) - // ->getQuery() - // ->getResult() - // ; - // } - - // public function findOneBySomeField($value): ?User - // { - // return $this->createQueryBuilder('u') - // ->andWhere('u.exampleField = :val') - // ->setParameter('val', $value) - // ->getQuery() - // ->getOneOrNullResult() - // ; - // } } From ffa04a5b5a0c6217be78945df32179b5f4b44c3a Mon Sep 17 00:00:00 2001 From: IgorIlyaguev Date: Mon, 24 Mar 2025 15:46:58 +0300 Subject: [PATCH 06/10] add VerifyPhoneCodeDto.php --- src/Dto/Request/VerifyPhoneCodeDto.php | 44 ++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 src/Dto/Request/VerifyPhoneCodeDto.php diff --git a/src/Dto/Request/VerifyPhoneCodeDto.php b/src/Dto/Request/VerifyPhoneCodeDto.php new file mode 100644 index 0000000..301fe40 --- /dev/null +++ b/src/Dto/Request/VerifyPhoneCodeDto.php @@ -0,0 +1,44 @@ +phoneNumber; + } + + public function setPhoneNumber(string $phoneNumber): void + { + $this->phoneNumber = $phoneNumber; + } + + public function getPhoneCode(): string + { + return $this->phoneCode; + } + + public function setPhoneCode(string $phoneCode): void + { + $this->phoneCode = $phoneCode; + } +} From fa701110ca749de62e5f3d593fd8d8308e17b9bb Mon Sep 17 00:00:00 2001 From: IgorIlyaguev Date: Mon, 24 Mar 2025 15:47:25 +0300 Subject: [PATCH 07/10] rename GetPhoneCodeDto.php to RequestPhoneCodeDto.php --- .../Request/{GetPhoneCodeDto.php => RequestPhoneCodeDto.php} | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) rename src/Dto/Request/{GetPhoneCodeDto.php => RequestPhoneCodeDto.php} (84%) diff --git a/src/Dto/Request/GetPhoneCodeDto.php b/src/Dto/Request/RequestPhoneCodeDto.php similarity index 84% rename from src/Dto/Request/GetPhoneCodeDto.php rename to src/Dto/Request/RequestPhoneCodeDto.php index 50a73f7..da3f37c 100644 --- a/src/Dto/Request/GetPhoneCodeDto.php +++ b/src/Dto/Request/RequestPhoneCodeDto.php @@ -6,9 +6,9 @@ use Symfony\Component\Validator\Constraints as Assert; -class GetPhoneCodeDto +class RequestPhoneCodeDto { - #[Assert\NotBlank(message: 'Phone number cannot be blank.')] + #[Assert\NotBlank(message: 'Phone number cannot be blank')] #[Assert\Regex( pattern: '/^\+79\d{9}$/', message: 'Phone number must be in the format +79151234567' From b2c51a0b3fbde17d810a9642c9b835d07fb8971e Mon Sep 17 00:00:00 2001 From: IgorIlyaguev Date: Mon, 24 Mar 2025 15:47:59 +0300 Subject: [PATCH 08/10] fix UserController.php to add new endpoint --- src/Controller/UserController.php | 37 +++++++++++++++++-------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/src/Controller/UserController.php b/src/Controller/UserController.php index 9407c33..966dd71 100644 --- a/src/Controller/UserController.php +++ b/src/Controller/UserController.php @@ -2,7 +2,8 @@ namespace App\Controller; -use App\Dto\Request\GetPhoneCodeDto; +use App\Dto\Request\RequestPhoneCodeDto; +use App\Dto\Request\VerifyPhoneCodeDto; use App\Service\PhoneVerificationService; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\JsonResponse; @@ -15,12 +16,12 @@ final class UserController extends AbstractController * @throws \Exception */ #[Route( - '/user/request-code', - name: 'user_request_code', + '/request-code', + name: 'request_code', methods: ['POST']) ] public function requestCode( - #[MapRequestPayload] GetPhoneCodeDto $requestDto, + #[MapRequestPayload] RequestPhoneCodeDto $requestDto, PhoneVerificationService $verificationService, ): JsonResponse { $phoneCodeDto = $verificationService->getPhoneCode($requestDto); @@ -28,17 +29,19 @@ public function requestCode( return $this->json($phoneCodeDto); } - // #[Route('/verify-code', methods: ['POST'])] - // public function verifyCode(Request $request): JsonResponse - // { - // $phoneNumber = $request->request->get('phone_number'); - // $code = $request->request->get('code'); - // - // try { - // $user = $this->verificationService->verifyCode($phoneNumber, $code); - // return $this->json(['success' => true, 'user_id' => $user->getId()]); - // } catch (\Exception $e) { - // return $this->json(['error' => $e->getMessage()], 400); - // } - // } + /** + * @throws \Exception + */ + #[Route('/verify-code', methods: ['POST'])] + public function verifyCode( + #[MapRequestPayload] VerifyPhoneCodeDto $requestDto, + PhoneVerificationService $verificationService, + ): JsonResponse { + $authDto = $verificationService->verifyCode( + $requestDto->getPhoneNumber(), + $requestDto->getPhoneCode() + ); + + return $this->json($authDto); + } } From f5d648a2868f493be3d4ee0ff745604b89a2ec91 Mon Sep 17 00:00:00 2001 From: IgorIlyaguev Date: Mon, 24 Mar 2025 15:48:32 +0300 Subject: [PATCH 09/10] fix PhoneVerificationService.php to verify phone code --- src/Service/PhoneVerificationService.php | 81 +++++++++++++++++++++--- 1 file changed, 71 insertions(+), 10 deletions(-) diff --git a/src/Service/PhoneVerificationService.php b/src/Service/PhoneVerificationService.php index 746bfb5..5805058 100644 --- a/src/Service/PhoneVerificationService.php +++ b/src/Service/PhoneVerificationService.php @@ -4,11 +4,13 @@ namespace App\Service; -use App\Dto\Request\GetPhoneCodeDto; +use App\Dto\Request\RequestPhoneCodeDto; +use App\Dto\Response\AuthDto; use App\Dto\Response\PhoneCodeDto; use App\Entity\PhoneVerificationCode; use App\Entity\User; use App\Repository\PhoneVerificationCodeRepository; +use App\Repository\UserRepository; use Doctrine\ORM\EntityManagerInterface; class PhoneVerificationService @@ -18,19 +20,22 @@ class PhoneVerificationService private EntityManagerInterface $em; private PhoneVerificationCodeRepository $codeRepository; + private UserRepository $userRepository; public function __construct( EntityManagerInterface $em, PhoneVerificationCodeRepository $codeRepository, + UserRepository $userRepository, ) { $this->em = $em; $this->codeRepository = $codeRepository; + $this->userRepository = $userRepository; } /** * @throws \Exception */ - public function getPhoneCode(GetPhoneCodeDto $getPhoneCodeDto): PhoneCodeDto + public function getPhoneCode(RequestPhoneCodeDto $getPhoneCodeDto): PhoneCodeDto { $phoneNumber = $getPhoneCodeDto->getPhoneNumber(); @@ -96,20 +101,20 @@ private function blockPhoneNumber(string $phoneNumber): void } /** - * @param array $code + * @param array $codeData * * @throws \Exception */ - private function isActualExistedCode(array $code): bool + private function isActualExistedCode(array $codeData): bool { /** @var string $codeCreatedAt */ - $codeCreatedAt = $code['created_at']; + $codeCreatedAt = $codeData['created_at']; // TODO: // Возникли проблемы с временем, пришлось сделать костыль с timezone, // надо будет с этим разобраться. Возможно в docker контейнере все наладится - $createdAt = new \DateTimeImmutable($codeCreatedAt, new \DateTimeZone('Europe/Moscow')); - $now = new \DateTimeImmutable('-1 minute', new \DateTimeZone('Europe/Moscow')); + $createdAt = new \DateTimeImmutable($codeCreatedAt); + $now = new \DateTimeImmutable('-1 minute'); return $createdAt > $now; } @@ -121,11 +126,67 @@ private function generateCode(): string private function createPhoneVerificationCode(string $phoneNumber, string $newVerificationCode): void { - $verificationCode = new PhoneVerificationCode(); - $verificationCode->setPhoneNumber($phoneNumber); - $verificationCode->setCode($newVerificationCode); + $verificationCode = PhoneVerificationCode::create( + $phoneNumber, + $newVerificationCode + ); $this->em->persist($verificationCode); $this->em->flush(); } + + /** + * @throws \Exception + */ + public function verifyCode(string $phoneNumber, string $code): AuthDto + { + $lastCodeData = $this->codeRepository->getLastCode($phoneNumber); + + if ($lastCodeData === false) { + throw new \Exception('Код не найден'); + } + + if (!$this->isActualExistedCode($lastCodeData)) { + throw new \Exception('Код истек, запросите новый'); + } + + /** @var PhoneVerificationCode $verificationCode */ + $verificationCode = $this->codeRepository->find($lastCodeData['id']); + + if ($lastCodeData['is_used']) { + throw new \Exception('Код уже использован'); + } + + if ($lastCodeData['code'] !== $code) { + throw new \Exception('Код неверный'); + } + + $user = $this->userRepository->findOneBy(['phoneNumber' => $lastCodeData['phone_number']]); + + if ($user !== null) { + return new AuthDto('Authorise success', $user->getId()); + } + + /* + * Тут, думаю, стоит использовать в транзакцию, + * чтобы не получилось, что юзер создался, а код не пометился как использованный + */ + $this->em->beginTransaction(); + + try { + $user = User::create($phoneNumber); + $this->em->persist($user); + + $verificationCode->setIsUsed(true); + + $this->em->flush(); + $this->em->commit(); + } catch (\Exception $e) { + $this->em->rollback(); + + throw $e; + } + + return new AuthDto('Registration success', $user->getId()); + } } From e0c58521c68fd8df1b7ceecef07ea34603477057 Mon Sep 17 00:00:00 2001 From: IgorIlyaguev Date: Mon, 24 Mar 2025 17:11:19 +0300 Subject: [PATCH 10/10] add docker --- .dockerignore | 1 + .env | 4 +++ .gitignore | 5 +++ Makefile | 12 ++++++- compose.override.yaml | 18 ---------- compose.yaml | 25 ------------- docker-compose.yml | 68 ++++++++++++++++++++++++++++++++++++ docker/.env.dist | 5 +++ docker/nginx/conf.d/conf.d | 27 ++++++++++++++ docker/php/Dockerfile | 44 +++++++++++++++++++++++ docker/php/conf.d/xdebug.ini | 4 +++ docker/php/php.ini | 0 12 files changed, 169 insertions(+), 44 deletions(-) create mode 100644 .dockerignore delete mode 100644 compose.override.yaml delete mode 100644 compose.yaml create mode 100644 docker-compose.yml create mode 100644 docker/.env.dist create mode 100644 docker/nginx/conf.d/conf.d create mode 100644 docker/php/Dockerfile create mode 100644 docker/php/conf.d/xdebug.ini create mode 100644 docker/php/php.ini diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0b58df5 --- /dev/null +++ b/.dockerignore @@ -0,0 +1 @@ +docker/pgdata diff --git a/.env b/.env index 32ab3c6..caa68b0 100644 --- a/.env +++ b/.env @@ -39,3 +39,7 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 ###> symfony/mailer ### MAILER_DSN=null://null ###< symfony/mailer ### + +# Настройки Xdebug +XDEBUG_CLIENT_HOST=host.docker.internal +XDEBUG_IDEKEY=PHPSTORM diff --git a/.gitignore b/.gitignore index b934e6f..81e7c50 100644 --- a/.gitignore +++ b/.gitignore @@ -37,3 +37,8 @@ phpstan.neon /.php-cs-fixer.php /.php-cs-fixer.cache ###< friendsofphp/php-cs-fixer ### + +###> IDE files ### +/docker/pgdata +/docker/.env +###> IDE files ### diff --git a/Makefile b/Makefile index 6babd19..40d6017 100644 --- a/Makefile +++ b/Makefile @@ -4,9 +4,10 @@ install: validate: composer validate +PORT ?= 8000 start: symfony server:start - #php -S localhost:8000 -t public/ + #PHP_CLI_SERVER_WORKERS=5 php -S 0.0.0.0:$(PORT) -t public lint: phpcsfixer-check phpstan @@ -27,4 +28,13 @@ phpstan-baseline: test: ./bin/phpunit +docker-up-d: + docker-compose --env-file ./docker/.env up -d + +docker-down: + docker-compose --env-file ./docker/.env down -v + +docker-build: + docker-compose --env-file ./docker/.env build + .PHONY: tests diff --git a/compose.override.yaml b/compose.override.yaml deleted file mode 100644 index 8dc54de..0000000 --- a/compose.override.yaml +++ /dev/null @@ -1,18 +0,0 @@ - -services: -###> doctrine/doctrine-bundle ### - database: - ports: - - "5432" -###< doctrine/doctrine-bundle ### - -###> symfony/mailer ### - mailer: - image: axllent/mailpit - ports: - - "1025" - - "8025" - environment: - MP_SMTP_AUTH_ACCEPT_ANY: 1 - MP_SMTP_AUTH_ALLOW_INSECURE: 1 -###< symfony/mailer ### diff --git a/compose.yaml b/compose.yaml deleted file mode 100644 index 89c74d1..0000000 --- a/compose.yaml +++ /dev/null @@ -1,25 +0,0 @@ - -services: -###> doctrine/doctrine-bundle ### - database: - image: postgres:${POSTGRES_VERSION:-16}-alpine - environment: - POSTGRES_DB: ${POSTGRES_DB:-app} - # You should definitely change the password in production - POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-!ChangeMe!} - POSTGRES_USER: ${POSTGRES_USER:-app} - healthcheck: - test: ["CMD", "pg_isready", "-d", "${POSTGRES_DB:-app}", "-U", "${POSTGRES_USER:-app}"] - timeout: 5s - retries: 5 - start_period: 60s - volumes: - - database_data:/var/lib/postgresql/data:rw - # You may use a bind-mounted host directory instead, so that it is harder to accidentally remove the volume and lose all your data! - # - ./docker/db/data:/var/lib/postgresql/data:rw -###< doctrine/doctrine-bundle ### - -volumes: -###> doctrine/doctrine-bundle ### - database_data: -###< doctrine/doctrine-bundle ### diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..4ca608f --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,68 @@ +version: '3.8' + +services: + ilyaguev_igor-indigolab-php: + build: + context: . + dockerfile: docker/php/Dockerfile + container_name: ilyaguev_igor-indigolab-php + volumes: + - ./:/var/www/html + environment: + - DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@ilyaguev_igor-indigolab-postgres:5432/${POSTGRES_DB} + - REDIS_URL=redis://ilyaguev_igor-indigolab-redis:6379 +# - XDEBUG_CLIENT_HOST=${XDEBUG_CLIENT_HOST} +# - XDEBUG_IDEKEY=${XDEBUG_IDEKEY} + depends_on: + - ilyaguev_igor-indigolab-postgres + - ilyaguev_igor-indigolab-redis + networks: + - indigolab-network + + + ilyaguev_igor-indigolab-nginx: + image: nginx:latest + container_name: ilyaguev_igor-indigolab-nginx + restart: unless-stopped + ports: + - "8080:80" + volumes: + - ./docker/nginx/conf.d:/etc/nginx/conf.d + - ./public:/var/www/html/public + depends_on: + - ilyaguev_igor-indigolab-php + networks: + - indigolab-network + + ilyaguev_igor-indigolab-postgres: + image: postgres:latest + container_name: ilyaguev_igor-indigolab-postgres + restart: unless-stopped + environment: + POSTGRES_DB: ${POSTGRES_DB} + POSTGRES_USER: ${POSTGRES_USER} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} + POSTGRES_ROOT_PASSWORD: ${POSTGRES_ROOT_PASSWORD} + TZ: "Europe/Moscow" + ports: + - "${POSTGRES_PORT}:5432" + volumes: + - ./docker/pgdata:/var/lib/postgresql/data + networks: + - indigolab-network + + ilyaguev_igor-indigolab-redis: + image: redis:latest + container_name: ilyaguev_igor-indigolab-redis + restart: unless-stopped + ports: + - "6379:6379" + networks: + - indigolab-network + +volumes: + postgres_data: + +networks: + indigolab-network: + driver: bridge diff --git a/docker/.env.dist b/docker/.env.dist new file mode 100644 index 0000000..775ec2c --- /dev/null +++ b/docker/.env.dist @@ -0,0 +1,5 @@ +POSTGRES_DB=indigolab +POSTGRES_USER=postgres_user +POSTGRES_PASSWORD=postgres_password +POSTGRES_ROOT_PASSWORD=postgres_root_password +POSTGRES_PORT=5432 diff --git a/docker/nginx/conf.d/conf.d b/docker/nginx/conf.d/conf.d new file mode 100644 index 0000000..8ec6200 --- /dev/null +++ b/docker/nginx/conf.d/conf.d @@ -0,0 +1,27 @@ +server { + listen 80; + server_name localhost; + + root /var/www/html/public; + index index.php; + + location / { + try_files $uri /index.php$is_args$args; + } + + location ~ ^/index\.php(/|$) { + fastcgi_pass ilyaguev_igor-indigolab-php:9000; # Связь с PHP-FPM + fastcgi_split_path_info ^(.+\.php)(/.*)$; + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param DOCUMENT_ROOT $document_root; + internal; + } + + location ~ \.php$ { + return 404; + } + + error_log /var/log/nginx/project_error.log; + access_log /var/log/nginx/project_access.log; +} diff --git a/docker/php/Dockerfile b/docker/php/Dockerfile new file mode 100644 index 0000000..4f1060b --- /dev/null +++ b/docker/php/Dockerfile @@ -0,0 +1,44 @@ +FROM php:8.3-fpm + +# Устанавливаем необходимые зависимости +RUN apt-get update && apt-get install -y \ + git \ + libzip-dev \ + libpq-dev \ + unzip \ + && rm -rf /var/lib/apt/lists/* + +# Устанавливаем расширения PHP +RUN docker-php-ext-install zip pdo pdo_pgsql opcache + +# Настройка PHP +COPY docker/php/php.ini /usr/local/etc/php/conf.d/ + +# Устанавливаем Composer +RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" \ + && php composer-setup.php --install-dir=/usr/local/bin --filename=composer \ + && php -r "unlink('composer-setup.php');" + +# Устанавливаем Xdebug +RUN pecl install xdebug && docker-php-ext-enable xdebug + +# Копируем конфигурацию Xdebug +#COPY xdebug.ini /usr/local/etc/php/conf.d/xdebug.ini + +# Устанавливаем рабочую директорию +WORKDIR /var/www/html + +# Копируем только файлы, необходимые для установки зависимостей +COPY composer.json composer.lock symfony.lock ./ + +# Устанавливаем зависимости Composer +RUN composer install + +# Копируем весь исходный код +COPY . . + +# Указываем пользователя для выполнения команд +USER www-data + +# Права для веб-сервера +RUN chown -R www-data:www-data /var/www/html/var diff --git a/docker/php/conf.d/xdebug.ini b/docker/php/conf.d/xdebug.ini new file mode 100644 index 0000000..1904814 --- /dev/null +++ b/docker/php/conf.d/xdebug.ini @@ -0,0 +1,4 @@ +zend_extension=xdebug.so +xdebug.mode=develop,debug +xdebug.client_host=${XDEBUG_CLIENT_HOST} +xdebug.idekey=${XDEBUG_IDEKEY} diff --git a/docker/php/php.ini b/docker/php/php.ini new file mode 100644 index 0000000..e69de29