Skip to content

Commit 4770c71

Browse files
committed
Add Dockerfile, nginx and supervisord confs
1 parent 7561c62 commit 4770c71

File tree

4 files changed

+245
-1
lines changed

4 files changed

+245
-1
lines changed

Dockerfile

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
################################################################
2+
# Laravel + Statamic · Nginx · PHP-FPM 8.3 · CloudWatch logs #
3+
################################################################
4+
FROM php:8.3-fpm-alpine
5+
6+
# ---------- 1. System packages & PHP extensions ----------
7+
RUN apk add --no-cache \
8+
nginx supervisor git curl zip unzip icu-libs oniguruma libpng \
9+
icu-dev oniguruma-dev libpng-dev autoconf make g++ \
10+
&& docker-php-ext-install -j$(nproc) \
11+
bcmath \
12+
exif \
13+
gd \
14+
intl \
15+
mbstring \
16+
pdo_mysql \
17+
opcache \
18+
&& apk del --no-network icu-dev oniguruma-dev libpng-dev autoconf make g++
19+
20+
# ---------- 2. Composer ----------
21+
RUN curl -sS https://getcomposer.org/installer \
22+
| php -- --install-dir=/usr/local/bin --filename=composer
23+
24+
# ---------- 3. Application code --------------------------------------------
25+
WORKDIR /var/www/html
26+
COPY . .
27+
28+
# ── 3.1 Install PHP dependencies as root ───────────────────────────────────
29+
RUN composer install --no-dev --prefer-dist --optimize-autoloader
30+
31+
# ── 3.2 Pre-warm Statamic/Laravel caches (still as root) ───────────────────
32+
RUN php artisan optimize:clear \
33+
&& php please stache:refresh || true \
34+
&& php please static:clear || true
35+
36+
# ── 3.3 Ensure every writable directory exists and is accessible to FPM ────
37+
RUN set -eux; \
38+
mkdir -p \
39+
storage/framework/{cache,data,sessions,testing,views} \
40+
storage/logs \
41+
bootstrap/cache; \
42+
chown -R www-data:www-data \
43+
storage bootstrap/cache; \
44+
chmod -R ug+rwX \
45+
storage bootstrap/cache
46+
47+
48+
# ---------- 4. CloudWatch-friendly logging with awslogs drive----------
49+
RUN ln -sf /dev/stdout /var/log/nginx/access.log \
50+
&& ln -sf /dev/stderr /var/log/nginx/error.log \
51+
&& { \
52+
echo "error_log = /proc/self/fd/2"; \
53+
echo "log_errors = On"; \
54+
echo "display_errors = Off"; \
55+
} > /usr/local/etc/php/conf.d/error_log.ini
56+
57+
58+
RUN { \
59+
echo '[global]'; \
60+
echo 'error_log = /proc/self/fd/2'; \
61+
echo 'log_level = notice'; \
62+
echo ''; \
63+
echo '[www]'; \
64+
echo 'catch_workers_output = yes'; \
65+
} > /usr/local/etc/php-fpm.d/zz-log.conf
66+
67+
68+
# ---------- 5. Configuration & health check ----------
69+
COPY docker/nginx.conf /etc/nginx/nginx.conf
70+
COPY docker/supervisord.conf /etc/supervisord.conf
71+
72+
EXPOSE 8080
73+
HEALTHCHECK --interval=90s --timeout=3s CMD \
74+
wget -qO- http://127.0.0.1:8080/healthz || exit 1
75+
76+
CMD ["/usr/bin/supervisord","-c","/etc/supervisord.conf"]

