Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
RyuuKodex authored Oct 27, 2023
0 parents commit 5ad757c
Showing 38 changed files with 8,248 additions and 0 deletions.
27 changes: 27 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#############################
### IDE
#############################
# PhpStorm
/.idea

#############################
### Docker
#############################
# Currently used profile
/compose.override.yaml

#############################
### PHP / Symfony
#############################
# Vendors
app/vendor

# Cache and logs
app/var

# Code quality tools cache files
/app/.phpunit.result.cache
/app/.php-cs-fixer.cache

# Front-end bundles
app/public/bundles
25 changes: 25 additions & 0 deletions .github/workflows/deploy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: deploy
on:
push:
branches: [ "main" ]
paths: [ "**", "!**.md" ]
env:
PACKAGE_NAME: "ghcr.io/archi-tektur/symfony-project-bootstrap"
PACKAGE_VERSION: "2.0.0"
jobs:
deploy:
runs-on: ubuntu-22.04
timeout-minutes: 3
steps:
# Checkout repository
- { name: "Login to ghcr.io", uses: "docker/login-action@v2", with: { registry: "ghcr.io", username: "${{github.actor}}", password: "${{secrets.GITHUB_TOKEN}}" } }
- { name: "Clone git repository", uses: "actions/checkout@v3" }

# Build containers using minimal configuration created for CI
- { name: "Load CI env configuration", run: "ln -s ./etc/envs/compose.ci.yaml . && mv compose.ci.yaml compose.override.yaml" }
- { name: "Build app docker image", run: "docker build -t ${{ env.PACKAGE_NAME }}:${{ env.PACKAGE_VERSION }} ." }

# Publish tag and image
- { name: "Release tag", run: "git tag ${{ env.PACKAGE_VERSION }}" }
- { name: "Publish tag", run: "git push --tags" }
- { name: "Publish docker image", run: "docker push ${{ env.PACKAGE_NAME}}:${{ env.PACKAGE_VERSION }}" }
34 changes: 34 additions & 0 deletions .github/workflows/integrate.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
name: integrate
on:
pull_request:
paths: [ "**", "!**.md" ]
env:
PACKAGE_NAME: "ghcr.io/archi-tektur/symfony-project-bootstrap"
PACKAGE_VERSION: "2.0.0"
jobs:
integrate:
runs-on: ubuntu-22.04
timeout-minutes: 3
steps:
# Checkout repository
- { name: "Login to ghcr.io", uses: "docker/login-action@v2", with: { registry: "ghcr.io", username: "${{github.actor}}", password: "${{secrets.GITHUB_TOKEN}}" } }
- { name: "Clone git repository", uses: "actions/checkout@v3" }

# Build containers using minimal configuration created for CI
- { name: "Load CI env configuration", run: "ln -s ./etc/envs/compose.ci.yaml . && mv compose.ci.yaml compose.override.yaml" }
- { name: "Build app docker image", run: "docker build -t ${{ env.PACKAGE_NAME }}:${{ env.PACKAGE_VERSION }} ." }

- { name: "Pull up docker setup", run: "docker-compose up --detach" }

# Linting, code style, static analysis
- { name: "Lint Symfony service container", run: "docker-compose exec -T app bin/console lint:container" }
- { name: "Lint YAML config files", run: "docker-compose exec -T app bin/console lint:yaml config" }
- { name: "Lint PHP source code", run: "docker-compose exec -T app vendor/bin/php-cs-fixer fix --dry-run --using-cache no --allow-risky=yes" }
- { name: "Run code static analysis", run: "docker-compose exec -T app vendor/bin/phpstan analyse" }

# Unit tests
- { name: "Unit tests", run: "docker-compose exec -T app php bin/phpunit --do-not-cache-result --testsuite unit" }

# Functional tests
- { name: "Functional tests", run: "docker-compose exec -T app php bin/phpunit --do-not-cache-result --testsuite functional" }

24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#############################
### IDE
#############################
# PhpStorm
/.idea

#############################
### Docker
#############################
# Currently used profile
/compose.override.yaml

#############################
### PHP / Symfony
#############################
# Vendors
app/vendor

# Cache and logs
app/var

# Code quality tools cache files
/app/.phpunit.result.cache
/app/.php-cs-fixer.cache
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Changelog

All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.

## 2.0.0 (2023-19-05)
- upgrade symfony to version 6.3
- upgrade php caddy image to version 2.2.0
- changed file names and the way how environment is configured
- changed location of env compose files
- upgrade ci configuration

## 1.0.4 (2022-12-10)
- symfony security update

## 1.0.3 (2022-08-10)
- symfony security update

## 1.0.0 (2022-08-01)
- initial release
17 changes: 17 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM ghcr.io/archi-tektur/caddy-php:2.2.0 AS app

ENV VERSION="2.0.0"

COPY ./app /app
RUN composer install

