services: app: build: context: . args: - IMAGE_TAG_PREFIX - PHP_VERSION - SWOOLE_BRANCH platform: linux/amd64 links: - consul - httpbin:local.httpbin.org - mysql - nacos - oracle - php-fpm - pgsql - redis - wordpress - mongodb environment: DISABLE_DEFAULT_SERVER: 1 GITHUB_ACTIONS: "yes" # /var/www is the bind mount below, owned on the host by whoever checked the code out -- the runner user # on GitHub Actions -- while everything in this container runs as root. Git refuses to read a repository # owned by somebody else ("detected dubious ownership"), and so does every tool that shells out to it: # Composer guesses the root package version with `git branch -a --no-color --no-abbrev -v` and reports # the version as 1.0.0 once that fails. These three variables are git's "command" configuration scope, # one of the three scopes it considers protected; safe.directory is deliberately ignored from anywhere # else. `docker compose exec` inherits them, so every step gets the exception. Adding a second setting # here means raising GIT_CONFIG_COUNT to match. GIT_CONFIG_COUNT: 1 GIT_CONFIG_KEY_0: safe.directory GIT_CONFIG_VALUE_0: /var/www ports: - "80:80" volumes: - .:/var/www - wordpress:/var/www/html php-fpm: image: php:8.4-fpm volumes: - .:/var/www wordpress: image: wordpress:php8.4-fpm links: - mysql environment: WORDPRESS_DB_HOST: mysql WORDPRESS_DB_USER: username WORDPRESS_DB_PASSWORD: password WORDPRESS_DB_NAME: test WORDPRESS_TABLE_PREFIX: wp_ volumes: - type: volume source: wordpress target: /var/www/html volume: nocopy: false mysql: image: mysql:8 healthcheck: test: ["CMD-SHELL", "mysql --protocol=TCP -h127.0.0.1 -u$$MYSQL_USER -p$$MYSQL_PASSWORD $$MYSQL_DATABASE -e 'SELECT 1'"] interval: 2s timeout: 5s retries: 60 start_period: 30s environment: MYSQL_DATABASE: test MYSQL_USER: username MYSQL_PASSWORD: password MYSQL_ROOT_PASSWORD: password pgsql: image: postgres:17-alpine healthcheck: test: ["CMD-SHELL", "pg_isready -h127.0.0.1 -U$$POSTGRES_USER -d$$POSTGRES_DB"] interval: 2s timeout: 5s retries: 60 environment: POSTGRES_DB: test POSTGRES_USER: username POSTGRES_PASSWORD: password oracle: image: gvenzl/oracle-xe:slim healthcheck: test: ["CMD", "healthcheck.sh"] interval: 5s timeout: 10s retries: 30 start_period: 30s platform: linux/amd64 environment: ORACLE_PASSWORD: oracle redis: image: redis:7.2 healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 2s timeout: 5s retries: 60 # A local stand-in for httpbin.org (a Go reimplementation of its API), so the HTTP/curl tests are not at the # mercy of the real site's throttling. The app container reaches it as local.httpbin.org (see the link alias # above), on the default HTTP port so that URLs and Host headers look just like the httpbin.org ones. httpbin: image: mccutchen/go-httpbin environment: PORT: 80 # MongoDB 8.0+ bundles a tcmalloc that violates the kernel's rseq ABI and corrupts memory shortly after # startup on Linux kernels 6.19 through 7.0.13 (SERVER-121912), so those servers refuse to start on such a # kernel -- both the mongodb/mongodb-community-server entrypoint and mongod itself bail out. Docker Desktop's # linuxkit VM reports kernel 7.0.12, which leaves the service crash-looping on every macOS host, and there is # no supported way to bypass the check. MongoDB 7.0 predates the tcmalloc version at fault and is supported # until August 2027; it runs from the Docker official image because the mongodb/mongodb-community-server # entrypoint refuses to start on these kernels whatever server version it wraps. Once Docker Desktop ships # kernel 7.0.14 or newer this can go back to 8.x. The service deliberately carries no container_name: setting # it to "mongodb" (the service name) makes that name stop resolving from the other containers. mongodb: image: mongo:7.0 healthcheck: test: ["CMD", "mongosh", "--quiet", "--eval", "quit(db.adminCommand('ping').ok ? 0 : 1)"] interval: 5s timeout: 10s retries: 30 restart: always ports: - "27017:27017" # Pinned to the last 2.x release: the client (src/core/NameResolver/Nacos.php) uses the v1 Open API without # authentication. Nacos 3.0 refuses to start without NACOS_AUTH_TOKEN, NACOS_AUTH_IDENTITY_KEY and # NACOS_AUTH_IDENTITY_VALUE, and later 3.x releases no longer serve the v1 API at all (HTTP 501). nacos: image: nacos/nacos-server:v2.5.4 healthcheck: test: ["CMD", "curl", "--fail", "--silent", "--show-error", "--max-time", "3", "http://127.0.0.1:8848/nacos/v1/console/health/readiness"] interval: 2s timeout: 5s retries: 60 start_period: 20s environment: MODE: standalone PREFER_HOST_MODE: hostname # The default heap is 1 GB, far more than a few test instances need. JVM_XMS: 256m JVM_XMX: 256m JVM_XMN: 128m consul: image: consul:1.15 healthcheck: test: ["CMD", "consul", "operator", "raft", "list-peers"] interval: 2s timeout: 5s retries: 60 command: consul agent -dev -client=0.0.0.0 volumes: wordpress: