• Skip to secondary menu
  • Skip to main content
  • Skip to primary sidebar
  • Home
  • Projects
  • Products
  • Themes
  • Tools
  • Request for Quote

Vengala Vinay

Having 12+ Years of Experience in Software Development

  • Home
  • WordPress
  • PHP
    • Codeigniter
  • Django
  • Magento
  • Selenium
  • Server
Home » Setting up an ultra-lightweight Nginx + PHP-FPM Alpine container server on openSUSE for CodeIgniter 4 apps

Setting up an ultra-lightweight Nginx + PHP-FPM Alpine container server on openSUSE for CodeIgniter 4 apps

Prerequisites and Base System Setup

This guide assumes a fresh installation of openSUSE Leap or Tumbleweed. We’ll be leveraging Docker for containerization, which is the most efficient way to manage isolated, lightweight environments. Ensure Docker is installed and running on your host system.

On openSUSE, installation is straightforward:

  • Install Docker: sudo zypper install docker docker-compose
  • Start and enable the Docker service: sudo systemctl enable docker --now
  • Add your user to the ‘docker’ group to avoid using sudo for every Docker command (log out and back in for this to take effect): sudo usermod -aG docker $USER

Crafting the Nginx + PHP-FPM Alpine Dockerfile

We will create a custom Dockerfile to build a minimal Alpine Linux image containing Nginx and PHP-FPM, optimized for serving CodeIgniter 4 applications. This approach offers granular control and reduces the attack surface compared to pre-built images.

Create a directory for your project, e.g., ~/ci4-docker, and inside it, create a file named Dockerfile:

Dockerfile Contents

The following Dockerfile installs Nginx and PHP-FPM, configures them to work together, and sets up a basic Nginx configuration suitable for CodeIgniter 4. We’ll use specific versions for reproducibility.

# Use a minimal Alpine Linux base image
FROM alpine:3.18

# Install Nginx, PHP-FPM, and necessary PHP extensions
# We'll install PHP extensions that are commonly required by CodeIgniter 4
RUN apk add --no-cache \
    nginx \
    php82 php82-fpm php82-common php82-opcache php82-mbstring php82-xml php82-pdo php82-pdo_mysql php82-tokenizer php82-ctype php82-session php82-json \
    supervisor \
    tzdata

# Configure PHP-FPM
# Copy custom php-fpm configuration
COPY --chown=nginx:nginx php-fpm.d/www.conf /etc/php82/php-fpm.d/www.conf

# Configure Nginx
# Copy custom Nginx configuration
COPY --chown=nginx:nginx nginx.conf /etc/nginx/nginx.conf
COPY --chown=nginx:nginx conf.d/default.conf /etc/nginx/conf.d/default.conf

# Copy application code (placeholder for now)
# In a real-world scenario, you'd likely use a volume mount or a multi-stage build
COPY --chown=nginx:nginx app/ /var/www/html/

# Ensure correct permissions for Nginx and PHP-FPM
RUN chown -R nginx:nginx /var/www/html \
    && chown -R nginx:nginx /var/lib/nginx \
    && chown -R nginx:nginx /var/log/nginx \
    && chown -R nginx:nginx /var/run/nginx \
    && chown -R nginx:nginx /var/run/php82-fpm

# Expose ports
EXPOSE 80

# Start Nginx and PHP-FPM using Supervisor
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf"]

PHP-FPM Configuration (php-fpm.d/www.conf)

Create a directory php-fpm.d in your project root and place the following www.conf file inside it. This configuration sets up PHP-FPM to run as the nginx user and group, which is standard practice in Alpine Linux environments.

[global]
pid = /run/php82-fpm.pid
error_log = /var/log/php82-fpm.log
daemonize = no

[www]
user = nginx
group = nginx
listen = /run/php82-fpm.sock
listen.owner = nginx
listen.group = nginx
listen.mode = 0660
pm = dynamic
pm.max_children = 50
pm.min_spare_servers = 5
pm.max_spare_servers = 10
pm.start_servers = 2
pm.slowlog = /var/log/php82-fpm.slow.log
request_terminate_timeout = 60s
request_slowlog_timeout = 10s
catch_workers_output = yes
clear_env = no