RUN chmod --recursive a+r /app \
&& chmod --recursive a+x /app/bin/* \
&& chown --recursive www-data:www-data /app/var/log \
&& chmod --recursive a+w /app/var/log

ENV APP_ENV="prod"

USER www-data:www-data

HEALTHCHECK CMD curl --fail http://localhost || exit 1
139 changes: 139 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# Symfony Bootstrap

Modern Symfony (PHP) project template created in order to follow 12-factor-app principles. Great starter for small,
medium and large projects.

## Motivation

While working in few major IT companies in Poland, I saw how many people are struggling with creating simple, yet
effective work environment. Sometimes people were just following Symfony Docs - they of course are good for learning,
however they are not following the [12-Factor-App](https://12factor.net) recommendations. Also, the way how Symfony
recommends using Docker is far from perfect, hence I created this bootstrap.

## PHP, Symfony and the database

This project is using PHP in version **8.1.\** and Symfony framework with version **^6.1**. In the future, I plan to
update this repository to match next PHP and Symfony versions. Also, the MariaDB 10.6 is used.

## Required tools

Before we start, let's make sure that our host device has required programs. We will use `docker` and `docker compose`
to manage containers.

To create this bootstrap I used the tools in version listed below. I cannot guarantee that this configuration will work
automatically with newer versions.

```shell
docker --version
> Docker version 20.10.17, build 100c701

docker compose version
> Docker Compose version v2.6.1
```

## Building environment for development

First things first you have to copy the development environment template. It' located in `.devcontainer`, I'd reccomend
to leave it there and create a symbolic link.

```shell
ln -s ./etc/envs/compose.dev.yaml .
mv compose.dev.yaml compose.override.yaml
```

Now we'll use `docker` to build our image locally, with local architecture:

```shell
docker compose build
```

It may take few seconds, when it's completed proceed with running the container:

```shell
docker compose up --detach
```

Remember that you have installed the vendors in an image, however while creating container you've replaced built app
folder with empty one (repository has no `vendor` folder intentionally). So, we have to proceed once again with app
configuration:

```shell
docker compose exec app bash -ce "
composer install
chown -R $(id -u):$(id -g) .
"
```

Now you're all set, you can visit the [localhost with port 80](http://localhost), you should
see the Symfony default application web page.

Also, a GET endpoint [/api/hello-world](http://localhost/api/hello-world) was added to configure and show the functional
test environment. It will always return static data:
```json
{
"message": "Hello, world"
}
```

If for some reason you'd like to enter the container, use the command below.

```shell
docker compose exec app bash
```

## Removing local environment

You can remove local environment using the command below:

```shell
docker compose down --remove-orphans
```

## Assumptions

### Custom PHP image

In the main Dockerfile I used [caddy-php](https://github.com/archi-tektur/caddy-php-image): my own high-performance PHP
image that uses Caddy as a runner and php-fpm as a daemon.

```dockerfile
FROM ghcr.io/archi-tektur/caddy-php:2.2.0 AS app
```

You're free to change it to any image and configuration you'd like. You may read
[here](https://github.com/archi-tektur/caddy-php-image/README.md) what's bundled inside my image and create your own
with my approach as a guidelines.

### Application logs

Due to extensive configuration you will find all the logs stored in `./app/var/log` folder, including Caddy, php-fpm
access and error logs and xdebug outputs. Also files like `dev.log`, `prod.log` will be stored with all the messages
logged with PSR `LoggerInterface` and `monolog` package.

### Testing

Modern web applications must be well tested. To keep things simple I prepared ready to use suite for unit and functional
tests.

#### Unit
Use the command below to run unit tests. Initially this project contains
[one test](https://github.com/archi-tektur/symfony-bootstrap/app/tests/NullTest.php) with one assertion
(NullTest pattern).

```
docker compose exec app composer run-unit-tests
```

#### Functional

Use the command below to run functional tests:

```
docker compose exec app composer run-functional-tests
```

Functional test is testing here the hello-world endpoint.

## Troubleshooting

This section will be expanded as first problem will come.
8 changes: 8 additions & 0 deletions app/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
###> symfony/framework-bundle ###
APP_ENV="dev"
APP_SECRET="a9806d99cd5c1503d8af30c963c9411f"
###< symfony/framework-bundle ###

###> doctrine/doctrine-bundle ###
DATABASE_URL="mysql://user:password@mariadb:3306/symfony-bootstrap"
###< doctrine/doctrine-bundle ###
22 changes: 22 additions & 0 deletions app/.php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

$finder = new PhpCsFixer\Finder();
$finder
->in(__DIR__)
->exclude('var')
->exclude('vendor');

$config = new PhpCsFixer\Config();
$config
->setRules([
'@PhpCsFixer' => true,
'declare_strict_types' => true,
'ordered_class_elements' => false,
'php_unit_test_class_requires_covers' => false,
'php_unit_internal_class' => false,
])
->setFinder($finder);

return $config;
17 changes: 17 additions & 0 deletions app/bin/console
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env php
<?php

use App\Kernel;
use Symfony\Bundle\FrameworkBundle\Console\Application;

if (!is_file(dirname(__DIR__).'/vendor/autoload_runtime.php')) {
throw new LogicException('Symfony Runtime is missing. Try running "composer require symfony/runtime".');
}

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
$kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);

return new Application($kernel);
};
19 changes: 19 additions & 0 deletions app/bin/phpunit
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env php
<?php

if (!ini_get('date.timezone')) {
ini_set('date.timezone', 'UTC');
}

if (is_file(dirname(__DIR__).'/vendor/phpunit/phpunit/phpunit')) {
define('PHPUNIT_COMPOSER_INSTALL', dirname(__DIR__).'/vendor/autoload.php');
require PHPUNIT_COMPOSER_INSTALL;
PHPUnit\TextUI\Command::main();
} else {
if (!is_file(dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php')) {
echo "Unable to find the `simple-phpunit.php` script in `vendor/symfony/phpunit-bridge/bin/`.\n";
exit(1);
}

require dirname(__DIR__).'/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php';
}
Loading

0 comments on commit 5ad757c

Please sign in to comment.