diff --git a/docker-compose.yml b/.dev/docker-compose.yml similarity index 96% rename from docker-compose.yml rename to .dev/docker-compose.yml index aad53f4..3c6e0ef 100644 --- a/docker-compose.yml +++ b/.dev/docker-compose.yml @@ -24,11 +24,13 @@ services: - "9001:9001" volumes: - "/var/run/docker.sock:/var/run/docker.sock" + - "./ssl:/etc/ssl" restart: always command: - "--providers.docker=true" - "--api.insecure=true" - "--ping" + - "--providers.file.filename=/etc/ssl/traefik.yml" - "--providers.docker.exposedByDefault=false" - "--entrypoints.web.address=:80" - "--entrypoints.web-secure.address=:443" @@ -40,7 +42,7 @@ services: composer-runtime: volumes: - - .:/app + - ..:/app image: siteworxpro/composer entrypoint: "/bin/sh -c 'while true; do sleep 30; done;'" environment: @@ -62,8 +64,8 @@ services: migration-container: volumes: - - ./db/migrations:/app/db/migrations - - ./bin:/app/bin + - ../db/migrations:/app/db/migrations + - ../bin:/app/bin image: siteworxpro/migrate:v4.18.3 working_dir: /app # entrypoint: "/bin/sh -c 'while true; do sleep 30; done;'" @@ -96,11 +98,11 @@ services: - "traefik.tcp.routers.grpc.service=api" container_name: dev-runtime volumes: - - .:/app + - ..:/app build: args: KAFKA_ENABLED: "1" - context: . + context: .. dockerfile: Dockerfile entrypoint: "/bin/sh -c 'while true; do sleep 30; done;'" depends_on: diff --git a/.dev/ssl/localhost.crt b/.dev/ssl/localhost.crt new file mode 100644 index 0000000..b6345ae --- /dev/null +++ b/.dev/ssl/localhost.crt @@ -0,0 +1,83 @@ +-----BEGIN CERTIFICATE----- +MIIEFzCCA52gAwIBAgIURfvF11Q9R3Ue38Tr0BzIoUe0TKQwCgYIKoZIzj0EAwMw +MDEuMCwGA1UEAxMlU2l0ZXdvcnggSW50ZXJtZWRpYXRlIEVDMzg0IEF1dGhvcml0 +eTAeFw0yNTEyMDQxNjM1NTFaFw0yNjEyMDQxNjM2MjFaMHExCzAJBgNVBAYTAlVT +MREwDwYDVQQIEwhWaXJnaW5pYTEVMBMGA1UEBxMMUHVyY2VsbHZpbGxlMSQwIgYD +VQQKExtTaXRld29yeCBQcm9mZXNzaW9uYWxzLCBMTEMxEjAQBgNVBAMTCWxvY2Fs +aG9zdDB2MBAGByqGSM49AgEGBSuBBAAiA2IABM+jXangYCOi01IMblAXJ6iFZE4v +SBBOZKNQCwGz8kKi5jyXtVwz6U26DMlBSK+InhhOFQlCRcP9ow8LtlQdaY2XnGKr +3X3zxdUZJVhLi/wog+I4igU3+xuyn1E/BgEZx6OCAjUwggIxMA4GA1UdDwEB/wQE +AwIHgDATBgNVHSUEDDAKBggrBgEFBQcDATAMBgNVHRMBAf8EAjAAMB0GA1UdDgQW +BBRAtanjiWMYAdpCCz0rEkyqf691bzAfBgNVHSMEGDAWgBQYBC15lPoGGGxbmwqY +MWL7jjI6azBJBggrBgEFBQcBAQQ9MDswOQYIKwYBBQUHMAGGLWh0dHBzOi8vdmF1 +bHQuc2l0ZXdvcnhwcm8uY29tL3YxL3N3eF9pbnQvb2NzcDAaBgNVHREEEzARggls +b2NhbGhvc3SHBH8AAAEwHAYDVR0gBBUwEzAIBgZngQwBAgIwBwYFZ4EMAQEwggE1 +BgNVHR8EggEsMIIBKDBioGCgXoZcaHR0cHM6Ly92YXVsdC5zaXRld29yeHByby5j +b20vdjEvc3d4X2ludC9pc3N1ZXIvMjVmMWRiNTAtZDQxOS1kZWQ3LTZiZjktZWNh +Y2E4NGEwMmY0L2NybC9wZW0wXqBcoFqGWGh0dHBzOi8vdmF1bHQuc2l0ZXdvcnhw +cm8uY29tL3YxL3N3eF9pbnQvaXNzdWVyLzI1ZjFkYjUwLWQ0MTktZGVkNy02YmY5 +LWVjYWNhODRhMDJmNC9jcmwwYqBgoF6GXGh0dHBzOi8vdmF1bHQuc2l0ZXdvcnhw +cm8uY29tL3YxL3N3eF9pbnQvaXNzdWVyLzI1ZjFkYjUwLWQ0MTktZGVkNy02YmY5 +LWVjYWNhODRhMDJmNC9jcmwvZGVyMAoGCCqGSM49BAMDA2gAMGUCMGxgZmKITQFu +H6j3j/t9MOTxhVsfOuoD0q3pMlp9d1u4Lg0THKUOzN06BVuXwC1eagIxAL2I/2a1 +MMJmhky2EavzOsYt37Ae+1KGyELiwcWe5f/lActlw97pqRajpmqEmdo7PA== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIEETCCAfmgAwIBAgIUIRpRFzFBITweYJETytgbPBgwbWgwDQYJKoZIhvcNAQEL +BQAwgZ0xCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhWaXJnaW5pYTEVMBMGA1UEBwwM +UHVyY2VsbHZpbGxlMSQwIgYDVQQKDBtTaXRld29yeCBQcm9mZXNzaW9uYWxzLCBM +TEMxFDASBgNVBAMMC1NXWCBSb290IENBMSgwJgYJKoZIhvcNAQkBFhl3ZWJtYXN0 +ZXJAc2l0ZXdvcnhwcm8uY29tMB4XDTIzMDMyMTE2MzAxNVoXDTMzMDMxODE2MzA0 +NVowMDEuMCwGA1UEAxMlU2l0ZXdvcnggSW50ZXJtZWRpYXRlIEVDMzg0IEF1dGhv +cml0eTB2MBAGByqGSM49AgEGBSuBBAAiA2IABIhlP1W1O1WjoDFGFi5XbE0zVy90 +76pQQ8VmSYtaZI9Jz5pAZTOQ073t/QkTWge8uhDaJ2J2uBhjQJGr5BPttvBcLJFI +52X7hJuck4oL0aukXiHYA5gZbC5LhKVvCyZcWqNjMGEwDgYDVR0PAQH/BAQDAgEG +MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFBgELXmU+gYYbFubCpgxYvuOMjpr +MB8GA1UdIwQYMBaAFHWCysIFrdsWYZJSjBO1pSQPETkTMA0GCSqGSIb3DQEBCwUA +A4ICAQBbw5roegt0tUc+gu0IcHDt56cUoqChmIZXzla8gTgg820ww/+Wm+vNAl8W +r3Y67LzK19CygoujD2o7M25syaByRiw9JdIfNGvBzklOOM+sus9DDmwSUBMCuljS +KLBhWzIrXDZwemzklGEbj+RL4o2ZiL01nx8xygDF55eaudNS0VzRzd2Hv0C+rm2i +nnwRNoKsL14YXc41rFBWwb5ViRuD2Wp0c9CivEOd4UNKgOnGyNxcNhjzNlY05t3c +NEeskEXiz21sj0vnrwM7olKyXPXDFUCCKGb21Sn9sWKldicumU1i1HdDGA1w50uh +NS4G4wqGQ8iZCq3h6JkpBMGPJPG3Dq6yuzrh8fmh56IqtKY4MxdKHb91MtFHnkw5 +jCrxqpTKShRyqcBSx8QmXRXpec5FEB88NQ3aKhtFlNqXYphNRAI9bLIyGkdxUF/r +PCkZkKBhbsRvXT8Ii/K1PQHzliQqJxXhrrJEsIg2jiSQItBg52ZySzuw+Y6++h11 +73XMKJ53oOeLcxvp2qJRwMkNTwVfNxDmKC0tIRdI+KoJYbYeN0Ev/pEdPdYl+hjY +uQhKMt1KtpUyYwPzTGPKGMnklKj/T3Qu7fmpsWxtAOuK7yLLMayBwXBlVBD23md+ +UAfPR3FfVX+aRqqsvT7WI+SnlycJuYXs41ZPxBjLq2aB7fhAwQ== +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIGIjCCBAqgAwIBAgIJAKU+Idu5bncNMA0GCSqGSIb3DQEBCwUAMIGdMQswCQYD +VQQGEwJVUzERMA8GA1UECAwIVmlyZ2luaWExFTATBgNVBAcMDFB1cmNlbGx2aWxs +ZTEkMCIGA1UECgwbU2l0ZXdvcnggUHJvZmVzc2lvbmFscywgTExDMRQwEgYDVQQD +DAtTV1ggUm9vdCBDQTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQHNpdGV3b3J4 +cHJvLmNvbTAeFw0yMDA5MDgxMjU3NTJaFw00MDA5MDMxMjU3NTJaMIGdMQswCQYD +VQQGEwJVUzERMA8GA1UECAwIVmlyZ2luaWExFTATBgNVBAcMDFB1cmNlbGx2aWxs +ZTEkMCIGA1UECgwbU2l0ZXdvcnggUHJvZmVzc2lvbmFscywgTExDMRQwEgYDVQQD +DAtTV1ggUm9vdCBDQTEoMCYGCSqGSIb3DQEJARYZd2VibWFzdGVyQHNpdGV3b3J4 +cHJvLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAN9JNyWot7VX +ODvru8S5/o6gdFuynA1l5T0uXSzWhROMYHndmY+n7pwQCwf1R8iLL3aat9sDRxqM +RRScD3nNW6UzC5xNz12wiuemf2KT82cTjmUBU3CvtjstbgkrQ/SrpR/Arvu2YwUe +tmL9ft/xaoGvZXx8LKpyRMrHA1FlS2st+RFWBC0yXTU/nL4/7YQKVEcbc3YZvgCT +P4/8pxH9u8W7kgnufQHHKEIZR9lxIUhQ7yvc61B3zMntbJsZV1N+0c7j5DXY5cfT +6zXlfG2hSX1dbhM56y8O8KiCFaWaDRZ9mwkfZGM0W58gkhXUPXOrIOwewLmvl2Z4 +Vu43UkLfKhtQApxk6zodHRq1e2rNWSpBCGznT9XyoeO/spJ7yggNkleTa+SnnlmV +rHJS/YUp3/jAvJY2bCHQKFu/mguMY3Ub2X6eEBsVZOmUqDMbya1TPP6GCVqh4gUu +yip6qS9UksaTF6IN3IcrGhwtTyvp8BFqwVA0tMhgraf1rv6ZoXjY/NDuGjE1xXJg +Hg+gg2pIIRcXjcsG1tXFXTgxDqoh127ADg/gtq9cIyarMx4LdNTjnR+CnhjqvRkT +uiUBB1bwDc9pbX0ulfnR+VuIZtQ6PSuWwChnMdNBKmCgQT1J1AHWpQqnFTjg42NV +5QAdFOQxAnsq2DxkurVFEz2J3euZx1ZdAgMBAAGjYzBhMB0GA1UdDgQWBBR1gsrC +Ba3bFmGSUowTtaUkDxE5EzAfBgNVHSMEGDAWgBR1gsrCBa3bFmGSUowTtaUkDxE5 +EzAPBgNVHRMBAf8EBTADAQH/MA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG9w0BAQsF +AAOCAgEAZDjIlaAoMfRGdb3/i40s6nN18iWN2Chttd8dLXgV+/SZ8GrAU89JNJrK +ODaLZT1wHeWVz0LP3miByuvfrnH4qzPEOI2L6zEy/FJr8SCivjm7aUExyb5kTSXp +LkwVcOI9UfQb6lCy9Gs/rUEcWQjs5KS3dy6ZwBMaywq6sRj7MeXmhqXhj7aAyWFA +psnQsuP2XweWa9OX6Z+u78sebfoiJlOEUvV9VRNHQYpLUd75p6sti1Dm9blWkZEO +hyssi3kOJMH+g5pc9xNbD9gS+/pFUWxEVAhHOc0xdEIcHfV5oiiOUDD5EOIPi3xv +/NYTV7o7pv2/QlH09vO2PHdsy07lhsg7NoM3U+zYq609Ox78/b4PNd+TkdtYKebO +VumZ0xXab0lWbTVuno52k473ODQRA/v9YWHtuovW0Lzf5fDcBhVXTDeW21SmMJIx +B+dgJDh7ql7ruZqjMj+kePjM9Mm+M5pDZ6vrEtgiR2yQj/IE+LoQh/bxFHpFkIK8 +I6AWoxABAvLZB+KHl1ufR5yOauJG2+SQRuzHNZvkAcdjmwpgfxcsB2mY7o0RbGmZ +VWm97P4P9iJhje/W4C0cGwVY5wRAMAg6SI1BpcW7YghB14UrKaxpEzHCdZIeeT94 +GYzN2XNSSGW3s1anFedd5PQyRM7PlJIcloLYrqyWW6M7OwWnMXA= +-----END CERTIFICATE----- \ No newline at end of file diff --git a/.dev/ssl/localhost.key b/.dev/ssl/localhost.key new file mode 100644 index 0000000..fd525ca --- /dev/null +++ b/.dev/ssl/localhost.key @@ -0,0 +1,6 @@ +-----BEGIN EC PRIVATE KEY----- +MIGkAgEBBDBrpJYaCMqgu490fpZoIphGVspE33v3JwyD9B55HwSX/jykySs9NTOv +68YndzE9LNCgBwYFK4EEACKhZANiAATPo12p4GAjotNSDG5QFyeohWROL0gQTmSj +UAsBs/JCouY8l7VcM+lNugzJQUiviJ4YThUJQkXD/aMPC7ZUHWmNl5xiq91988XV +GSVYS4v8KIPiOIoFN/sbsp9RPwYBGcc= +-----END EC PRIVATE KEY----- \ No newline at end of file diff --git a/.dev/ssl/traefik.yml b/.dev/ssl/traefik.yml new file mode 100644 index 0000000..04883da --- /dev/null +++ b/.dev/ssl/traefik.yml @@ -0,0 +1,14 @@ +tls: + stores: + default: + defaultCertificate: + certFile: /etc/ssl/localhost.crt + keyFile: /etc/ssl/localhost.key + + options: + default: + minVersion: VersionTLS13 + preferServerCipherSuites: true + + mintls13: + minVersion: VersionTLS13 \ No newline at end of file diff --git a/.run/ Compose Deployment.run.xml b/.run/ Compose Deployment.run.xml index 46b86bd..f5ff961 100644 --- a/.run/ Compose Deployment.run.xml +++ b/.run/ Compose Deployment.run.xml @@ -1,8 +1,8 @@ - + - diff --git a/makefile b/makefile index e4d4d80..6eb733f 100644 --- a/makefile +++ b/makefile @@ -2,8 +2,11 @@ SHELL := /bin/sh .DEFAULT_GOAL := help +# Docker Compose file +COMPOSE_FILE := -f .dev/docker-compose.yml + # Reusable vars -DOCKER := docker compose +DOCKER := docker compose $(COMPOSE_FILE) COMPOSER_RUNTIME := composer-runtime DEV_RUNTIME := dev-runtime MIGRATION_CONTAINER := migration-container @@ -12,8 +15,8 @@ PROTOC_GEN_DIR := ./protoc-gen-php-grpc-2025.1.5-darwin-arm64 PROTOC_GEN := $(PROTOC_GEN_DIR)/protoc-gen-php-grpc PROTOC_URL := https://github.com/roadrunner-server/roadrunner/releases/download/v2025.1.5/protoc-gen-php-grpc-2025.1.5-darwin-arm64.tar.gz -COMPOSER := $(DOCKER) exec $(COMPOSER_RUNTIME) sh -c DEV := $(DOCKER) exec $(DEV_RUNTIME) sh -c +COMPOSER := $(DOCKER) exec $(COMPOSER_RUNTIME) sh -c # Colors GREEN := \033[32m @@ -42,7 +45,7 @@ help: ## Show this help start: ## Start the development runtime container @printf "$(GREEN)$(ROCKET) Starting $(DEV_RUNTIME)$(RESET)\n" - $(DOCKER) up $(DEV_RUNTIME) -d --no-recreate + $(DOCKER) up $(DEV_RUNTIME) -d --no-recreate sh: ## Open a shell in the development runtime container @$(MAKE) start @@ -136,7 +139,7 @@ lint: ## Run linting (phpcs/phpstan) in composer runtime fmt: ## Format code (php-cs-fixer) @printf "$(MAGNIFY) $(GREEN)Formatting code$(RESET)\n" - @$(DOCKER) up $(COMPOSER_RUNTIME) -d --no-recreate + @$(DOCKER) up $(COMPOSER_RUNTIME) -d --no-recreate $(COMPOSER) "composer run-script tests:lint:fix" test: ## Run test suite (phpunit) @@ -152,7 +155,7 @@ test-coverage: ## Run test suite with coverage report # Convenience aliases dev: run ## Alias for start -ci: composer-install license-check lint test ## CI-like local flow +ci: composer-install migrate license-check lint test ## CI-like local flow down: stop ## Alias for stop up: start ## Alias for start diff --git a/src/Grpc.php b/src/Grpc.php index d8c2779..1b5f5b7 100644 --- a/src/Grpc.php +++ b/src/Grpc.php @@ -20,6 +20,10 @@ use Spiral\RoadRunner\Worker; */ class Grpc { + private const array SERVICES = [ + GreeterInterface::class => GreeterHandler::class, + ]; + /** * @throws \ReflectionException */ @@ -39,7 +43,10 @@ class Grpc 'debug' => Config::get('app.dev_mode'), ]); - $server->registerService(GreeterInterface::class, new GreeterHandler()); + foreach (self::SERVICES as $interface => $handler) { + $server->registerService($interface, new $handler()); + } + $server->serve(Worker::create()); return 0;