Skip to content

SimplePHP Template

Eric Mann edited this page Jan 7, 2026 · 2 revisions

Simple PHP Template

The Simple PHP template provides a lightweight deployment for straightforward PHP applications on Kubernetes. Designed for PHP sites that don't require frameworks or databases, it's perfect for file repositories, landing pages, contact forms, and legacy PHP migration.

Template Repository: github.com/DisplaceTech/displace-template-simplephp

Overview

The Simple PHP template includes:

  • PHP-FPM + Nginx: Production-ready PHP setup without framework overhead
  • No Database Required: Ideal for file-based PHP applications
  • Kubernetes Manifests: Production-ready deployment without Helm complexity
  • Content Synchronization: Update PHP files without rebuilding containers
  • Automatic HTTPS: SSL certificates via cert-manager and Let's Encrypt
  • Docker Development: docker-compose for local development
  • Built-in Monitoring: Health checks, resource limits, and observability

When to Use Simple PHP

This template is ideal for:

Use Case Description
File Repositories Directory listing sites, file browsers
Landing Pages Marketing pages, coming soon pages
Contact Forms Simple form handlers with email
Legacy PHP Migration Moving old PHP sites to Kubernetes
Lightweight APIs Simple REST endpoints without frameworks
Internal Tools Dashboards, admin panels, utilities

Quick Start

# Create project directory
mkdir my-php-site && cd my-php-site

# Initialize Simple PHP project
displace project init simplephp

# You'll be prompted for:
# - Project name (e.g., "my-site")
# - Kubernetes namespace (defaults to project name)
# - Domain name (e.g., "site.example.com")

# Add your PHP files
cp -r /path/to/your/php-files/* public/

# Deploy to local cluster
displace project deploy --cluster displace-local

# Access your application
make port-forward
# Visit http://localhost:8080

Template Structure

After initialization, you'll have:

my-php-site/
├── README.md                         # Generated project documentation
├── .gitignore                        # Git ignore file (protects secrets)
├── .credentials                      # Credential file (git-ignored)
├── Dockerfile                        # PHP-FPM + Nginx build
├── Makefile                          # Cross-platform commands
├── docker-compose.yaml               # Local development setup
├── docker/                           # Docker configuration
│   ├── nginx.conf                    # Nginx configuration
│   └── php.ini                       # PHP configuration
├── public/                           # Your PHP files go here
│   └── index.php                     # Sample index file
├── manifests/                        # Kubernetes manifests
│   ├── 01-namespace.yaml             # Namespace definition
│   ├── 02-pvc.yaml                   # Persistent volume claim
│   ├── 03-deployment.yaml            # PHP deployment
│   ├── 04-service.yaml               # Service definition
│   └── 05-ingress.yaml               # Ingress with SSL

Template Variables

Required Variables

Variable Description Generated
{{.ProjectName}} Project identifier User input
{{.Namespace}} Kubernetes namespace Defaults to project name
{{.Domain}} Application domain User input

Optional Variables

Variable Default Description
{{.ProjectDisplayName}} Project name Human-readable name
{{.PHPVersion}} 8.3 PHP version (8.2, 8.3)
{{.Replicas}} 2 Number of PHP pods
{{.StorageSize}} 5Gi PVC size for content
{{.IngressClass}} nginx Ingress controller class
{{.CertIssuer}} letsencrypt-prod Cert-manager issuer
{{.MemoryLimit}} 256Mi Container memory limit
{{.CPULimit}} 250m Container CPU limit
{{.MaxUploadSize}} 10M Maximum upload size

Available Commands

The generated Makefile includes comprehensive commands:

Development

Command Description
make build Build Docker image locally
make dev Start local development with docker-compose
make dev-down Stop local development environment
make dev-logs View local development logs

Deployment

Command Description
make deploy Deploy to Kubernetes
make destroy Remove deployment from cluster
make status Check deployment status

Content Management

Command Description
make sync-content Sync public/ to running pods
make push Push image to registry

Monitoring

Command Description
make logs View application logs
make shell Access pod shell
make port-forward Forward local port to service
make events View Kubernetes events

Development Workflow

Local Development

# Start local environment
make dev

# PHP site available at http://localhost:8080
# Make changes to public/ directory
# Changes are immediately visible (volume mounted)

# View logs
make dev-logs

# Stop when done
make dev-down

Content Synchronization

For deployed applications, sync content without rebuilding:

# Make changes to public/ directory
vim public/index.php

# Sync to running pods
make sync-content

# Changes are live immediately

Template Comparison

Feature Static Site Simple PHP Laravel
Runtime Caddy PHP-FPM + Nginx PHP-FPM + Nginx
Database None None MySQL
Framework None None Laravel
Use Case HTML/CSS/JS Simple PHP Full PHP Apps
Complexity Minimal Low Medium
Resources ~50MB ~100MB ~200MB

PHP Configuration

Custom php.ini

Edit docker/php.ini for PHP settings:

; Memory limit
memory_limit = 128M

; Upload settings
upload_max_filesize = 10M
post_max_size = 10M

; OPcache for production
opcache.enable=1
opcache.memory_consumption=64
opcache.max_accelerated_files=4000

Nginx Configuration

Edit docker/nginx.conf for web server settings:

# Security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header X-Content-Type-Options "nosniff";

# PHP processing
location ~ \.php$ {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Security Features

Container Security

  • Non-root container execution
  • Resource limits and security contexts
  • Read-only root filesystem where applicable
  • Health checks and liveness probes

Web Security

  • Security headers configured in Nginx
  • PHP version exposure disabled
  • Hidden file protection (.htaccess, .git)
  • Automatic HTTPS with cert-manager

PHP Security

  • OPcache enabled for production
  • Disabled dangerous functions
  • Error display off in production
  • Session security configured

Deployment

Local Cluster

# Deploy to local k3d cluster
displace project deploy --cluster displace-local

# Access via port forward
make port-forward
# Visit http://localhost:8080

# Or via local domain
# http://my-site.local.displace.tech

Production Deployment

# Create production cluster
displace cluster create production --provider aws

# Deploy to production
displace project deploy --cluster production

# Configure DNS to point to cluster ingress
# Access via your configured domain with HTTPS

Troubleshooting

PHP Errors

# Check application logs
make logs

# Access shell for debugging
make shell

# Check PHP info
php -i

# Verify Nginx configuration
nginx -t

Content Not Updating

# Force sync content
make sync-content

# Check pod status
make status

# Verify PVC is mounted
kubectl describe pod -n <namespace>

Permission Issues

# Access shell
make shell

# Check file permissions
ls -la /var/www/html/

# Fix permissions if needed
chmod -R 755 /var/www/html/

Requirements

  • Kubernetes: 1.20+
  • Docker: 20.10+
  • kubectl: For cluster access

Related Documentation:

Clone this wiki locally