README.md

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,97 @@
1-
# phpfpm-nginx-composer-laravel-docker
1+
# Laravel + Statamic Docker Image
2+
3+
This Docker image provides a production-ready environment for running Laravel and Statamic applications. It combines Nginx, PHP-FPM 8.3, and Supervisor in a single container, optimized for AWS ECS/Fargate deployment.
4+
5+
## Image Components
6+
7+
- **Base Image**: `php:8.3-fpm-alpine` (Alpine Linux-based PHP-FPM)
8+
- **Web Server**: Nginx
9+
- **Process Manager**: Supervisor
10+
- **PHP Version**: 8.3
11+
- **Composer**: Latest version
12+
13+
## Key Features
14+
15+
### 1. PHP Extensions
16+
The image includes essential PHP extensions:
17+
- bcmath
18+
- exif
19+
- gd
20+
- intl
21+
- mbstring
22+
- pdo_mysql
23+
- opcache
24+
25+
### 2. Application Setup
26+
- Uses Composer for dependency management
27+
- Optimizes autoloader for production
28+
- Pre-warms Statamic/Laravel caches
29+
- Sets up proper permissions for storage and cache directories
30+
31+
### 3. Process Management
32+
Supervisor manages two main processes:
33+
- PHP-FPM (FastCGI Process Manager)
34+
- Nginx web server
35+
36+
### 4. Logging Strategy
37+
The image implements a comprehensive logging strategy optimized for container environments:
38+
39+
#### Nginx Logging
40+
- Access logs are redirected to STDOUT
41+
- Error logs are redirected to STDERR
42+
- Log rotation is disabled for container-friendly logging
43+
44+
#### PHP-FPM Logging
45+
- Error logs are redirected to STDERR
46+
- Worker output is captured
47+
- Log level set to "notice"
48+
49+
#### PHP Error Handling
50+
- Error logging enabled
51+
- Display errors disabled (production-safe)
52+
- Errors logged to STDERR
53+
54+
This logging setup ensures:
55+
- All logs are properly captured in container environments
56+
- Compatibility with AWS CloudWatch
57+
- No log file rotation issues in containers
58+
- Proper error tracking without exposing sensitive information
59+
60+
### 5. Health Checks
61+
- Built-in health check endpoint at `/healthz`
62+
- 90-second interval health checks
63+
- 3-second timeout
64+
65+
## Configuration Files
66+
67+
### Nginx Configuration
68+
- Listens on port 8080
69+
- Configured for Laravel/Statamic routing
70+
- Includes health check endpoint
71+
- Optimized for PHP-FPM communication
72+
73+
### Supervisor Configuration
74+
- Runs in foreground mode (PID 1)
75+
- Manages both Nginx and PHP-FPM processes
76+
- Configures proper logging for both services
77+
78+
## Usage
79+
80+
### Building the Image
81+
```bash
82+
docker build -t your-image-name .
83+
```
84+
85+
### Running the Container
86+
```bash
87+
docker run -p 8080:8080 your-image-name
88+
```
89+
90+
### Environment Variables
91+
The application can be configured using standard Laravel environment variables.
92+
93+
## Notes
94+
95+
- The image is designed to run as a single container in production
96+
- All logs are properly forwarded to container logs
97+
- The setup is optimized for AWS ECS/Fargate deployment

docker/nginx.conf

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
# ── Global ───────────────────────────────────────────────────
2+
worker_processes 1; # one worker is ample in a single-core Fargate task
3+
4+
events {
5+
worker_connections 1024;
6+
}
7+
8+
http {
9+
include mime.types;
10+
default_type application/octet-stream;
11+
12+
access_log /var/log/nginx/access.log; # symlinked to STDOUT in Dockerfile
13+
error_log /var/log/nginx/error.log warn;
14+
15+
sendfile on;
16+
keepalive_timeout 65;
17+
18+
# ── Virtual host ────────────────────────────────────────
19+
server {
20+
listen 8080 default_server; # matches EXPOSE 8080
21+
server_name _; # wildcard
22+
23+
root /var/www/html/public; # Laravel/Statamic document root
24+
index index.php;
25+
26+
# 1. Slim front-controller pattern
27+
location / {
28+
try_files $uri $uri/ /index.php?$query_string;
29+
}
30+
31+
# 2. PHP hand-off to local FastCGI (PHP-FPM)
32+
location ~ \.php$ {
33+
include fastcgi_params;
34+
fastcgi_pass 127.0.0.1:9000; # PHP-FPM listens on 9000
35+
fastcgi_index index.php;
36+
37+
# Resolve symlinks correctly and avoid PATH_INFO issues
38+
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
39+
fastcgi_param DOCUMENT_ROOT $realpath_root;
40+
}
41+
42+
# 3. Health-check endpoint for ALB / ECS
43+
location = /healthz {
44+
add_header Content-Type text/plain;
45+
return 200 'ok';
46+
}
47+
}
48+
}

docker/supervisord.conf

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
[supervisord]
2+
nodaemon=true ; keep Supervisor in foreground (PID 1)
3+
loglevel=info
4+
logfile_maxbytes=0 ; disable rotation
5+
6+
[program:php-fpm]
7+
command = /usr/local/sbin/php-fpm --nodaemonize
8+
autorestart = true
9+
stdout_logfile = /dev/stdout
10+
stderr_logfile = /dev/stderr
11+
stdout_logfile_maxbytes = 0 ; ← disable rotation
12+
stderr_logfile_maxbytes = 0
13+
stdout_logfile_backups = 0 ; ← avoid stale settings
14+
stderr_logfile_backups = 0
15+
16+
[program:nginx]
17+
command = /usr/sbin/nginx -g 'daemon off; error_log /dev/stderr info;'
18+
autorestart = true
19+
stdout_logfile = /dev/stdout
20+
stderr_logfile = /dev/stderr
21+
stdout_logfile_maxbytes = 0
22+
stderr_logfile_maxbytes = 0
23+
stdout_logfile_backups = 0
24+
stderr_logfile_backups = 0

0 commit comments

Comments
 (0)