Nginx Configuration (conf.d/default.conf)

Create a directory conf.d in your project root and place the following default.conf file inside it. This Nginx configuration is tailored for CodeIgniter 4, directing all requests to index.php via PHP-FPM.

server {
    listen 80;
    server_name localhost;
    root /var/www/html/public; # CodeIgniter 4's public directory

    index index.php index.html index.htm;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass unix:/run/php82-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    # Deny access to hidden files
    location ~ /\.ht {
        deny all;
    }

    # Serve static files directly
    location ~* \.(css|js|jpg|jpeg|gif|png|ico|svg|webp)$ {
        expires 1y;
        add_header Cache-Control "public";
    }
}

Supervisor Configuration (supervisord.conf)

Create a file named supervisord.conf in your project root. Supervisor is used to manage the Nginx and PHP-FPM processes within the container, ensuring they are started and restarted if they crash.

[supervisord]
nodaemon=true
user=root

[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true
priority=10
stdout_logfile=/var/log/supervisor/nginx_stdout.log
stderr_logfile=/var/log/supervisor/nginx_stderr.log

[program:php-fpm]
command=/usr/sbin/php-fpm82 --nodaemonize --fpm-config /etc/php82/php-fpm.conf
autostart=true
autorestart=true
priority=20
stdout_logfile=/var/log/supervisor/php-fpm_stdout.log
stderr_logfile=/var/log/supervisor/php-fpm_stderr.log

Building and Running the Docker Image

Navigate to your project directory (~/ci4-docker) in your terminal. You can now build the Docker image. We’ll tag it as ci4-nginx-php-alpine.

docker build -t ci4-nginx-php-alpine .

Once the image is built, you can run it as a container. For development, mapping ports and volumes is crucial. We’ll map host port 8080 to container port 80 and mount your CodeIgniter 4 application code into the container.

Assuming your CodeIgniter 4 application’s public directory is at ~/my-ci4-app/public on your host, and you want to serve it from the container’s web root:

docker run -d \
  --name ci4-app-server \
  -p 8080:80 \
  -v ~/my-ci4-app/public:/var/www/html/public \
  -v ~/my-ci4-app:/var/www/html \
  ci4-nginx-php-alpine

Explanation of the docker run command:

  • -d: Run the container in detached mode (in the background).
  • --name ci4-app-server: Assign a name to the container for easier management.
  • -p 8080:80: Map port 8080 on your host machine to port 80 inside the container.
  • -v ~/my-ci4-app/public:/var/www/html/public: Mount your host’s CodeIgniter public directory to the container’s web root. This is essential for Nginx to find your application’s entry point.
  • -v ~/my-ci4-app:/var/www/html: Mount the entire application directory. This is useful for development so changes are reflected immediately, and for Nginx to access other application files if needed (though the public mount is primary for serving).
  • ci4-nginx-php-alpine: The name of the Docker image to run.

Accessing Your Application and Debugging

You should now be able to access your CodeIgniter 4 application by navigating to http://localhost:8080 in your web browser. If you encounter issues, here are some debugging steps:

Checking Container Logs

To view logs from the container, use:

docker logs ci4-app-server

For more detailed logs from Nginx and PHP-FPM, you can inspect the supervisor logs within the container:

docker exec ci4-app-server tail -f /var/log/supervisor/nginx_stderr.log
docker exec ci4-app-server tail -f /var/log/supervisor/php-fpm_stderr.log

Inspecting Container Filesystem

If you need to examine the container’s filesystem, you can start an interactive shell:

docker exec -it ci4-app-server sh

Inside the shell, you can check Nginx configuration validity:

nginx -t

And check PHP-FPM status:

php-fpm82 -t

Common Configuration Pitfalls

  • Permissions: Ensure the nginx user and group have read/write access to necessary directories (e.g., writable, logs) within your CodeIgniter application. The volume mounts should handle this, but double-check if you’re not using standard paths.
  • Nginx Root Directive: The root directive in default.conf must point to your CodeIgniter application’s public directory.
  • FastCGI Pass: Verify that fastcgi_pass in default.conf correctly points to the PHP-FPM socket (unix:/run/php82-fpm.sock).
  • PHP Extensions: If your CodeIgniter application requires additional PHP extensions, add them to the apk add command in the Dockerfile and rebuild the image.

Production Considerations

For production deployments, several adjustments are recommended:

  • Multi-stage Builds: Use multi-stage Docker builds to create a lean production image, copying only necessary artifacts from a build stage.
  • Environment Variables: Manage database credentials, API keys, and other configurations via environment variables passed to the container, rather than hardcoding them.
  • HTTPS: Configure Nginx for SSL/TLS termination, typically using a reverse proxy like Traefik or Caddy, or by mounting SSL certificates directly into the container.
  • Logging: Centralize logs using a dedicated logging service (e.g., ELK stack, Graylog) instead of relying solely on container logs.
  • Health Checks: Implement Docker health checks to monitor the status of Nginx and PHP-FPM.
  • Database: Run your database in a separate container or use a managed database service.

This setup provides a robust, ultra-lightweight foundation for serving CodeIgniter 4 applications on openSUSE using Docker, offering excellent performance and manageability.

Reader Interactions

Leave a Reply Cancel reply

You must be logged in to post a comment.

Primary Sidebar

A little about the Author

Having 12+ Years of Experience in Software Development, Vinay is a principal software architect, senior systems engineer, and elite technical consultant. He specializes in bespoke PHP/WordPress development, high-performance Magento 2 & Shopify architectures, custom plugin/theme development from scratch, and legacy code modernization (including VB6, VB.NET, PyQt, and Crystal Reports). Known for solving complex database bottlenecks, speed optimization (Core Web Vitals), and advanced security code auditing, Vinay engineers production-ready systems designed to scale under heavy concurrent load conditions.



Chat on WhatsApp

Recent Posts

  • Debugging Guide: Diagnosing PHP-FPM child process pool exhaustion in multi-site network environments with modern tools
  • Debugging and Resolving complex namespace class loading collisions issues during heavy concurrent database traffic
  • Step-by-Step Guide: Offloading high-frequency customer support tickets metadata writes to a Redis KV store
  • How to refactor legacy event ticket registers queries using modern WP_Query and custom Transient caching
  • Step-by-Step Guide: Offloading high-frequency member profile directories metadata writes to a Redis KV store

Categories

  • apache (1)
  • Business & Monetization (390)
  • Centos (4)
  • Comparisons & Decision Making (55)
  • Debian (2)
  • Debugging & Troubleshooting (662)
  • Desktop Applications (14)
  • DevOps (7)
  • DevOps & Cloud Scaling (962)
  • Django (1)
  • Laravel (4)
  • Migration & Architecture (192)
  • Mobile Applications (24)
  • MySQL (1)
  • Performance & Optimization (873)
  • PHP (5)
  • PHP Development (49)
  • Plugins & Themes (244)
  • Programming Languages (9)
  • Python (20)
  • Ruby on Rails (1)
  • Security & Compliance (647)
  • SEO & Growth (492)
  • Server (118)
  • Ubuntu (9)
  • VB6 & VB.NET (8)
  • Web Applications & Frontend (19)
  • Web Assembly (Wasm) (2)
  • WordPress (22)
  • WordPress Plugin Development (726)
  • WordPress Theme Development (357)

Recent Posts

  • Debugging Guide: Diagnosing PHP-FPM child process pool exhaustion in multi-site network environments with modern tools
  • Debugging and Resolving complex namespace class loading collisions issues during heavy concurrent database traffic
  • Step-by-Step Guide: Offloading high-frequency customer support tickets metadata writes to a Redis KV store

Top Categories

  • DevOps & Cloud Scaling (962)
  • Performance & Optimization (873)
  • WordPress Plugin Development (726)
  • Debugging & Troubleshooting (662)
  • Security & Compliance (647)
  • SEO & Growth (492)

Our Products

  • ERP & LMS Systems (4)
  • Directories & Marketplaces (4)
  • Healthcare Portals (3)
  • Point of Sale (POS) (2)
  • E-Commerce Engines (2)

Our Services

  • E-Commerce Development (10)
  • WordPress Development (8)
  • Python & Desktop GUI (7)
  • General Consulting (7)
  • Legacy Modernization (5)
  • Mobile App Development (4)

Copyright © 2026 · Vinay Vengala