Environment Setup - Detailed Reference
This detailed reference provides comprehensive documentation for all configuration files and options in BEAR.Sunday development environments.
malt Configuration Details
malt.json
{
"services": {
"php": {
"version": "8.4",
"extensions": ["mysql", "redis", "apcu"],
"ini": {
"memory_limit": "256M",
"max_execution_time": "30",
"display_errors": "On",
"error_reporting": "E_ALL"
}
},
"mysql": {
"version": "8.0",
"port": 3306,
"data_dir": "malt/data/mysql",
"config": "malt/conf/my_3306.cnf"
},
"redis": {
"version": "latest",
"port": 6379,
"data_dir": "malt/data/redis"
},
"apache": {
"version": "2.4",
"port": 8080,
"config": "malt/conf/httpd_8080.conf",
"document_root": "public"
},
"nginx": {
"version": "latest",
"port": 80,
"config": "malt/conf/nginx_80.conf",
"document_root": "public"
}
},
"env": {
"PATH": "malt/bin:${PATH}",
"DB_HOST": "127.0.0.1",
"DB_PORT": "3306",
"REDIS_HOST": "127.0.0.1:6379"
}
}
Key Configuration Items:
services.php.version: PHP version (8.1, 8.2, 8.3, 8.4)services.php.extensions: PHP extensions to auto-installservices.mysql.port: MySQL port (default 3306)services.redis.port: Redis port (default 6379)env: Project-specific environment variables
MySQL Configuration (my_3306.cnf)
[client]
port = 3306
socket = /tmp/mysql_3306.sock
default-character-set = utf8mb4
[mysql]
default-character-set = utf8mb4
[mysqld]
# Basic settings
port = 3306
socket = /tmp/mysql_3306.sock
datadir = malt/data/mysql
pid-file = malt/tmp/mysql_3306.pid
log-error = malt/logs/mysql_error.log
# Character set
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci
# Performance settings
innodb_buffer_pool_size = 128M # InnoDB buffer pool size
innodb_log_file_size = 64M # InnoDB log file size (Note: Use innodb_redo_log_capacity for MySQL 8.0.30+)
innodb_flush_log_at_trx_commit = 2 # Log flush setting (dev)
innodb_dedicated_server = OFF # Usually disabled in development environment
# Query cache (removed in MySQL 8.0, only for 5.7 and earlier)
# query_cache_type = 1 # Query cache enabled
# query_cache_size = 32M # Query cache size
# Connection settings
max_connections = 100 # Maximum connections
wait_timeout = 600 # Wait timeout
interactive_timeout = 600 # Interactive timeout
# Binary log (for replication, usually disabled in development)
# log-bin = mysql-bin
# server-id = 1
# Slow query log
slow_query_log = 1
slow_query_log_file = malt/logs/mysql_slow.log
long_query_time = 2
# General query log (for debugging, large performance impact)
# general_log = 1
# general_log_file = malt/logs/mysql_general.log
[mysqldump]
quick
max_allowed_packet = 16M
[mysql]
no-auto-rehash
Configuration Details:
| Setting | Description | Dev Recommended | Production Recommended |
|---|---|---|---|
innodb_buffer_pool_size |
InnoDB data and index cache | 128M-512M | 50-80% of RAM |
innodb_log_file_size |
Transaction log size | 64M | 256M-1G |
innodb_flush_log_at_trx_commit |
Log flush frequency 0: Every second 1: Every transaction 2: Every transaction (OS managed) |
2 (fast) | 1 (safe) |
query_cache_size |
Query cache size (MySQL 5.7 and earlier) | 32M | 64M-256M |
max_connections |
Maximum concurrent connections | 100 | 200-1000 |
slow_query_log |
Slow query log recording | 1 (enabled) | 1 (enabled) |
long_query_time |
Slow query threshold (seconds) | 2 | 1 |
PHP Configuration (php.ini)
[PHP]
; Error display (development)
display_errors = On
display_startup_errors = On
log_errors = On
error_log = malt/logs/php_error.log
error_reporting = E_ALL
; Resource limits
memory_limit = 256M
max_execution_time = 30
max_input_time = 60
upload_max_filesize = 64M
post_max_size = 64M
max_file_uploads = 20
; Performance
realpath_cache_size = 4M
realpath_cache_ttl = 600
opcache.enable = 1
opcache.enable_cli = 0
opcache.memory_consumption = 128
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 8000 # PHP 8.4 recommended value (increased)
opcache.revalidate_freq = 2
opcache.save_comments = 1
opcache.enable_file_override = 0
; Sessions
session.save_handler = files
session.save_path = malt/tmp/sessions
session.gc_maxlifetime = 1440
session.cookie_httponly = 1
session.cookie_secure = 0 # For development (set to 1 for HTTPS)
session.cookie_samesite = Lax # Strict recommended for production
; Japanese settings
default_charset = UTF-8
mbstring.language = Japanese
mbstring.internal_encoding = UTF-8
date.timezone = Asia/Tokyo
[xdebug]
; Xdebug 3.x settings (usually commented out for performance)
; xdebug.mode = debug
; xdebug.start_with_request = yes
; xdebug.client_host = 127.0.0.1
; xdebug.client_port = 9003
; xdebug.log = malt/logs/xdebug.log
[xhprof]
; XHProf settings (usually commented out for performance)
; xhprof.output_dir = malt/tmp/xhprof
Configuration Details:
| Setting | Description | Dev Recommended | Production Recommended |
|---|---|---|---|
memory_limit |
Maximum memory usage per script | 256M | 128M-512M |
max_execution_time |
Maximum script execution time (seconds) | 30 | 30 |
upload_max_filesize |
Maximum upload file size | 64M | As needed |
opcache.memory_consumption |
OPcache memory usage (MB) | 128 | 256-512 |
opcache.revalidate_freq |
File update check interval (seconds) | 2 | 60 |
realpath_cache_size |
Path cache size | 4M | 16M |
session.gc_maxlifetime |
Session lifetime (seconds) | 1440 | 1440 |
Apache Configuration (httpd_8080.conf)
# Basic settings
ServerRoot malt/apache
PidFile malt/tmp/httpd_8080.pid
Listen 127.0.0.1:8080
ServerName localhost:8080
# Modules (adjust paths based on your environment)
# macOS Homebrew example: /opt/homebrew/lib/httpd/modules/
# Ubuntu/CentOS example: /usr/lib/apache2/modules/ or /usr/lib64/httpd/modules/
LoadModule rewrite_module modules/mod_rewrite.so
LoadModule php_module modules/libphp.so
LoadModule dir_module modules/mod_dir.so
# PHP
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
# Document root
DocumentRoot "public"
<Directory "public">
Options Indexes FollowSymLinks
AllowOverride All
Require all granted
# URL rewriting
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
</Directory>
# Logs
ErrorLog malt/logs/apache_error.log
CustomLog malt/logs/apache_access.log combined
LogLevel warn
# Security
ServerTokens Prod
ServerSignature Off
# Performance
<IfModule mod_deflate.c>
AddOutputFilterByType DEFLATE text/html text/css text/javascript application/javascript application/json
</IfModule>
# Cache
<IfModule mod_expires.c>
ExpiresActive On
ExpiresByType text/css "access plus 1 month"
ExpiresByType application/javascript "access plus 1 month"
ExpiresByType image/png "access plus 1 month"
ExpiresByType image/jpg "access plus 1 month"
ExpiresByType image/jpeg "access plus 1 month"
ExpiresByType image/gif "access plus 1 month"
</IfModule>
Nginx Configuration (nginx_80.conf)
# Basic settings
# Adjust user based on your environment (Ubuntu: www-data, CentOS: nginx, macOS: _www)
user www-data; # or nginx, _www, etc.
worker_processes auto;
pid malt/tmp/nginx.pid;
error_log malt/logs/nginx_error.log;
events {
worker_connections 1024;
use epoll;
}
http {
# Basic settings
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 64M;
# MIME types
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Log format
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log malt/logs/nginx_access.log main;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/javascript
application/json
application/xml+rss;
# Server settings
server {
listen 127.0.0.1:80;
server_name localhost;
root public;
index index.php index.html;
# Access logs
access_log malt/logs/nginx_site_access.log;
error_log malt/logs/nginx_site_error.log;
# PHP processing
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
# URL rewriting (BEAR.Sunday)
location / {
try_files $uri $uri/ @rewrite;
}
location @rewrite {
rewrite ^(.*)$ /index.php last;
}
# Static file cache
location ~* \.(css|js|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1M;
add_header Cache-Control "public, immutable";
}
# Security
location ~ /\. {
deny all;
}
location ~* \.(md|lock|json|xml|yml|yaml|log)$ {
deny all;
}
}
}
Docker Configuration Details
docker-compose.yml (Comprehensive)
version: '3.8'
services:
php:
build:
context: .
dockerfile: docker/php/Dockerfile
volumes:
- .:/var/www/html
- ./docker/php/php.ini:/usr/local/etc/php/conf.d/custom.ini
depends_on:
mysql:
condition: service_healthy
redis:
condition: service_started
environment:
- DB_HOST=mysql
- DB_PORT=3306
- REDIS_HOST=redis:6379
networks:
- bear-network
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- .:/var/www/html
- ./docker/nginx/nginx.conf:/etc/nginx/nginx.conf
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./docker/nginx/ssl:/etc/nginx/ssl
depends_on:
- php
networks:
- bear-network
mysql:
image: mysql:8.0
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-secret}
MYSQL_DATABASE: ${DB_NAME:-myapp}
MYSQL_USER: ${DB_USER:-user}
MYSQL_PASSWORD: ${DB_PASSWORD:-password}
ports:
- "${DB_PORT:-3306}:3306"
volumes:
- mysql_data:/var/lib/mysql
- ./docker/mysql/my.cnf:/etc/mysql/conf.d/custom.cnf
- ./docker/mysql/init:/docker-entrypoint-initdb.d
command: >
--character-set-server=utf8mb4
--collation-server=utf8mb4_unicode_ci
--default-authentication-plugin=mysql_native_password
--innodb-buffer-pool-size=256M
--innodb-log-file-size=128M
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-p$$MYSQL_ROOT_PASSWORD"]
interval: 10s
timeout: 5s
retries: 5
start_period: 30s
networks:
- bear-network
redis:
image: redis:alpine
ports:
- "${REDIS_PORT:-6379}:6379"
volumes:
- redis_data:/data
- ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 3
networks:
- bear-network
memcached:
image: memcached:alpine
ports:
- "${MEMCACHED_PORT:-11211}:11211"
command: ["-m", "64"]
networks:
- bear-network
# Development tools
phpmyadmin:
image: phpmyadmin:latest
environment:
PMA_HOST: mysql
PMA_PORT: 3306
ports:
- "8080:80"
depends_on:
mysql:
condition: service_healthy
networks:
- bear-network
redis-commander:
image: rediscommander/redis-commander:latest
environment:
REDIS_HOSTS: local:redis:6379
ports:
- "8081:8081"
depends_on:
- redis
networks:
- bear-network
volumes:
mysql_data:
driver: local
redis_data:
driver: local
networks:
bear-network:
driver: bridge
Docker PHP Dockerfile
FROM php:8.4-fpm-alpine
# Install system dependencies
RUN apk add --no-cache \
git \
curl \
libpng-dev \
oniguruma-dev \
libxml2-dev \
libzip-dev \
freetype-dev \
libjpeg-turbo-dev \
icu-dev \
autoconf \
g++ \
make
# Install PHP extensions
RUN docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install \
pdo_mysql \
mysqli \
mbstring \
exif \
pcntl \
bcmath \
gd \
zip \
intl \
opcache
# Redis extension
RUN pecl install redis \
&& docker-php-ext-enable redis
# APCu extension
RUN pecl install apcu \
&& docker-php-ext-enable apcu
# Xdebug (development only)
ARG INSTALL_XDEBUG=false
RUN if [ ${INSTALL_XDEBUG} = true ]; then \
pecl install xdebug \
&& docker-php-ext-enable xdebug; \
fi
# Install Composer
COPY --from=composer:latest /usr/bin/composer /usr/bin/composer
# Set working directory
WORKDIR /var/www/html
# User configuration
RUN addgroup -g 1000 -S www \
&& adduser -u 1000 -S www -G www
# Permissions
RUN chown -R www:www /var/www/html
USER www
EXPOSE 9000
CMD ["php-fpm"]
Production Optimization
PHP Production Settings
[PHP]
; Security
expose_php = Off
display_errors = Off
display_startup_errors = Off
log_errors = On
error_log = /var/log/php/error.log
; Performance
memory_limit = 128M
max_execution_time = 30
realpath_cache_size = 16M
realpath_cache_ttl = 3600
; OPcache (production optimized)
opcache.enable = 1
opcache.enable_cli = 0
opcache.memory_consumption = 512
opcache.interned_strings_buffer = 64
opcache.max_accelerated_files = 32531
opcache.revalidate_freq = 60
opcache.validate_timestamps = 0
opcache.save_comments = 0
opcache.enable_file_override = 1
; Sessions (using Redis)
session.save_handler = redis
session.save_path = "tcp://127.0.0.1:6379"
session.gc_maxlifetime = 3600
session.cookie_secure = 1
session.cookie_httponly = 1
session.cookie_samesite = Strict
session.use_strict_mode = 1 # Strict mode for session IDs
MySQL Production Settings
[mysqld]
# Performance optimization
innodb_buffer_pool_size = 2G
innodb_log_file_size = 512M # Use innodb_redo_log_capacity for MySQL 8.0.30+
innodb_redo_log_capacity = 512M # MySQL 8.0.30+ new redo log setting
innodb_flush_log_at_trx_commit = 1
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
innodb_dedicated_server = ON # MySQL 8.0.3+ server-dedicated optimization
# Connection settings
max_connections = 500
thread_cache_size = 50
table_open_cache = 4000
# Query cache (MySQL 5.7 and earlier, removed in 8.0)
# query_cache_type = 1
# query_cache_size = 128M
# Binary logging
log-bin = mysql-bin
binlog_format = ROW
expire_logs_days = 7
# Security
skip-name-resolve
local-infile = 0
Performance Monitoring
New Relic Configuration Example
; New Relic PHP agent
extension = newrelic.so
newrelic.license = "YOUR_LICENSE_KEY"
newrelic.appname = "BEAR.Sunday App"
newrelic.daemon.address = "/tmp/.newrelic.sock"
newrelic.logfile = "/var/log/newrelic/php_agent.log"
newrelic.loglevel = "info"
Xdebug Profiling
# Run profiling
php -dzend_extension=xdebug.so \
-dxdebug.mode=profile \
-dxdebug.output_dir=/tmp/xdebug \
-dxdebug.profiler_output_name=cachegrind.out.%p \
script.php
XHProf Example
<?php
// Start XHProf profiling
if (extension_loaded('xhprof')) {
xhprof_enable(XHPROF_FLAGS_CPU + XHPROF_FLAGS_MEMORY);
}
// Application execution
// ...
// Save profiling results
if (extension_loaded('xhprof')) {
$xhprof_data = xhprof_disable();
$xhprof_runs = new XHProfRuns_Default();
$run_id = $xhprof_runs->save_run($xhprof_data, "myapp");
echo "XHProf Run ID: {$run_id}\n";
}
?>
Troubleshooting
Log Analysis
# PHP error log analysis
tail -f malt/logs/php_error.log | grep -E "(Fatal|Error|Warning)"
# MySQL slow query analysis
mysqldumpslow -s t -t 10 malt/logs/mysql_slow.log
# Apache/Nginx access log analysis
awk '{print $1}' malt/logs/apache_access.log | sort | uniq -c | sort -nr
Performance Testing
# Apache Bench test
ab -n 1000 -c 10 http://localhost:8080/
# Simple load test
for i in {1..100}; do
curl -w "@curl-format.txt" -o /dev/null -s http://localhost:8080/
done
This detailed reference provides comprehensive guidance for teams to deeply understand and properly customize their BEAR.Sunday environments.