├── .env
├── .env.dev
├── .env.prod
├── .env.stage
├── .env.test
├── .gitignore
├── .gitlab-ci.yml
├── README.md
├── assets
└── bootstrap.min.css
├── bin
├── console
└── phpunit
├── ci
├── check-connection
├── fetch-cluster-credentials
└── wait-for-rollout
├── composer.json
├── composer.lock
├── config
├── bootstrap.php
├── bundles.php
├── packages
│ ├── cache.yaml
│ ├── dev
│ │ ├── debug.yaml
│ │ ├── easy_log_handler.yaml
│ │ ├── monolog.yaml
│ │ ├── routing.yaml
│ │ ├── swiftmailer.yaml
│ │ └── web_profiler.yaml
│ ├── doctrine.yaml
│ ├── doctrine_migrations.yaml
│ ├── framework.yaml
│ ├── prod
│ │ ├── doctrine.yaml
│ │ └── monolog.yaml
│ ├── routing.yaml
│ ├── security.yaml
│ ├── sensio_framework_extra.yaml
│ ├── swiftmailer.yaml
│ ├── test
│ │ ├── framework.yaml
│ │ ├── monolog.yaml
│ │ ├── routing.yaml
│ │ ├── swiftmailer.yaml
│ │ └── web_profiler.yaml
│ ├── translation.yaml
│ ├── twig.yaml
│ └── validator.yaml
├── routes.yaml
├── routes
│ ├── annotations.yaml
│ └── dev
│ │ ├── twig.yaml
│ │ └── web_profiler.yaml
└── services.yaml
├── docker-compose.yml
├── docker
├── helm-gke
│ └── Dockerfile
├── mysql
│ ├── Dockerfile
│ ├── data
│ │ └── .gitkeep
│ └── init
│ │ └── products.sql
├── nginx
│ ├── Dockerfile
│ └── default.conf
└── php-fpm
│ ├── Dockerfile
│ └── default.ini
├── helm
├── .helmignore
├── Chart.yaml
├── templates
│ ├── deployment.tpl
│ ├── ingress.tpl
│ ├── mysql.deployment.yaml
│ ├── mysql.service.yaml
│ ├── nginx.deployment.yaml
│ ├── nginx.ingress.yaml
│ ├── nginx.service.yaml
│ ├── php-fpm.deployment.yaml
│ ├── php-fpm.service.yaml
│ └── service.tpl
└── values.yaml
├── phpunit.xml.dist
├── public
└── index.php
├── src
├── Controller
│ ├── .gitignore
│ ├── HealthController.php
│ └── ProductController.php
├── Entity
│ ├── .gitignore
│ └── Product.php
├── Form
│ └── ProductAddType.php
├── Kernel.php
├── Migrations
│ └── .gitignore
└── Repository
│ ├── .gitignore
│ └── ProductRepository.php
├── symfony.lock
├── templates
├── base.html.twig
└── product
│ ├── add.html.twig
│ └── show.html.twig
├── tests
├── .gitignore
├── EndToEnd
│ ├── collection.json
│ ├── env.dev.json
│ └── env.stage.json
├── Integration
│ └── Controller
│ │ └── ProductControllerTest.php
├── Support
│ ├── CsrfTokenManager.php
│ ├── Database.php
│ ├── HttpClient.php
│ ├── Kernel.php
│ └── Router.php
└── Unit
│ └── Controller
│ ├── HealthControllerTest.php
│ └── ProductControllerTest.php
└── translations
└── .gitignore
/.env:
--------------------------------------------------------------------------------
1 | ###> docker ###
2 | NGINX_VERSION=1.15
3 | PHP_VERSION=7.3
4 | MYSQL_VERSION=5.7
5 | MYSQL_DATABASE=app
6 | MYSQL_ROOT_PASSWORD=fP8cz7Q63nV
7 | ###< docker ###
8 |
--------------------------------------------------------------------------------
/.env.dev:
--------------------------------------------------------------------------------
1 | ###> symfony/framework-bundle ###
2 | APP_ENV=dev
3 | APP_SECRET=4c0ac06a5564e2ccb8b951f31db34099
4 | #TRUSTED_PROXIES=127.0.0.1,127.0.0.2
5 | #TRUSTED_HOSTS='^localhost|example\.com$'
6 | ###< symfony/framework-bundle ###
7 |
8 | ###> doctrine/doctrine-bundle ###
9 | # Format described at http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
10 | # For an SQLite database, use: "sqlite:///%kernel.project_dir%/var/data.db"
11 | # Configure your db driver and server_version in config/packages/doctrine.yaml
12 | DATABASE_URL=mysql://root:fP8cz7Q63nV@mysql:3306/app
13 | ###< doctrine/doctrine-bundle ###
14 |
15 | ###> symfony/swiftmailer-bundle ###
16 | # For Gmail as a transport, use: "gmail://username:password@localhost"
17 | # For a generic SMTP server, use: "smtp://localhost:25?encryption=&auth_mode="
18 | # Delivery is disabled by default via "null://localhost"
19 | MAILER_URL=null://localhost
20 | ###< symfony/swiftmailer-bundle ###
21 |
--------------------------------------------------------------------------------
/.env.prod:
--------------------------------------------------------------------------------
1 | ###> symfony/framework-bundle ###
2 | APP_ENV=prod
3 | APP_SECRET=6c8315b702166496a62a29ab8a643a2d292403df
4 | ###< symfony/framework-bundle ###
5 |
--------------------------------------------------------------------------------
/.env.stage:
--------------------------------------------------------------------------------
1 | ###> symfony/framework-bundle ###
2 | APP_ENV=stage
3 | APP_SECRET=7792eb5e9a9e5e1d6b9a5b98b3e1ae130552b13e
4 | ###< symfony/framework-bundle ###
5 |
--------------------------------------------------------------------------------
/.env.test:
--------------------------------------------------------------------------------
1 | ###> symfony/framework-bundle ###
2 | APP_ENV=test
3 | APP_SECRET=74d279aba0165f4bf0fd129f1e9300cf0ba7d607
4 | KERNEL_CLASS=App\Kernel
5 | ###< symfony/framework-bundle ###
6 |
7 | ###> doctrine/doctrine-bundle ###
8 | DATABASE_URL=mysql://root:fP8cz7Q63nV@mysql:3306/app
9 | ###< doctrine/doctrine-bundle ###
10 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | ###> symfony/framework-bundle ###
3 | /.env.local
4 | /.env.local.php
5 | /.env.*.local
6 | /public/bundles/
7 | /var/
8 | /vendor/
9 | ###< symfony/framework-bundle ###
10 |
11 | ###> symfony/phpunit-bridge ###
12 | .phpunit
13 | /phpunit.xml
14 | ###< symfony/phpunit-bridge ###
15 |
16 | ###> symfony/web-server-bundle ###
17 | /.web-server-pid
18 | ###< symfony/web-server-bundle ###
19 |
20 | ###> PhpStorm ###
21 | /.idea
22 | ###< PhpStorm ###
23 |
24 | ###> docker ###
25 | /docker/mysql/data/*
26 | !/docker/mysql/data/.gitkeep
27 | ###< docker ###
28 |
29 | .DS_Store
30 |
--------------------------------------------------------------------------------
/.gitlab-ci.yml:
--------------------------------------------------------------------------------
1 | image: docker:latest
2 |
3 | services:
4 | - docker:dind
5 |
6 | stages:
7 | - build
8 | - test
9 | - registry-update
10 | - stage-deployment
11 | - end-to-end-tests
12 | - production-deployment
13 |
14 | .build-template: &buildTemplate
15 | stage: build
16 | script:
17 | # Build the image
18 | - docker build --build-arg VERSION=$BUILD_VERSION --target $BUILD_TARGET -t $BUILD_IMAGE:$BUILD_TARGET -f $BUILD_DOCKERFILE $BUILD_CONTEXT
19 | after_script:
20 | # Save the image as an artifact
21 | - mkdir -p build/$BUILD_IMAGE
22 | - docker save $BUILD_IMAGE:$BUILD_TARGET -o build/$BUILD_IMAGE/$BUILD_TARGET.tar
23 | artifacts:
24 | name: $CI_JOB_NAME-${CI_COMMIT_SHA:0:8}
25 | expire_in: 1 day
26 | paths:
27 | - build/$BUILD_IMAGE
28 | dependencies: []
29 |
30 | build-php-fpm-test:
31 | <<: *buildTemplate
32 | variables:
33 | BUILD_IMAGE: symfony-dummy-project-php-fpm
34 | BUILD_TARGET: test
35 | BUILD_DOCKERFILE: docker/php-fpm/Dockerfile
36 | BUILD_CONTEXT: .
37 | before_script:
38 | # Export build version
39 | - source .env && export BUILD_VERSION=$PHP_VERSION
40 |
41 | build-php-fpm-prod:
42 | <<: *buildTemplate
43 | variables:
44 | BUILD_IMAGE: symfony-dummy-project-php-fpm
45 | BUILD_TARGET: prod
46 | BUILD_DOCKERFILE: docker/php-fpm/Dockerfile
47 | BUILD_CONTEXT: .
48 | before_script:
49 | # Export build version
50 | - source .env && export BUILD_VERSION=$PHP_VERSION
51 |
52 | build-nginx-prod:
53 | <<: *buildTemplate
54 | variables:
55 | BUILD_IMAGE: symfony-dummy-project-nginx
56 | BUILD_TARGET: prod
57 | BUILD_DOCKERFILE: docker/nginx/Dockerfile
58 | BUILD_CONTEXT: .
59 | before_script:
60 | # Export build version
61 | - source .env && export BUILD_VERSION=$NGINX_VERSION
62 |
63 | build-mysql-prod:
64 | <<: *buildTemplate
65 | variables:
66 | BUILD_IMAGE: symfony-dummy-project-mysql
67 | BUILD_TARGET: prod
68 | BUILD_DOCKERFILE: docker/mysql/Dockerfile
69 | BUILD_CONTEXT: docker/mysql
70 | before_script:
71 | # Export build version
72 | - source .env && export BUILD_VERSION=$MYSQL_VERSION
73 |
74 | unit-tests:
75 | stage: test
76 | before_script:
77 | # Load php image from the build stage
78 | - docker load -i build/symfony-dummy-project-php-fpm/test.tar
79 | script:
80 | - docker run --rm symfony-dummy-project-php-fpm:test bin/phpunit --testsuit unit --testdox
81 | dependencies:
82 | - build-php-fpm-test
83 |
84 | integration-tests:
85 | stage: test
86 | before_script:
87 | # Load php image from the build stage
88 | - docker load -i build/symfony-dummy-project-php-fpm/test.tar
89 | - docker load -i build/symfony-dummy-project-mysql/prod.tar
90 | # Start mysql
91 | - source .env
92 | - docker network create symfony-dummy-project-net
93 | - docker run --rm -d --network symfony-dummy-project-net --network-alias mysql -e MYSQL_DATABASE=$MYSQL_DATABASE -e MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD symfony-dummy-project-mysql:prod
94 | script:
95 | - docker run --rm --network symfony-dummy-project-net symfony-dummy-project-php-fpm:test sh -c "sh ci/check-connection mysql 3306 && bin/phpunit --testsuit integration --testdox"
96 | dependencies:
97 | - build-php-fpm-test
98 | - build-mysql-prod
99 |
100 | .registry-update-template: ®istryUpdateTemplate
101 | stage: registry-update
102 | before_script:
103 | # Load image from the build stage
104 | - docker load -i build/$BUILD_IMAGE/$BUILD_TARGET.tar
105 | script:
106 | # Tag the image
107 | - docker tag $BUILD_IMAGE:$BUILD_TARGET babenkoivan/$BUILD_IMAGE:${CI_COMMIT_SHA:0:8}
108 | # Push the image
109 | - echo $CONTAINER_REGISTRY_PASSWORD | docker login -u $CONTAINER_REGISTRY_USER --password-stdin
110 | - docker push babenkoivan/$BUILD_IMAGE:${CI_COMMIT_SHA:0:8}
111 | only:
112 | - master
113 |
114 | registry-update-php-fpm:
115 | <<: *registryUpdateTemplate
116 | variables:
117 | BUILD_IMAGE: symfony-dummy-project-php-fpm
118 | BUILD_TARGET: prod
119 | dependencies:
120 | - build-php-fpm-prod
121 |
122 | registry-update-nginx:
123 | <<: *registryUpdateTemplate
124 | variables:
125 | BUILD_IMAGE: symfony-dummy-project-nginx
126 | BUILD_TARGET: prod
127 | dependencies:
128 | - build-nginx-prod
129 |
130 | registry-update-mysql:
131 | <<: *registryUpdateTemplate
132 | variables:
133 | BUILD_IMAGE: symfony-dummy-project-mysql
134 | BUILD_TARGET: prod
135 | dependencies:
136 | - build-mysql-prod
137 |
138 | .deploy-template: &deployTemplate
139 | image: babenkoivan/helm-gke
140 | before_script:
141 | # Fetch cluster credentials
142 | - sh ci/fetch-cluster-credentials $SERVICE_ACCOUNT_KEY $CLUSTER_NAME $CLUSTER_ZONE
143 | script:
144 | - helm upgrade symfony-dummy-project helm --install --set-string phpfpm.env.plain.APP_ENV=$ENVIRONMENT,nginx.host=$HOST,imageTag=${CI_COMMIT_SHA:0:8} --namespace symfony-dummy-project
145 | dependencies: []
146 | only:
147 | - master
148 |
149 | deploy-staging:
150 | <<: *deployTemplate
151 | variables:
152 | ENVIRONMENT: stage
153 | CLUSTER_NAME: $CLUSTER_NAME_STAGE
154 | CLUSTER_ZONE: $CLUSTER_ZONE_STAGE
155 | HOST: $HOST_STAGE
156 | stage: stage-deployment
157 | after_script:
158 | # Wait for the rollout to complete
159 | - sh ci/wait-for-rollout symfony-dummy-project
160 |
161 | deploy-production:
162 | <<: *deployTemplate
163 | variables:
164 | ENVIRONMENT: prod
165 | CLUSTER_NAME: $CLUSTER_NAME_PROD
166 | CLUSTER_ZONE: $CLUSTER_ZONE_PROD
167 | HOST: $HOST_PROD
168 | stage: production-deployment
169 | when: manual
170 |
171 | end-to-end-test:
172 | stage: end-to-end-tests
173 | image:
174 | name: postman/newman:alpine
175 | entrypoint: [""]
176 | script:
177 | - newman run -e tests/EndToEnd/env.stage.json tests/EndToEnd/collection.json
178 | dependencies: []
179 | only:
180 | - master
181 |
182 | .rollback-template: &rollbackTemplate
183 | image: babenkoivan/helm-gke
184 | before_script:
185 | # Fetch cluster credentials
186 | - sh ci/fetch-cluster-credentials $SERVICE_ACCOUNT_KEY $CLUSTER_NAME $CLUSTER_ZONE
187 | script:
188 | - helm rollback symfony-dummy-project 0
189 | dependencies: []
190 | when: manual
191 | only:
192 | - master
193 |
194 | rollback-staging:
195 | <<: *rollbackTemplate
196 | variables:
197 | CLUSTER_NAME: $CLUSTER_NAME_STAGE
198 | CLUSTER_ZONE: $CLUSTER_ZONE_STAGE
199 | stage: stage-deployment
200 |
201 | rollback-production:
202 | <<: *rollbackTemplate
203 | variables:
204 | CLUSTER_NAME: $CLUSTER_NAME_PROD
205 | CLUSTER_ZONE: $CLUSTER_ZONE_PROD
206 | stage: production-deployment
207 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Symfony Dummy Project
2 |
3 | This project was created for **Let's Migrate Symfony Project to Kubernetes!** series:
4 | * [Part 1: Containerizing the Application](https://itnext.io/containerizing-symfony-application-a2a5a3bd5edc)
5 | * [Part 2: Publishing the Application with Helm](https://itnext.io/publishing-symfony-application-with-helm-ecb525b34289)
6 | * [Part 3: Testing the Application](https://medium.com/@babenko.i.a/testing-symfony-application-d02317d4018a)
7 | * [Part 4: Building a Continuous Delivery Pipeline](https://medium.com/@babenko.i.a/building-continuous-delivery-pipeline-2cc05e213935)
8 |
--------------------------------------------------------------------------------
/bin/console:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | getParameterOption(['--env', '-e'], null, true)) {
19 | putenv('APP_ENV='.$_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = $env);
20 | }
21 |
22 | if ($input->hasParameterOption('--no-debug', true)) {
23 | putenv('APP_DEBUG='.$_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = '0');
24 | }
25 |
26 | require dirname(__DIR__).'/config/bootstrap.php';
27 |
28 | if ($_SERVER['APP_DEBUG']) {
29 | umask(0000);
30 |
31 | if (class_exists(Debug::class)) {
32 | Debug::enable();
33 | }
34 | }
35 |
36 | $kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);
37 | $application = new Application($kernel);
38 | $application->run($input);
39 |
--------------------------------------------------------------------------------
/bin/phpunit:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env php
2 | =1.2)
9 | if (is_array($env = @include dirname(__DIR__).'/.env.local.php')) {
10 | $_SERVER += $env;
11 | $_ENV += $env;
12 | } elseif (!class_exists(Dotenv::class)) {
13 | throw new RuntimeException('Please run "composer require symfony/dotenv" to load the ".env" files configuring the application.');
14 | } else {
15 | // load all the .env files
16 | (new Dotenv())->loadEnv(dirname(__DIR__).'/.env');
17 | }
18 |
19 | $_SERVER['APP_ENV'] = $_ENV['APP_ENV'] = ($_SERVER['APP_ENV'] ?? $_ENV['APP_ENV'] ?? null) ?: 'dev';
20 | $_SERVER['APP_DEBUG'] = $_SERVER['APP_DEBUG'] ?? $_ENV['APP_DEBUG'] ?? 'prod' !== $_SERVER['APP_ENV'];
21 | $_SERVER['APP_DEBUG'] = $_ENV['APP_DEBUG'] = (int) $_SERVER['APP_DEBUG'] || filter_var($_SERVER['APP_DEBUG'], FILTER_VALIDATE_BOOLEAN) ? '1' : '0';
22 |
--------------------------------------------------------------------------------
/config/bundles.php:
--------------------------------------------------------------------------------
1 | ['all' => true],
5 | Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle::class => ['all' => true],
6 | Doctrine\Bundle\DoctrineBundle\DoctrineBundle::class => ['all' => true],
7 | Doctrine\Bundle\MigrationsBundle\DoctrineMigrationsBundle::class => ['all' => true],
8 | Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
9 | Symfony\Bundle\SwiftmailerBundle\SwiftmailerBundle::class => ['all' => true],
10 | Symfony\Bundle\TwigBundle\TwigBundle::class => ['all' => true],
11 | Symfony\Bundle\WebProfilerBundle\WebProfilerBundle::class => ['dev' => true, 'test' => true],
12 | Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
13 | Symfony\Bundle\DebugBundle\DebugBundle::class => ['dev' => true, 'test' => true],
14 | Symfony\Bundle\MakerBundle\MakerBundle::class => ['dev' => true],
15 | Symfony\Bundle\WebServerBundle\WebServerBundle::class => ['dev' => true],
16 | ];
17 |
--------------------------------------------------------------------------------
/config/packages/cache.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | cache:
3 | # Put the unique name of your app here: the prefix seed
4 | # is used to compute stable namespaces for cache keys.
5 | #prefix_seed: your_vendor_name/app_name
6 |
7 | # The app cache caches to the filesystem by default.
8 | # Other options include:
9 |
10 | # Redis
11 | #app: cache.adapter.redis
12 | #default_redis_provider: redis://localhost
13 |
14 | # APCu (not recommended with heavy random-write workloads as memory fragmentation can cause perf issues)
15 | #app: cache.adapter.apcu
16 |
17 | # Namespaced pools use the above "app" backend by default
18 | #pools:
19 | #my.dedicated.cache: ~
20 |
--------------------------------------------------------------------------------
/config/packages/dev/debug.yaml:
--------------------------------------------------------------------------------
1 | debug:
2 | # Forwards VarDumper Data clones to a centralized server allowing to inspect dumps on CLI or in your browser.
3 | # See the "server:dump" command to start a new server.
4 | dump_destination: "tcp://%env(VAR_DUMPER_SERVER)%"
5 |
--------------------------------------------------------------------------------
/config/packages/dev/easy_log_handler.yaml:
--------------------------------------------------------------------------------
1 | services:
2 | EasyCorp\EasyLog\EasyLogHandler:
3 | public: false
4 | arguments: ['%kernel.logs_dir%/%kernel.environment%.log']
5 |
6 | #// FIXME: How to add this configuration automatically without messing up with the monolog configuration?
7 | #monolog:
8 | # handlers:
9 | # buffered:
10 | # type: buffer
11 | # handler: easylog
12 | # channels: ['!event']
13 | # level: debug
14 | # easylog:
15 | # type: service
16 | # id: EasyCorp\EasyLog\EasyLogHandler
17 |
--------------------------------------------------------------------------------
/config/packages/dev/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: stream
5 | path: "%kernel.logs_dir%/%kernel.environment%.log"
6 | level: debug
7 | channels: ["!event"]
8 | # uncomment to get logging in your browser
9 | # you may have to allow bigger header sizes in your Web server configuration
10 | #firephp:
11 | # type: firephp
12 | # level: info
13 | #chromephp:
14 | # type: chromephp
15 | # level: info
16 | console:
17 | type: console
18 | process_psr_3_messages: false
19 | channels: ["!event", "!doctrine", "!console"]
20 |
--------------------------------------------------------------------------------
/config/packages/dev/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: true
4 |
--------------------------------------------------------------------------------
/config/packages/dev/swiftmailer.yaml:
--------------------------------------------------------------------------------
1 | # See https://symfony.com/doc/current/email/dev_environment.html
2 | swiftmailer:
3 | # send all emails to a specific address
4 | #delivery_addresses: ['me@example.com']
5 |
--------------------------------------------------------------------------------
/config/packages/dev/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler:
2 | toolbar: true
3 | intercept_redirects: false
4 |
5 | framework:
6 | profiler: { only_exceptions: false }
7 |
--------------------------------------------------------------------------------
/config/packages/doctrine.yaml:
--------------------------------------------------------------------------------
1 | parameters:
2 | # Adds a fallback DATABASE_URL if the env var is not set.
3 | # This allows you to run cache:warmup even if your
4 | # environment variables are not available yet.
5 | # You should not need to change this value.
6 | env(DATABASE_URL): ''
7 |
8 | doctrine:
9 | dbal:
10 | # configure these for your database server
11 | driver: 'pdo_mysql'
12 | server_version: '%env(MYSQL_VERSION)%'
13 | charset: utf8mb4
14 | default_table_options:
15 | charset: utf8mb4
16 | collate: utf8mb4_unicode_ci
17 |
18 | url: '%env(resolve:DATABASE_URL)%'
19 | orm:
20 | auto_generate_proxy_classes: true
21 | naming_strategy: doctrine.orm.naming_strategy.underscore
22 | auto_mapping: true
23 | mappings:
24 | App:
25 | is_bundle: false
26 | type: annotation
27 | dir: '%kernel.project_dir%/src/Entity'
28 | prefix: 'App\Entity'
29 | alias: App
30 |
--------------------------------------------------------------------------------
/config/packages/doctrine_migrations.yaml:
--------------------------------------------------------------------------------
1 | doctrine_migrations:
2 | dir_name: '%kernel.project_dir%/src/Migrations'
3 | # namespace is arbitrary but should be different from App\Migrations
4 | # as migrations classes should NOT be autoloaded
5 | namespace: DoctrineMigrations
6 |
--------------------------------------------------------------------------------
/config/packages/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | secret: '%env(APP_SECRET)%'
3 | #default_locale: en
4 | #csrf_protection: true
5 | #http_method_override: true
6 |
7 | # Enables session support. Note that the session will ONLY be started if you read or write from it.
8 | # Remove or comment this section to explicitly disable session support.
9 | session:
10 | handler_id: ~
11 | cookie_secure: auto
12 | cookie_samesite: lax
13 |
14 | #esi: true
15 | #fragments: true
16 | php_errors:
17 | log: true
18 |
--------------------------------------------------------------------------------
/config/packages/prod/doctrine.yaml:
--------------------------------------------------------------------------------
1 | doctrine:
2 | orm:
3 | auto_generate_proxy_classes: false
4 | metadata_cache_driver:
5 | type: service
6 | id: doctrine.system_cache_provider
7 | query_cache_driver:
8 | type: service
9 | id: doctrine.system_cache_provider
10 | result_cache_driver:
11 | type: service
12 | id: doctrine.result_cache_provider
13 |
14 | services:
15 | doctrine.result_cache_provider:
16 | class: Symfony\Component\Cache\DoctrineProvider
17 | public: false
18 | arguments:
19 | - '@doctrine.result_cache_pool'
20 | doctrine.system_cache_provider:
21 | class: Symfony\Component\Cache\DoctrineProvider
22 | public: false
23 | arguments:
24 | - '@doctrine.system_cache_pool'
25 |
26 | framework:
27 | cache:
28 | pools:
29 | doctrine.result_cache_pool:
30 | adapter: cache.app
31 | doctrine.system_cache_pool:
32 | adapter: cache.system
33 |
--------------------------------------------------------------------------------
/config/packages/prod/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: fingers_crossed
5 | action_level: error
6 | handler: nested
7 | excluded_404s:
8 | # regex: exclude all 404 errors from the logs
9 | - ^/
10 | nested:
11 | type: stream
12 | path: "%kernel.logs_dir%/%kernel.environment%.log"
13 | level: debug
14 | console:
15 | type: console
16 | process_psr_3_messages: false
17 | channels: ["!event", "!doctrine"]
18 | deprecation:
19 | type: stream
20 | path: "%kernel.logs_dir%/%kernel.environment%.deprecations.log"
21 | deprecation_filter:
22 | type: filter
23 | handler: deprecation
24 | max_level: info
25 | channels: ["php"]
26 |
--------------------------------------------------------------------------------
/config/packages/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: ~
4 | utf8: true
5 |
--------------------------------------------------------------------------------
/config/packages/security.yaml:
--------------------------------------------------------------------------------
1 | security:
2 | # https://symfony.com/doc/current/security.html#where-do-users-come-from-user-providers
3 | providers:
4 | in_memory: { memory: ~ }
5 | firewalls:
6 | dev:
7 | pattern: ^/(_(profiler|wdt)|css|images|js)/
8 | security: false
9 | main:
10 | anonymous: true
11 |
12 | # activate different ways to authenticate
13 |
14 | # http_basic: true
15 | # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
16 |
17 | # form_login: true
18 | # https://symfony.com/doc/current/security/form_login_setup.html
19 |
20 | # Easy way to control access for large sections of your site
21 | # Note: Only the *first* access control that matches will be used
22 | access_control:
23 | # - { path: ^/admin, roles: ROLE_ADMIN }
24 | # - { path: ^/profile, roles: ROLE_USER }
25 |
--------------------------------------------------------------------------------
/config/packages/sensio_framework_extra.yaml:
--------------------------------------------------------------------------------
1 | sensio_framework_extra:
2 | router:
3 | annotations: false
4 |
--------------------------------------------------------------------------------
/config/packages/swiftmailer.yaml:
--------------------------------------------------------------------------------
1 | swiftmailer:
2 | url: '%env(MAILER_URL)%'
3 | spool: { type: 'memory' }
4 |
--------------------------------------------------------------------------------
/config/packages/test/framework.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | test: true
3 | session:
4 | storage_id: session.storage.mock_file
5 |
--------------------------------------------------------------------------------
/config/packages/test/monolog.yaml:
--------------------------------------------------------------------------------
1 | monolog:
2 | handlers:
3 | main:
4 | type: stream
5 | path: "%kernel.logs_dir%/%kernel.environment%.log"
6 | level: debug
7 | channels: ["!event"]
8 |
--------------------------------------------------------------------------------
/config/packages/test/routing.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | router:
3 | strict_requirements: true
4 |
--------------------------------------------------------------------------------
/config/packages/test/swiftmailer.yaml:
--------------------------------------------------------------------------------
1 | swiftmailer:
2 | disable_delivery: true
3 |
--------------------------------------------------------------------------------
/config/packages/test/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler:
2 | toolbar: false
3 | intercept_redirects: false
4 |
5 | framework:
6 | profiler: { collect: false }
7 |
--------------------------------------------------------------------------------
/config/packages/translation.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | default_locale: '%locale%'
3 | translator:
4 | default_path: '%kernel.project_dir%/translations'
5 | fallbacks:
6 | - '%locale%'
7 |
--------------------------------------------------------------------------------
/config/packages/twig.yaml:
--------------------------------------------------------------------------------
1 | twig:
2 | default_path: '%kernel.project_dir%/templates'
3 | debug: '%kernel.debug%'
4 | strict_variables: '%kernel.debug%'
5 | form_themes: ['bootstrap_4_layout.html.twig']
6 |
--------------------------------------------------------------------------------
/config/packages/validator.yaml:
--------------------------------------------------------------------------------
1 | framework:
2 | validation:
3 | email_validation_mode: html5
4 |
--------------------------------------------------------------------------------
/config/routes.yaml:
--------------------------------------------------------------------------------
1 | #index:
2 | # path: /
3 | # controller: App\Controller\DefaultController::index
4 |
--------------------------------------------------------------------------------
/config/routes/annotations.yaml:
--------------------------------------------------------------------------------
1 | controllers:
2 | resource: ../../src/Controller/
3 | type: annotation
4 |
--------------------------------------------------------------------------------
/config/routes/dev/twig.yaml:
--------------------------------------------------------------------------------
1 | _errors:
2 | resource: '@TwigBundle/Resources/config/routing/errors.xml'
3 | prefix: /_error
4 |
--------------------------------------------------------------------------------
/config/routes/dev/web_profiler.yaml:
--------------------------------------------------------------------------------
1 | web_profiler_wdt:
2 | resource: '@WebProfilerBundle/Resources/config/routing/wdt.xml'
3 | prefix: /_wdt
4 |
5 | web_profiler_profiler:
6 | resource: '@WebProfilerBundle/Resources/config/routing/profiler.xml'
7 | prefix: /_profiler
8 |
--------------------------------------------------------------------------------
/config/services.yaml:
--------------------------------------------------------------------------------
1 | # This file is the entry point to configure your own services.
2 | # Files in the packages/ subdirectory configure your dependencies.
3 |
4 | # Put parameters here that don't need to change on each machine where the app is deployed
5 | # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
6 | parameters:
7 | locale: 'en'
8 |
9 | services:
10 | # default configuration for services in *this* file
11 | _defaults:
12 | autowire: true # Automatically injects dependencies in your services.
13 | autoconfigure: true # Automatically registers your services as commands, event subscribers, etc.
14 |
15 | # makes classes in src/ available to be used as services
16 | # this creates a service per class whose id is the fully-qualified class name
17 | App\:
18 | resource: '../src/*'
19 | exclude: '../src/{DependencyInjection,Entity,Migrations,Tests,Kernel.php}'
20 |
21 | # controllers are imported separately to make sure services can be injected
22 | # as action arguments even if you don't extend any base controller class
23 | App\Controller\:
24 | resource: '../src/Controller'
25 | tags: ['controller.service_arguments']
26 |
27 | # add more service definitions when explicit configuration is needed
28 | # please note that last definitions always *replace* previous ones
29 |
--------------------------------------------------------------------------------
/docker-compose.yml:
--------------------------------------------------------------------------------
1 | version: '3.7'
2 |
3 | services:
4 | nginx:
5 | build:
6 | args:
7 | VERSION: $NGINX_VERSION
8 | context: .
9 | dockerfile: ./docker/nginx/Dockerfile
10 | target: dev
11 | volumes:
12 | - ./assets:/app/public
13 | depends_on:
14 | - php-fpm
15 | ports:
16 | - 8000:80
17 | php-fpm:
18 | build:
19 | args:
20 | VERSION: $PHP_VERSION
21 | context: .
22 | dockerfile: ./docker/php-fpm/Dockerfile
23 | target: dev
24 | volumes:
25 | - .:/app
26 | command: sh -c 'composer install --no-interaction --optimize-autoloader && php-fpm'
27 | depends_on:
28 | - mysql
29 | mysql:
30 | build:
31 | args:
32 | VERSION: $MYSQL_VERSION
33 | context: ./docker/mysql
34 | environment:
35 | MYSQL_DATABASE: $MYSQL_DATABASE
36 | MYSQL_ROOT_PASSWORD: $MYSQL_ROOT_PASSWORD
37 | volumes:
38 | - ./docker/mysql/data:/var/lib/mysql
39 |
40 |
--------------------------------------------------------------------------------
/docker/helm-gke/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM google/cloud-sdk:alpine
2 |
3 | # Install system dependencies
4 | RUN apk add --update --no-cache openssl
5 |
6 | # Install kubectl
7 | RUN gcloud components install --quiet kubectl
8 |
9 | # Install helm
10 | ARG HELM_VERSION
11 | RUN curl https://raw.githubusercontent.com/helm/helm/master/scripts/get > ~/get_helm.sh && \
12 | chmod +x ~/get_helm.sh && \
13 | if [ -z $HELM_VERSION ]; then ~/get_helm.sh; else ~/get_helm.sh -v $HELM_VERSION; fi && \
14 | rm ~/get_helm.sh
15 |
--------------------------------------------------------------------------------
/docker/mysql/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG VERSION
2 |
3 | FROM mysql:${VERSION} as prod
4 |
5 | # Copy sql dump to initialize tables on stratup
6 | COPY init /docker-entrypoint-initdb.d
7 |
--------------------------------------------------------------------------------
/docker/mysql/data/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/babenkoivan/symfony-dummy-project/92123cd2e9644f822a8d5dec2c4a96c081971acc/docker/mysql/data/.gitkeep
--------------------------------------------------------------------------------
/docker/mysql/init/products.sql:
--------------------------------------------------------------------------------
1 | CREATE TABLE `products` (
2 | `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
3 | `name` varchar(255) NOT NULL DEFAULT '',
4 | `price` float NOT NULL,
5 | PRIMARY KEY (`id`)
6 | ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
7 |
8 | LOCK TABLES `products` WRITE;
9 |
10 | INSERT INTO `products` (`id`, `name`, `price`)
11 | VALUES
12 | (1,'Product 1',100),
13 | (2,'Product 2',200),
14 | (3,'Product 3',300);
15 |
16 | UNLOCK TABLES;
17 |
--------------------------------------------------------------------------------
/docker/nginx/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG VERSION
2 |
3 | # Dev image
4 | FROM nginx:${VERSION}-alpine as dev
5 |
6 | # Copy nginx config
7 | COPY ./docker/nginx/default.conf /etc/nginx/conf.d/default.conf
8 |
9 | # Prod image
10 | FROM dev as prod
11 |
12 | # Copy assets
13 | COPY ./assets /app/public
14 |
--------------------------------------------------------------------------------
/docker/nginx/default.conf:
--------------------------------------------------------------------------------
1 | server {
2 | root /app/public;
3 |
4 | location / {
5 | try_files $uri /index.php$is_args$args;
6 | }
7 |
8 | location ~ ^/index\.php(/|$) {
9 | fastcgi_pass php-fpm:9000;
10 | fastcgi_split_path_info ^(.+\.php)(/.*)$;
11 | include fastcgi_params;
12 | fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
13 | fastcgi_param DOCUMENT_ROOT $document_root;
14 | internal;
15 | }
16 |
17 | location ~ \.php$ {
18 | return 404;
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/docker/php-fpm/Dockerfile:
--------------------------------------------------------------------------------
1 | ARG VERSION
2 |
3 | # Dev image
4 | FROM php:${VERSION}-fpm-alpine AS dev
5 |
6 | ## Install system dependencies
7 | RUN apk update && \
8 | apk add --no-cache --virtual dev-deps git autoconf gcc g++ make && \
9 | apk add --no-cache zlib-dev libzip-dev
10 |
11 | ## Install php extensions
12 | RUN pecl install xdebug && \
13 | docker-php-ext-enable xdebug && \
14 | docker-php-ext-install pdo_mysql zip
15 |
16 | ## Copy php default configuration
17 | COPY ./docker/php-fpm/default.ini /usr/local/etc/php/conf.d/default.ini
18 |
19 | ENV APP_ENV=dev
20 | WORKDIR /app
21 |
22 | ## Install composer
23 | RUN wget https://getcomposer.org/installer && \
24 | php installer --install-dir=/usr/local/bin/ --filename=composer && \
25 | rm installer && \
26 | composer global require hirak/prestissimo
27 |
28 | # Test image
29 | FROM dev AS test
30 |
31 | WORKDIR /app
32 |
33 | ## Copy project files to workdir
34 | COPY . .
35 |
36 | ## Install application dependencies
37 | RUN composer install --no-interaction --optimize-autoloader
38 |
39 | ## Change files owner to php-fpm default user
40 | RUN chown -R www-data:www-data .
41 |
42 | # Prod image
43 | FROM test AS prod
44 |
45 | ENV APP_ENV=prod
46 | WORKDIR /app
47 |
48 | ## Remove dev dependencies
49 | RUN composer install --no-dev --no-interaction --optimize-autoloader
50 |
51 | ## Disable xdebug on production
52 | RUN rm /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
53 |
54 | ## Cleanup
55 | RUN apk del dev-deps && \
56 | composer global remove hirak/prestissimo && \
57 | rm /usr/local/bin/composer
58 |
59 |
--------------------------------------------------------------------------------
/docker/php-fpm/default.ini:
--------------------------------------------------------------------------------
1 | memory_limit = 256M
2 | error_reporting = E_ERROR
3 |
--------------------------------------------------------------------------------
/helm/.helmignore:
--------------------------------------------------------------------------------
1 | # OS specific
2 | .DS_Store
3 |
4 | # Common backup files
5 | *.swp
6 | *.bak
7 | *.tmp
8 | *~
9 |
--------------------------------------------------------------------------------
/helm/Chart.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: v1
2 | appVersion: "1.0"
3 | description: A Helm chart for Symfony dummy project
4 | name: symfony-dummy-project
5 | version: 1.0.0
6 |
--------------------------------------------------------------------------------
/helm/templates/deployment.tpl:
--------------------------------------------------------------------------------
1 | {{- define "deployment.template" -}}
2 | apiVersion: apps/v1
3 | kind: Deployment
4 | metadata:
5 | name: {{ .service.name | quote }}
6 | spec:
7 | replicas: {{ .service.replicas | default 1 }}
8 | selector:
9 | matchLabels:
10 | service: {{ .service.name | quote }}
11 | template:
12 | metadata:
13 | labels:
14 | service: {{ .service.name | quote }}
15 | spec:
16 | containers:
17 | - name: {{ .service.name | quote }}
18 | image: {{ printf "%s:%s" .service.image .imageTag | quote }}
19 | imagePullPolicy: {{ .service.pullPolicy | default "IfNotPresent" | quote }}
20 | resources:
21 | {{ toYaml .resources | trim | indent 12 }}
22 | {{- if (.service.probes) }}
23 | livenessProbe:
24 | httpGet:
25 | path: {{ .service.probes.liveness | quote }}
26 | port: {{ .service.port }}
27 | readinessProbe:
28 | httpGet:
29 | path: {{ .service.probes.readiness | quote }}
30 | port: {{ .service.port }}
31 | {{- end }}
32 | {{- if (.service.env) }}
33 | env:
34 | {{- if (.service.env.plain) }}
35 | {{- range $envName, $envValue := .service.env.plain }}
36 | - name: {{ $envName | quote }}
37 | value: {{ $envValue }}
38 | {{- end }}
39 | {{- end }}
40 | {{- if (.service.env.secret) }}
41 | {{- range $envName, $secret := .service.env.secret }}
42 | - name: {{ $envName | quote }}
43 | valueFrom:
44 | secretKeyRef:
45 | name: {{ $secret.name | quote }}
46 | key: {{ $secret.key | quote }}
47 | {{- end }}
48 | {{- end }}
49 | {{- end }}
50 | {{- end -}}
51 |
--------------------------------------------------------------------------------
/helm/templates/ingress.tpl:
--------------------------------------------------------------------------------
1 | {{- define "ingress.template" -}}
2 | apiVersion: extensions/v1beta1
3 | kind: Ingress
4 | metadata:
5 | name: {{ .service.name | quote }}
6 | spec:
7 | backend:
8 | serviceName: {{ .service.name | quote }}
9 | servicePort: {{ .service.port }}
10 | {{- end -}}
11 |
--------------------------------------------------------------------------------
/helm/templates/mysql.deployment.yaml:
--------------------------------------------------------------------------------
1 | {{ include "deployment.template" (dict "service" .Values.mysql "imageTag" .Values.imageTag "resources" .Values.resources) }}
2 |
--------------------------------------------------------------------------------
/helm/templates/mysql.service.yaml:
--------------------------------------------------------------------------------
1 | {{ include "service.template" (dict "service" .Values.mysql) }}
2 |
--------------------------------------------------------------------------------
/helm/templates/nginx.deployment.yaml:
--------------------------------------------------------------------------------
1 | {{ include "deployment.template" (dict "service" .Values.nginx "imageTag" .Values.imageTag "resources" .Values.resources) }}
2 |
--------------------------------------------------------------------------------
/helm/templates/nginx.ingress.yaml:
--------------------------------------------------------------------------------
1 | {{ include "ingress.template" (dict "service" .Values.nginx) }}
2 |
--------------------------------------------------------------------------------
/helm/templates/nginx.service.yaml:
--------------------------------------------------------------------------------
1 | {{ include "service.template" (dict "service" .Values.nginx) }}
2 |
--------------------------------------------------------------------------------
/helm/templates/php-fpm.deployment.yaml:
--------------------------------------------------------------------------------
1 | {{ include "deployment.template" (dict "service" .Values.phpfpm "imageTag" .Values.imageTag "resources" .Values.resources) }}
2 |
--------------------------------------------------------------------------------
/helm/templates/php-fpm.service.yaml:
--------------------------------------------------------------------------------
1 | {{ include "service.template" (dict "service" .Values.phpfpm) }}
2 |
--------------------------------------------------------------------------------
/helm/templates/service.tpl:
--------------------------------------------------------------------------------
1 | {{- define "service.template" -}}
2 | apiVersion: v1
3 | kind: Service
4 | metadata:
5 | name: {{ .service.name | quote }}
6 | spec:
7 | type: NodePort
8 | ports:
9 | - port: {{ .service.port }}
10 | selector:
11 | service: {{ .service.name | quote }}
12 | {{- end -}}
13 |
--------------------------------------------------------------------------------
/helm/values.yaml:
--------------------------------------------------------------------------------
1 | resources:
2 | limits:
3 | cpu: 2
4 | memory: 1024Mi
5 | requests:
6 | cpu: 0.25
7 | memory: 256Mi
8 |
9 | mysql:
10 | name: "mysql"
11 | image: "babenkoivan/symfony-dummy-project-mysql"
12 | port: 3306
13 | env:
14 | secret:
15 | MYSQL_DATABASE:
16 | name: "database-secret"
17 | key: "database"
18 | MYSQL_ROOT_PASSWORD:
19 | name: "database-secret"
20 | key: "password"
21 |
22 | nginx:
23 | name: "nginx"
24 | image: "babenkoivan/symfony-dummy-project-nginx"
25 | port: 80
26 | probes:
27 | liveness: /healthz
28 | readiness: /healthz
29 |
30 | phpfpm:
31 | name: "php-fpm"
32 | image: "babenkoivan/symfony-dummy-project-php-fpm"
33 | port: 9000
34 | env:
35 | secret:
36 | DATABASE_URL:
37 | name: "database-secret"
38 | key: "url"
39 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
Only today! Buy for {{ product.price }}$!
14 |