Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #272: Add Docker environment #334

Merged
merged 2 commits into from
Oct 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Ignore everything
*

# except:

!/config
!/public
!/src
!/vendor
!autoload.php
!configuration.php
!yii
!composer.json
!composer.lock
!.env*
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ phpunit.phar

# NPM packages
/node_modules
.env
/.env

# Codeception
c3.php
59 changes: 59 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
.DEFAULT_GOAL := help

# Run silent.
MAKEFLAGS += --silent

RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
$(eval $(RUN_ARGS):;@:)

include docker/.env

# Current user ID and group ID.
export UID=$(shell id -u)
export GID=$(shell id -g)

export COMPOSE_PROJECT_NAME=${STACK_NAME}

up: ## Up the dev environment.
docker compose -f docker/compose.yml -f docker/compose.dev.yml up -d --remove-orphans

up-build: ## Up the dev environment rebuilding images.
docker compose -f docker/compose.yml -f docker/compose.dev.yml up -d --remove-orphans --build

down: ## Down the dev environment.
docker compose -f docker/compose.yml -f docker/compose.dev.yml down --remove-orphans

exec: ## Run a command within the existing container.
docker compose -f docker/compose.yml -f docker/compose.dev.yml exec app $(CMD) $(RUN_ARGS)

run: ## Run a command within a temporary container.
docker compose -f docker/compose.yml -f docker/compose.dev.yml run --rm --entrypoint $(CMD) app $(RUN_ARGS)

shell: CMD="/bin/sh" ## Get into container shell.
shell: exec

yii: CMD="./yii" ## Execute Yii command.
yii: run

composer: CMD="composer" ## Run Composer.
composer: run

codecept: CMD="./vendor/bin/codecept" ## Run Codeception.
codecept: run

psalm: CMD="./vendor/bin/psalm" ## Run Psalm.
psalm: run

build-prod: ## Build an image.
docker build --file docker/Dockerfile --target prod --pull -t ${IMAGE}:${IMAGE_TAG} .

push-prod: ## Push image to repository.
docker push ${IMAGE}:${IMAGE_TAG}

deploy-prod: ## Deploy to production.
docker -H ${PROD_SSH} stack deploy --with-registry-auth -d -c docker/compose.yml -c docker/compose.prod.yml ${STACK_NAME}

# Output the help for each task, see https://marmelab.com/blog/2016/02/29/auto-documented-makefile.html
.PHONY: help
help: ## This help.
@awk 'BEGIN {FS = ":.*?## "} /^[a-zA-Z_-]+:.*?## / {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' $(MAKEFILE_LIST)
64 changes: 54 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
[![static analysis](https://github.com/yiisoft/app/workflows/static%20analysis/badge.svg)](https://github.com/yiisoft/app/actions?query=workflow%3A%22static+analysis%22)
[![type-coverage](https://shepherd.dev/github/yiisoft/app/coverage.svg)](https://shepherd.dev/github/yiisoft/app)

Web application template for Yii 3.

<p align="center">
<a href="https://github.com/yiisoft/app" target="_blank">
<img src="docs/images/home.png" alt="Home page" >
Expand All @@ -24,32 +26,57 @@

- PHP 8.1 or higher.

## Installation
## Local installation

If you do not have [Composer](https://getcomposer.org/), you may install it by following the instructions
at [getcomposer.org](https://getcomposer.org/doc/00-intro.md).

You can then install this project template using the following command:
Create a project:

```shell
composer create-project --stability=dev yiisoft/app <your project>
composer create-project --stability=dev yiisoft/app myproject
cd myproject
```

In order to launch development web server run:
To run the app:

```shell
composer run serve
```
./yii serve
```

Now you should be able to access the application through the URL printed to console.
Usually it is `http://localhost:8080`.

## Installation with Docker

Fork the repository, clone it, then:

```shell
cd myproject
make composer update
```

To run the app:

```shell
make up
```

To stop the app:

```shell
make down
```

The application is available at `https://localhost`.

## Directory structure

The application template has the following structure:

```
config/ Configuration files.
docker/ Docker-specific files.
docs/ Documentation.
public/ Files publically accessible from the Internet.
assets/ Published assets.
Expand All @@ -69,6 +96,7 @@ src/ Application source code.
ViewInjection/
tests/ A set of Codeception tests for the application.
vendor/ Installed Composer packages.
Makefile Config for make command.
```

## Configuration
Expand Down Expand Up @@ -130,7 +158,7 @@ use Psr\Log\LogLevel;
],
],
'file-rotator' => [
// maximum file size, in kilo-bytes. Defaults to 10240, meaning 10MB.
// maximum file size, in kilobytes. Defaults to 10240, meaning 10MB.
'maxfilesize' => 10,
// number of files used for rotation. Defaults to 5.
'maxfiles' => 5,
Expand Down Expand Up @@ -199,11 +227,21 @@ See ["Logging"](https://github.com/yiisoft/docs/blob/master/guide/en/runtime/log
## Testing

The template comes with ready to use [Codeception](https://codeception.com/) configuration.
In order to execute tests run:
To execute tests, in local installation run:

```shell
composer run serve > ./runtime/yii.log 2>&1 &
vendor/bin/codecept run
./vendor/bin/codecept build

./yii serve > ./runtime/yii.log 2>&1 &
./vendor/bin/codecept run
```

For Docker:

```shell
make codecept build

make codecept run
```

## Static analysis
Expand All @@ -214,6 +252,12 @@ The code is statically analyzed with [Psalm](https://psalm.dev/). To run static
./vendor/bin/psalm
```

or, using Docker:

```shell
make psalm
```

## Support

If you need help or have a question, the [Yii Forum](https://forum.yiiframework.com/c/yii-3-0/63) is a good place for that.
Expand Down
2 changes: 2 additions & 0 deletions config/common/di/logger.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Psr\Log\LoggerInterface;
use Yiisoft\Definitions\ReferencesArray;
use Yiisoft\Log\Logger;
use Yiisoft\Log\StreamTarget;
use Yiisoft\Log\Target\File\FileTarget;

/** @var array $params */
Expand All @@ -15,6 +16,7 @@
'__construct()' => [
'targets' => ReferencesArray::from([
FileTarget::class,
StreamTarget::class,
]),
],
],
Expand Down
11 changes: 11 additions & 0 deletions docker/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
STACK_NAME=app

PROD_HOST=app.example.com
PROD_SSH="ssh://docker-web"

IMAGE=app
IMAGE_TAG=latest

DEV_PORT=80

# XDEBUG_MODE=develop,debug
64 changes: 64 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
FROM composer/composer:latest-bin AS composer

FROM ghcr.io/shyim/wolfi-php/frankenphp:8.3 AS base
ARG UID=10001
ARG GID=10001
RUN <<SH
set -eo pipefail
set -x

# Add www-data group and user.
addgroup -g ${GID} -S www-data
adduser -u ${UID} -D -S -G www-data www-data

# Set volume permissions.
mkdir -p /data /config /app/runtime && \
chown -R www-data:www-data /data /config /app/runtime

# Install extra packages.
apk add --no-cache \
php-frankenphp-8.3-opcache \
php-frankenphp-8.3-mbstring \
php-frankenphp-8.3-intl \
php-frankenphp-8.3-dom \
php-frankenphp-8.3-curl \
php-frankenphp-8.3-phar \
php-frankenphp-8.3-openssl \
php-frankenphp-8.3-xml \
php-frankenphp-8.3-xmlwriter \
php-frankenphp-8.3-simplexml \
php-frankenphp-8.3-pdo
SH

FROM base AS prod-builder
COPY --from=composer /composer /usr/bin/composer

COPY .. /app

RUN --mount=type=cache,target=/tmp/cache \
<<SH
set -eo pipefail
set -x

composer install --no-dev --no-progress --no-interaction --classmap-authoritative && \
rm composer.lock composer.json
SH

FROM base AS prod
ENV YII_ENV=prod

COPY --from=prod-builder --chown=www-data:www-data /app /app
USER www-data

FROM base AS dev
RUN <<SH
set -eo pipefail
set -x

# Install extra packages for dev only.
apk add --no-cache \
php-frankenphp-8.3-xdebug
SH

COPY --from=composer /composer /usr/bin/composer
USER www-data
25 changes: 25 additions & 0 deletions docker/compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
services:
app:
build:
dockerfile: docker/Dockerfile
context: ..
target: dev
args:
UID: ${UID}
GID: ${GID}
environment:
XDEBUG_MODE: "${XDEBUG_MODE:-develop}"
YII_ENV: "${YII_ENV:-dev}"
YII_DEBUG: ${YII_DEBUG:-true}
SERVER_NAME: ":80"
restart: unless-stopped
ports:
- "${DEV_PORT:-80}:80"
volumes:
- ../:/app
- ../runtime:/app/runtime
- ${COMPOSER_CACHE_DIR:-~/.cache/composer}:/var/www/.composer
- caddy_data:/data
- caddy_config:/config
tty: true

39 changes: 39 additions & 0 deletions docker/compose.prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
services:
app:
image: ${IMAGE}:${IMAGE_TAG}
networks:
- caddy_public
volumes:
- runtime:/app/runtime
- caddy_data:/data
- caddy_config:/config
environment:
SERVER_NAME: ":80"
YII_ENV: "${YII_ENV:-prod}"
YII_DEBUG: ${YII_DEBUG:-false}
deploy:
replicas: 2
update_config:
delay: 10s
parallelism: 1
order: start-first
failure_action: rollback
monitor: 10s
rollback_config:
parallelism: 0
order: stop-first
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
labels:
caddy: ${PROD_HOST:-app.example.com}
caddy.reverse_proxy: "{{upstreams 80}}"

volumes:
runtime:

networks:
caddy_public:
external: true
8 changes: 8 additions & 0 deletions docker/compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
services:
app: &appconfig
extra_hosts:
- "host.docker.internal:host-gateway"

volumes:
caddy_data:
caddy_config:
Loading