Skip to content
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
8 changes: 6 additions & 2 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,14 @@ HTTP_PORT=80
HTTPS_PORT=443
TIMEZONE=Europe/Moscow

# Pinned nginx image — do not bump without testing
NGINX_IMAGE=nginx:1.27.4-bookworm

# PHP-FPM image tag and optional extra extensions (space-separated)
# Example: mbstring imagick redis xdebug
# mbstring is always installed in the base image (required by Bitrix)
# Example: imagick redis xdebug
PHP_VERSION=8.3
PHP_EXTRA_EXTENSIONS=mbstring
PHP_EXTRA_EXTENSIONS=

# Linux/macOS: set to your user to avoid permission issues in www/
UID=1000
Expand Down
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*.ps1 text eol=crlf

*.sh text eol=lf
docker/php/docker-entrypoint.sh text eol=lf
Makefile text eol=lf
*.conf text eol=lf
*.ini text eol=lf
Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ jobs:
uses: actions/checkout@v4

- name: Check shell syntax
run: bash -n scripts/*.sh docker/mysql/initdb/*.sh
run: bash -n scripts/*.sh docker/mysql/initdb/*.sh docker/php/docker-entrypoint.sh

- name: Validate Compose config
run: docker compose config
run: |
cp .env.example .env
docker compose config

- name: Build Docker images
run: docker compose build
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ Clone the repository, set a local domain, put a Bitrix backup into `www/`, run `
| --- | --- | --- |
| PHP-FPM | `php:8.3-fpm-bookworm` (build arg `PHP_VERSION`) | Custom image with Bitrix-oriented `php.ini` |
| MySQL | `mysql:8.0.36` (pinned via `MYSQL_IMAGE`) | Named volume `mysql-data`, init script for Bitrix user |
| nginx | `nginx:stable` | HTTPS, envsubst template, Bitrix URL rewrite |
| nginx | `nginx:1.27.4-bookworm` (override via `NGINX_IMAGE`) | HTTPS, envsubst template, Bitrix URL rewrite |
| SSL | [mkcert](https://github.com/FiloSottile/mkcert) | Certs in `docker/nginx/certs/` (gitignored) |
| Orchestration | Docker Compose v2 | `compose.yaml`, healthchecks, `depends_on` conditions |

**PHP extensions installed by default:** `bcmath`, `exif`, `gd`, `intl`, `mysqli`, `pdo_mysql`, `soap`, `zip`.
**PHP extensions installed by default:** `bcmath`, `exif`, `gd`, `intl`, `mbstring`, `mysqli`, `pdo_mysql`, `soap`, `zip`.

**Additional extensions** via `PHP_EXTRA_EXTENSIONS` in `.env` (space-separated). `.env.example` includes `mbstring` (required by Bitrix). You can add more, e.g. `mbstring imagick redis xdebug`.
**Optional extensions** via `PHP_EXTRA_EXTENSIONS` in `.env` (space-separated), e.g. `imagick redis xdebug`.

## Project Structure

Expand Down Expand Up @@ -83,9 +83,10 @@ cp .env.example .env
| `DOMAIN` | `bitrix.local` | Local HTTPS domain (must match hosts file and cert name) |
| `HTTP_PORT` | `80` | Host port mapped to nginx HTTP |
| `HTTPS_PORT` | `443` | Host port mapped to nginx HTTPS |
| `NGINX_IMAGE` | `nginx:1.27.4-bookworm` | Pinned nginx image tag |
| `TIMEZONE` | `Europe/Moscow` | PHP and MySQL timezone |
| `PHP_VERSION` | `8.3` | PHP-FPM image tag (Docker build arg) |
| `PHP_EXTRA_EXTENSIONS` | `mbstring` | Space-separated extra PHP extensions, e.g. `mbstring imagick redis xdebug` |
| `PHP_EXTRA_EXTENSIONS` | _(empty)_ | Space-separated optional PHP extensions, e.g. `imagick redis xdebug` |
| `UID` | `1000` | Linux/macOS user ID inside PHP container |
| `GID` | `1000` | Linux/macOS group ID inside PHP container |
| `XDEBUG_MODE` | `off` | Xdebug mode when `xdebug` is installed (`off`, `debug`, `develop`, …) |
Expand All @@ -100,7 +101,7 @@ Example `.env` for a custom domain with extra PHP extensions:
```dotenv
DOMAIN=my-site.local
MYSQL_PASSWORD=change-me
PHP_EXTRA_EXTENSIONS=mbstring imagick redis xdebug
PHP_EXTRA_EXTENSIONS=imagick redis xdebug
XDEBUG_MODE=debug
```

Expand Down Expand Up @@ -252,7 +253,7 @@ make clean # stop containers and remove Docker volumes

## PHP and nginx Defaults

PHP limits in `docker/php/php.ini` (oriented toward large Bitrix backups):
PHP limits in `docker/php/php.ini` (oriented toward large Bitrix backups). Timezone is set at container start from `TIMEZONE` in `.env` via `docker/php/docker-entrypoint.sh`.

- `memory_limit = 512M`
- `upload_max_filesize = 1024M`
Expand Down Expand Up @@ -286,7 +287,7 @@ On first start with an empty volume, `docker/mysql/initdb/01-bitrix-user.sh`:
The base PHP image stays small. Enable extra extensions only when needed:

```dotenv
PHP_EXTRA_EXTENSIONS=mbstring imagick redis xdebug
PHP_EXTRA_EXTENSIONS=imagick redis xdebug
XDEBUG_MODE=debug
```

Expand Down
10 changes: 8 additions & 2 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
services:
nginx:
image: nginx:stable
image: ${NGINX_IMAGE:-nginx:1.27.4-bookworm}
container_name: ${PROJECT_NAME:-bitrix-local}-nginx
restart: unless-stopped
depends_on:
php:
condition: service_started
condition: service_healthy
environment:
DOMAIN: ${DOMAIN:-bitrix.local}
NGINX_ENVSUBST_TEMPLATE_SUFFIX: .template
Expand Down Expand Up @@ -43,6 +43,12 @@ services:
working_dir: /var/www/html
expose:
- "9000"
healthcheck:
test: ["CMD-SHELL", "php-fpm -t || exit 1"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s

mysql:
image: ${MYSQL_IMAGE:-mysql:8.0.36}
Expand Down
4 changes: 4 additions & 0 deletions docker/php/.dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
README*
*.md
.git
.gitignore
8 changes: 7 additions & 1 deletion docker/php/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,15 @@ RUN set -eux; \
rm -rf /var/lib/apt/lists/*

RUN set -eux; \
curl -fsSL https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions \
curl -fsSL https://github.com/mlocati/docker-php-extension-installer/releases/download/2.11.12/install-php-extensions \
-o /usr/local/bin/install-php-extensions; \
chmod +x /usr/local/bin/install-php-extensions; \
IPE_GD_WITHOUTAVIF=1 install-php-extensions \
bcmath \
exif \
gd \
intl \
mbstring \
mysqli \
pdo_mysql \
soap \
Expand All @@ -44,5 +45,10 @@ RUN set -eux; \

COPY php.ini /usr/local/etc/php/conf.d/99-bitrix.ini
COPY opcache.ini /usr/local/etc/php/conf.d/99-opcache.ini
COPY docker-entrypoint.sh /usr/local/bin/bitrix-entrypoint.sh
RUN chmod +x /usr/local/bin/bitrix-entrypoint.sh

WORKDIR /var/www/html

ENTRYPOINT ["bitrix-entrypoint.sh"]
CMD ["php-fpm"]
8 changes: 8 additions & 0 deletions docker/php/docker-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash
set -e

if [ -n "${TZ:-}" ]; then
printf 'date.timezone = %s\n' "$TZ" > /usr/local/etc/php/conf.d/98-timezone.ini
fi

exec docker-php-entrypoint "$@"
2 changes: 0 additions & 2 deletions docker/php/php.ini
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
date.timezone = ${TZ}

short_open_tag = On
expose_php = Off

Expand Down
9 changes: 8 additions & 1 deletion scripts/doctor.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -euo pipefail
if [ -f .env ]; then
set -a
# shellcheck disable=SC1091
. ./.env
source <(grep -vE '^(UID|GID)=' .env)
set +a
fi

Expand Down Expand Up @@ -74,4 +74,11 @@ case "$(uname -s 2>/dev/null || echo unknown)" in
;;
esac

PHP_EXTRA_EXTENSIONS="${PHP_EXTRA_EXTENSIONS:-}"
XDEBUG_MODE="${XDEBUG_MODE:-off}"
if [[ " ${PHP_EXTRA_EXTENSIONS} " == *" xdebug "* ]] && [ "$XDEBUG_MODE" = "off" ]; then
echo "Warning: xdebug is in PHP_EXTRA_EXTENSIONS but XDEBUG_MODE=off."
echo " Set XDEBUG_MODE=debug in .env and rebuild: docker compose build php"
fi

exit "$STATUS"
Loading