diff --git a/Makefile b/Makefile index 60bf187..8ec0228 100644 --- a/Makefile +++ b/Makefile @@ -23,6 +23,46 @@ docker_run_win: docker_stop_win: docker-compose down +# Production Docker Management Commands +#------------------------------------------------- + +# Start the production Docker environment +prod_up: + docker-compose -f docker-compose.prod.yml up -d + +# Stop the production Docker environment +prod_down: + docker-compose -f docker-compose.prod.yml down + +# Restart the production Docker environment +prod_restart: + make prod_down + make prod_up + +# View logs for the production Docker environment +prod_logs: + docker-compose -f docker-compose.prod.yml logs + +# Rebuild and start the production Docker environment +prod_rebuild: + docker-compose -f docker-compose.prod.yml up -d --build + +# Stop and remove all containers, networks, and volumes +prod_clean: + docker-compose -f docker-compose.prod.yml down -v + +# Execute production migrations (adjust command as necessary for your project setup) +prod_migrate: + docker-compose -f docker-compose.prod.yml exec app php spark migrate + +# Execute production seeders (adjust command as necessary for your project setup) +prod_seed: + docker-compose -f docker-compose.prod.yml exec app php spark db:seed + +# Clear the Redis cache in the production environment +prod_clear_cache: + docker-compose -f docker-compose.prod.yml exec redis redis-cli FLUSHALL + # Database migrations #------------------------------------------------- diff --git a/docker-compose.prod.yml b/docker-compose.prod.yml new file mode 100644 index 0000000..0cc382c --- /dev/null +++ b/docker-compose.prod.yml @@ -0,0 +1,100 @@ +# Production Docker Configuration for CodeIgniter 4 Application +# ============================================================= +# +# This Docker Compose configuration is designed for production deployment of a +# CodeIgniter 4 application. It defines four main services: the application itself (`app`), +# an Nginx web server (`nginx`), a MySQL database (`mysql`), and a Redis cache (`redis`). +# Each service is configured with production in mind, using Alpine images where available +# for their smaller footprint and setting environment variables for secure and efficient operation. +# +# Usage: +# ------ +# Before running, ensure you have set the environment variables `MYSQL_PROD_DATABASE`, +# `MYSQL_PROD_USER`, and `MYSQL_PROD_PASSWORD` for the MySQL service. These can be set +# in an `.env` file located in the same directory as this docker-compose file or exported +# directly in your shell. +# +# To start all services in detached mode, use: +# `docker-compose -f docker-compose.prod.yml up -d` +# +# To stop all services and remove containers, networks, and volumes created by `up`, use: +# `docker-compose -f docker-compose.prod.yml down` +# +# Services: +# --------- +# app: The main application service built from a Dockerfile located in `./docker/ci4`. +# It's configured to run in a `production` environment. The entire application directory +# is mounted into the container to facilitate easy updates, but consider using COPY +# in Dockerfile for a more secure, immutable deployment. +# +# nginx: Serves as the web server, using the lightweight Alpine Linux version of Nginx. +# It serves static files directly and proxies PHP requests to the `app` service. +# The production Nginx configuration is mounted from `./docker/nginx/nginx.prod.conf`. +# +# mysql: The MySQL database service, crucial for data persistence. It's configured through +# environment variables for the database name, user, and password, which should be +# securely managed. Data is persisted in a Docker volume named `mysql-data`. +# +# redis: Used for caching and session storage to enhance application performance. +# Like Nginx, it uses an Alpine Linux image for a smaller footprint. +# +# Networks: +# --------- +# app-network: A custom bridge network that facilitates communication between services. +# All services are attached to this network. +# +# Volumes: +# -------- +# mysql-data: A Docker-managed volume that ensures the persistence of MySQL data across +# container restarts and deployments. +# +# Notes: +# ------ +# - This configuration is optimized for production use, but security and performance +# tuning is an ongoing process. Always keep your images up to date and monitor +# for any potential security vulnerabilities. +# - Ensure SSL/TLS configuration for Nginx if exposing services directly to the internet. +# Consider using a service like Let's Encrypt for free SSL certificates. +# +version: '3.8' +services: + app: + build: + context: ./docker/ci4 + volumes: + - .:/var/www/html + environment: + CI_ENVIRONMENT: production + networks: + - app-network + + nginx: + image: nginx:alpine # Using the alpine version for smaller size + volumes: + - ./public:/var/www/html/public + - ./docker/nginx/nginx.prod.conf:/etc/nginx/conf.d/default.conf + networks: + - app-network + depends_on: + - app + + mysql: + image: mysql:5.7 + environment: + MYSQL_DATABASE: ${MYSQL_PROD_DATABASE} + MYSQL_USER: ${MYSQL_PROD_USER} + MYSQL_PASSWORD: ${MYSQL_PROD_PASSWORD} + networks: + - app-network + + redis: + image: redis:alpine # Using the alpine version for smaller size + networks: + - app-network + +networks: + app-network: + driver: bridge + +volumes: + mysql-data: diff --git a/docker-compose.yml b/docker-compose.yml index 7517ba3..0773886 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,3 +1,61 @@ +# CodeIgniter 4 Project Docker Configuration +# ========================================== +# +# This Docker Compose file orchestrates a Docker environment suitable for developing +# and running a CodeIgniter 4 application. It sets up the following services: +# +# 1. App - The main application service running PHP and the CodeIgniter framework. +# 2. Nginx - A web server to serve the CodeIgniter application. +# 3. MySQL - A database server for the application's data persistence. +# 4. Redis - A key-value store used for caching and session storage to enhance performance. +# 5. Adminer - A database management tool accessible via a web interface for managing the MySQL database. +# +# Each service is configured to meet the development needs of a typical CodeIgniter 4 application, +# ensuring that developers can work on the application in an environment that mirrors +# production settings as closely as possible. This setup also facilitates easy sharing of +# the development environment among team members, ensuring consistency across development setups. +# +# Usage: +# ------ +# To start the entire stack, run: `docker-compose up -d` +# This will build and start all the defined services in detached mode. +# +# To stop the services, run: `docker-compose down` +# This command stops and removes all running containers defined in this file. +# +# Service Details: +# ---------------- +# - `app`: This service uses a custom Dockerfile located in `./docker/ci4`. It's set up to run PHP applications, +# particularly tailored for the CodeIgniter framework. The project directory is mounted into the container +# to allow live editing of the application code. +# +# - `nginx`: Configured as the web server for the application. It uses the official Nginx image and forwards +# requests to the PHP application running in the `app` service. Custom Nginx configurations can be applied +# by modifying `./docker/nginx/nginx.conf`. +# +# - `mysql`: This service runs a MySQL database server, version 5.7. It's used for the application's data storage. +# The service is configured with environment variables to set the root password and create a default database +# upon initialization. +# +# - `redis`: Utilizes the latest Redis image to provide caching and session storage capabilities. It's accessible +# by the application through the network, enhancing performance by storing session and cache data in memory. +# +# - `adminer`: A lightweight database management tool that provides a web interface for managing MySQL databases. +# It's useful for development and debugging purposes. +# +# Network Configuration: +# ---------------------- +# All services are connected via a custom bridge network named `app-network`. This setup ensures that services +# can communicate with each other using service names as hostnames, thereby simplifying configuration and connectivity. +# +# Volumes: +# -------- +# - `mysql-data`: A named volume for persisting MySQL data. This ensures that the database data remains +# intact across container restarts and rebuilds. +# +# Note: Modify the service configurations as per your project requirements. Ensure that any sensitive or +# environment-specific variables are appropriately managed, ideally through a `.env` file or Docker secrets. +# version: '3.8' services: app: @@ -9,10 +67,6 @@ services: - mysql environment: CI_ENVIRONMENT: development - DB_HOST: mysql - DB_DATABASE: ci4 - DB_USERNAME: root - DB_PASSWORD: root networks: - app-network diff --git a/docker/nginx/nginx.prod.conf b/docker/nginx/nginx.prod.conf new file mode 100644 index 0000000..9c3fb9d --- /dev/null +++ b/docker/nginx/nginx.prod.conf @@ -0,0 +1,44 @@ +server { + listen 80; + # Strongly recommended to also configure listening on 443 (SSL) for HTTPS + # listen 443 ssl; + # ssl_certificate /path/to/your_certificate.pem; + # ssl_certificate_key /path/to/your_private.key; + + server_name example.com; # Change this to your domain + + root /var/www/html/public; + index index.php index.html index.htm; + + # Serve static files directly without passing to PHP + location ~* \.(jpg|jpeg|gif|css|png|js|ico|html)$ { + access_log off; + expires max; + } + + # Deny access to sensitive files + location ~ /\.ht { + deny all; + } + + # URL rewrites and forwarding to index.php + location / { + try_files $uri $uri/ /index.php?$query_string; + } + + # PHP FPM configuration + location ~ \.php$ { + try_files $uri /index.php =404; + fastcgi_pass app:9000; + fastcgi_index index.php; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + include fastcgi_params; + } + + # Recommended: security headers + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + + # Further optimizations and security settings can be added here +} diff --git a/env b/env index 5cc68df..6aa0716 100644 --- a/env +++ b/env @@ -15,6 +15,9 @@ #-------------------------------------------------------------------- # CI_ENVIRONMENT = production +#MYSQL_PROD_USER= +#MYSQL_PROD_DATABASE= +#MYSQL_PROD_PASSWORD= #-------------------------------------------------------------------- # APP @@ -30,12 +33,24 @@ # DATABASE #-------------------------------------------------------------------- +# DEV + database.default.hostname = mysql database.default.database = ci4 database.default.username = root database.default.password = root database.default.DBDriver = MySQLi +# PROD + +# database.default.hostname = mysql +# database.default.database = YOUR_PROD_DATABASE +# database.default.username = YOUR_PROD_USERNAME +# database.default.password = YOUR_PROD_PASSWORD +# database.default.DBDriver = MySQLi + +# TESTS + # database.tests.hostname = localhost # database.tests.database = ci4_test # database.tests.username = root