Skip to content

Commit

Permalink
Added Docker Compose support to simplify local development (#47)
Browse files Browse the repository at this point in the history
* Added Docker Compose support to simplify local development

* Got app running PHP on nginx, fixed permissions issue with tmp, added integration for health check endpoint

* Updated to mount the nginx conf as a volume to ease development, switched default port to 8080 for portability

* Trying to get Xdebug working

* Got Xdebug working

* Removed unneeded IDE key from Xdebug config

* Fixed issues with aphiria service, added composer service, added CI for Docker images

* Trying to fix Docker Compose in CI

* Trying to fix Docker Compose in CI

* Added Composer root version so that the latest can be discerned without needing Git installed in the Docker image

* Updated docker compose commands in CI to use modern syntax

* Added step to install dependencies

* Fixed missing strategy

* Updated names of steps in Docker job, added commented-out steps that will eventually be re-enabledF

* Updated README to document Docker Compose

* Updated CHANGELOG
  • Loading branch information
davidbyoung authored Dec 4, 2024
1 parent a70d324 commit a297844
Show file tree
Hide file tree
Showing 10 changed files with 205 additions and 3 deletions.
29 changes: 29 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,32 @@ jobs:
run: |
composer global require php-coveralls/php-coveralls
php-coveralls --coverage_clover=./.coverage/clover.xml --json_path=./coveralls-upload.json -v
docker-ci:
runs-on: ubuntu-latest
strategy:
fail-fast: true
matrix:
include:
- php: '8.4'
stability: prefer-stable
name: Docker Compose ${{ matrix.php }} - ${{ matrix.stability }}
steps:
- name: Check Out Code
uses: actions/checkout@v4
- name: Set Up Docker
uses: docker/setup-buildx-action@v2
- name: Build Docker Images
run: docker compose build
- name: Start Docker Compose
run: docker compose up -d
- name: Install Dependencies
run: docker compose run --rm composer update --${{ matrix.stability }} --prefer-dist --no-interaction --no-progress --ignore-platform-reqs
- name: Run Tests
run: docker compose run --rm composer phpunit
#- name: Run Linter
# run: docker compose run --rm composer phpcs-test
#- name: Run Psalm Static Analysis
# run: docker compose run --rm composer psalm -- --shepherd
- name: Stop Docker Compose
if: always()
run: docker compose down
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
# Changelog

## [v1.0.0-alpha6](https://github.com/aphiria/app/compare/v1.0.0-alpha5...v1.0.0-alpha6) (?)
## [v1.0.0-alpha7](https://github.com/aphiria/app/compare/v1.0.0-alpha6...v1.0.0-alpha7) (?)

### Added

- Nothing

### Changed

- Nothing

## [v1.0.0-alpha6](https://github.com/aphiria/app/compare/v1.0.0-alpha5...v1.0.0-alpha6) (2024-12-03)

### Added

- Added support for running the skeleton app via Docker Compose ([#47](https://github.com/aphiria/app/pull/47))

### Changed

- Required PHP 8.4 ([#46](https://github.com/aphiria/app/pull/46))
- Updated to Symfony 7.0 ([#43](https://github.com/aphiria/app/pull/43))

Expand Down
16 changes: 14 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,24 @@ composer create-project aphiria/app --prefer-dist --stability dev

## Running Locally

You can run your app locally (defaults to http://localhost:8080):
You can run your app locally either directly via the built-in PHP web server or via Docker Compose. Both solutions result in your app being hosted at http://localhost:8080.

```php
### Built-In PHP Web Server

```
php aphiria app:serve
```

### Docker Compose Web Server

This app comes bundled with a Docker Compose setup meant to ease local development. It is not meant for production, but can get you up and running quickly with an nginx web server running your application along with Xdebug for debugging. Simply run:

```
docker compose up -d --build app
```

To start debugging with Xdebug, configure your IDE to map your checked out Aphiria code to the /app directory within the php service created by Docker Compose. Ensure that your IDE is configured to listen to port 9004 for Xdebug connections.

## Demo

This app comes with a simple demo that can store, retrieve, and authenticate users from a local SQLite database. It uses <a href="https://book.cakephp.org/phinx/0/en/contents.html" target="_blank">Phinx</a> to manage database migrations and seeding, which can be executed with the following commands, respectively:
Expand Down
58 changes: 58 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
networks:
aphiria:

services:
app:
build:
context: ./infrastructure/docker
dockerfile: nginx.dockerfile
volumes:
- ./:/usr/share/nginx/html
- ./infrastructure/docker/nginx.conf:/etc/nginx/conf.d/default.conf
command: >
sh -c "chmod -R 777 /usr/share/nginx/html/tmp && nginx -g 'daemon off;'"
depends_on:
- php
ports:
- "8080:80"
networks:
- aphiria

php:
build:
context: ./infrastructure/docker
dockerfile: php.dockerfile
volumes:
- ./:/usr/share/nginx/html
- ./infrastructure/docker/xdebug.ini:/usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
ports:
- "9004:9004"
networks:
- aphiria

aphiria:
build:
context: ./infrastructure/docker
dockerfile: php.dockerfile
volumes:
- ./:/app
depends_on:
- php
entrypoint: [ 'php', '/app/aphiria' ]
networks:
- aphiria

composer:
build:
context: ./infrastructure/docker
dockerfile: php.dockerfile
volumes:
- ./:/app
depends_on:
- php
environment:
# Necessary so that Composer can tell what version of the app it's running
- COMPOSER_ROOT_VERSION=1.0.0
entrypoint: [ 'composer', '--ignore-platform-reqs' ]
networks:
- aphiria
24 changes: 24 additions & 0 deletions infrastructure/docker/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
server {
index index.php index.html;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /usr/share/nginx/html/public;
add_header X-Frame-Options "SAMEORIGIN";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";

location / {
try_files $uri $uri/ /index.php$is_args$args;
}

location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Pass this through to the PHP image running in this pod on port 9000 (you must reference the "php" service exposed by docker-compose.yml)
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_hide_header X-Powered-By;
}
}
6 changes: 6 additions & 0 deletions infrastructure/docker/nginx.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM nginx:alpine

WORKDIR /usr/share/nginx/html

# Remove the default content from the Nginx default web root
RUN rm -rf /usr/share/nginx/html/*
15 changes: 15 additions & 0 deletions infrastructure/docker/php.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM php:8.4-fpm

WORKDIR /app

# Install dependencies and extensions
RUN apt-get update && apt-get install -y git libxml2-dev libpq-dev libzip-dev unzip
RUN docker-php-ext-install dom intl opcache zip

# Install Xdebug via PECL
RUN pecl install xdebug && docker-php-ext-enable xdebug

# Install Composer
COPY --from=composer:2 /usr/bin/composer /usr/bin/composer

CMD ["php-fpm", "-y", "/usr/local/etc/php-fpm.conf", "-R"]
7 changes: 7 additions & 0 deletions infrastructure/docker/xdebug.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[Xdebug]
zend_extension=xdebug.so
xdebug.mode=debug
xdebug.start_with_request=yes
xdebug.client_host=host.docker.internal
xdebug.client_port=9004
xdebug.log=/tmp/xdebug.log
25 changes: 25 additions & 0 deletions src/Health/Api/Controllers/HealthController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace App\Health\Api\Controllers;

use Aphiria\Api\Controllers\Controller;
use Aphiria\Net\Http\HttpException;
use Aphiria\Net\Http\IResponse;
use Aphiria\Routing\Attributes\Get;

class HealthController extends Controller
{
/**
* Checks the health of the API
*
* @return IResponse The OK response
* @throws HttpException Thrown if the request could not be negotiated
*/
#[Get('/health')]
public function checkHealth(): IResponse
{
return $this->ok();
}
}
16 changes: 16 additions & 0 deletions tests/Integration/Health/HealthTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace App\Tests\Integration\Health;

use Aphiria\Net\Http\HttpStatusCode;
use App\Tests\Integration\IntegrationTestCase;

class HealthTest extends IntegrationTestCase
{
public function testCheckingHealthReturnsOk(): void
{
$this->assertStatusCodeEquals(HttpStatusCode::Ok, $this->get('/health'));
}
}

0 comments on commit a297844

Please sign in to comment.