Skip to content

Commit fc35461

Browse files
maks-rafalkoclaude
andcommitted
chore(MSP-5160): add dockerised makefile-driven local dev env
Lets contributors run composer ci without matching PHP/Composer on the host. Docker/Makefile structure follows Lendable/doctrine-migrations-extensions#175, with the Makefile conventions and pcov coverage driver aligned with Lendable/messaging. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
1 parent a2f5f35 commit fc35461

9 files changed

Lines changed: 183 additions & 0 deletions

File tree

.dockerignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.git*
2+
bin
3+
vendor
4+
.phpunit.result.cache

.gitattributes

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,13 @@
11
/.github export-ignore
2+
/local export-ignore
23
/tests export-ignore
4+
.dockerignore export-ignore
35
.gitattributes export-ignore
46
.gitignore export-ignore
57
.php-cs-fixer.php export-ignore
68
composer.lock export-ignore -merge
79
infection.json5 export-ignore
10+
Makefile export-ignore
811
phpstan.neon export-ignore
912
phpstan-rector.neon export-ignore
1013
phpunit.xml.dist export-ignore

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
/vendor
33
phpunit.xml
44
/.phpunit.result.cache
5+
/local/.env

Makefile

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
DIR := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
2+
PROJECT_NAME = lendable_json_serializer_dev
3+
CONTAINER = runner
4+
PUID ?= 1000
5+
PGID ?= 1000
6+
EXEC_SHELL = /bin/sh
7+
EXEC_USER = app
8+
9+
DOCKER_COMPOSE = docker compose \
10+
-f ${DIR}/local/docker-compose.yaml \
11+
--project-directory $(DIR)/local \
12+
-p ${PROJECT_NAME}
13+
14+
init:
15+
@mkdir -p $(HOME)/.composer && (chown $(PUID):$(PGID) $(HOME)/.composer || echo "No need to chown $(HOME)/.composer");
16+
17+
build:
18+
$(DOCKER_COMPOSE) build
19+
20+
up:
21+
$(DOCKER_COMPOSE) up -d
22+
23+
down:
24+
$(DOCKER_COMPOSE) down -v
25+
26+
start:
27+
$(DOCKER_COMPOSE) start
28+
29+
stop:
30+
$(DOCKER_COMPOSE) stop
31+
32+
restart:
33+
$(DOCKER_COMPOSE) restart
34+
35+
ps:
36+
$(DOCKER_COMPOSE) ps
37+
38+
logs:
39+
$(DOCKER_COMPOSE) logs -f
40+
41+
shell:
42+
$(DOCKER_COMPOSE) exec -u $(EXEC_USER) $(CONTAINER) $(EXEC_SHELL)
43+
44+
clean:
45+
@$(DOCKER_COMPOSE) down -v --rmi local
46+
47+
.PHONY: init build up down start stop restart ps logs shell clean

README.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,45 @@ Deserializes a JSON string into an `array`.
4141

4242
Throws `DeserializationFailed` on failure to deserialize.
4343
Throws `InvalidDeserializedData` if the data type of the resulting deserialized data is not an `array`.
44+
45+
## Local development
46+
47+
Everything runs inside Docker - no PHP or Composer is needed on the host. The
48+
environment is defined in `local/` (`Dockerfile`, `docker-compose.yaml`,
49+
`.env.dist`) and driven from the `Makefile`.
50+
51+
### Prerequisites
52+
53+
- Docker with Compose v2
54+
55+
### Getting started
56+
57+
```shell
58+
make up # builds the image (on first run) and starts the container
59+
make shell # opens a shell inside the container, in /app
60+
make down # stops and removes the container
61+
```
62+
63+
From the shell:
64+
65+
```shell
66+
composer install
67+
composer ci
68+
```
69+
70+
### Common targets
71+
72+
| Target | Description |
73+
| --- | --- |
74+
| `make build` | Build the container image |
75+
| `make up` / `make down` | Start / tear down the environment |
76+
| `make start` / `make stop` / `make restart` | Control the running container |
77+
| `make ps` / `make logs` | Inspect the environment |
78+
| `make shell` | Shell into the container as the `app` user |
79+
| `make clean` | Tear down and remove the locally built image |
80+
81+
### Xdebug
82+
83+
Xdebug is installed but disabled by default. Copy `local/.env.dist` to
84+
`local/.env`, set `XDEBUG_ENABLED=1` (optionally with `XDEBUG_HOST`,
85+
`XDEBUG_PORT` and `XDEBUG_IDE_KEY`), then run `make restart`.

local/.env.dist

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
XDEBUG_ENABLED=0
2+
PHP_IDE_CONFIG=serverName=json-serializer

local/Dockerfile

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
FROM public.ecr.aws/docker/library/php:8.4-cli-alpine AS base
2+
3+
ARG USER_ID=1000
4+
ARG GROUP_ID=1000
5+
6+
RUN addgroup --gid "${GROUP_ID}" "app" && \
7+
adduser \
8+
--disabled-password \
9+
--gecos "" \
10+
--home "/app-home" \
11+
--ingroup "app" \
12+
--uid "${USER_ID}" \
13+
-s "/bin/sh" \
14+
"app"
15+
16+
COPY --from=composer/composer:2.10.2-bin /composer /usr/bin/composer
17+
18+
RUN apk add --no-cache git
19+
20+
WORKDIR /app
21+
22+
FROM base AS dev
23+
24+
ARG XDEBUG_VERSION="3.5.1"
25+
RUN apk add --no-cache autoconf file g++ gcc libc-dev make pkgconf re2c linux-headers \
26+
&& apk add --no-cache bash git \
27+
&& pecl install "xdebug-${XDEBUG_VERSION}" pcov \
28+
&& docker-php-ext-enable pcov \
29+
&& apk del autoconf file g++ gcc libc-dev make pkgconf re2c linux-headers
30+
31+
COPY xdebug-entrypoint.sh /usr/local/bin/docker-php-xdebug-entrypoint
32+
33+
RUN touch /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini /usr/local/bin/noxdebug \
34+
&& chown app:app /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini /usr/local/bin/noxdebug
35+
36+
USER app

local/docker-compose.yaml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
services:
2+
runner:
3+
entrypoint: "/usr/local/bin/docker-php-xdebug-entrypoint"
4+
tty: true
5+
build:
6+
context: .
7+
target: dev
8+
environment:
9+
XDEBUG_ENABLED: "${XDEBUG_ENABLED:-}"
10+
XDEBUG_HOST: "${XDEBUG_HOST:-}"
11+
XDEBUG_PORT: "${XDEBUG_PORT:-}"
12+
XDEBUG_IDE_KEY: "${XDEBUG_IDE_KEY:-}"
13+
PHP_IDE_CONFIG: "${PHP_IDE_CONFIG:-}"
14+
volumes:
15+
- "..:/app:rw"

local/xdebug-entrypoint.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/sh
2+
3+
set -e
4+
5+
if [ "${XDEBUG_ENABLED:-0}" = "1" ]; then
6+
XDEBUG_HOST=${XDEBUG_HOST:-$(route -n | egrep "^0.0.0.0" | awk '{print $2}')}
7+
8+
if [ "${XDEBUG_HOST}" = "" ]; then
9+
echo "XDebug remote host could not be configured";
10+
exit 1;
11+
fi
12+
13+
XDEBUG_PORT="${XDEBUG_PORT:-9003}"
14+
15+
echo "Configuring PHP for remote XDebug server ${XDEBUG_PORT}"
16+
echo "zend_extension=xdebug.so
17+
xdebug.mode = debug
18+
xdebug.start_with_request = 1
19+
xdebug.client_host = ${XDEBUG_HOST}
20+
xdebug.client_port = ${XDEBUG_PORT}
21+
xdebug.idekey = ${XDEBUG_IDE_KEY:-PHPSTORM}
22+
xdebug.max_nesting_level = 999999" > /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
23+
24+
echo '#!/bin/sh
25+
php -dxdebug.mode\=off "$@"' > /usr/local/bin/noxdebug
26+
27+
chmod 755 /usr/local/bin/noxdebug
28+
29+
else
30+
echo "Disabling XDebug per configuration"
31+
fi
32+
33+
/bin/sh

0 commit comments

Comments
 (0)