├── .dockerignore ├── .editorconfig ├── .env ├── .env.example ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── compose.yml ├── composer.json ├── composer.lock ├── container ├── docker ├── Dockerfile └── nginx │ └── Dockerfile ├── docs ├── .gitkeep └── images │ └── banner.png ├── public └── index.php ├── setup.sh ├── src └── Example.php └── tests └── ExampleTest.php /.dockerignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | /vendor 3 | .phpunit.result.cache 4 | /.idea 5 | /.vscode -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | end_of_line = lf 5 | insert_final_newline = true 6 | charset = utf-8 7 | indent_style = space 8 | 9 | [*.php] 10 | indent_size = 4 11 | 12 | [*.{js, json}] 13 | indent_size = 2 14 | 15 | [Makefile] 16 | indent_style = tab 17 | -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | # Informações do projeto 2 | PROJECT_NAME=podcast 3 | APP_ENV=development 4 | 5 | # Configurações de portas 6 | NGINX_PORT=8080 7 | NGINX_SSL_PORT=8443 8 | MYSQL_PORT=3306 9 | PMA_PORT=8081 10 | 11 | # Configurações do MySQL 12 | MYSQL_ROOT_PASSWORD=root 13 | MYSQL_DATABASE=app 14 | MYSQL_USER=app 15 | MYSQL_PASSWORD=app 16 | 17 | # Outras configurações 18 | PHP_MEMORY_LIMIT=256M 19 | PHP_UPLOAD_MAX_FILESIZE=25M 20 | PHP_POST_MAX_SIZE=25M 21 | MODE=web 22 | PROJECT_WITH_REDIS=FALSE 23 | MODE=web 24 | MODE=cli 25 | MODE=web 26 | MODE=web 27 | MODE=web 28 | MODE=web 29 | MODE=web 30 | MODE=web 31 | PROJECT_MODE=web 32 | -------------------------------------------------------------------------------- /.env.example: -------------------------------------------------------------------------------- 1 | # Informações do projeto 2 | PROJECT_NAME=meuapp 3 | APP_ENV=development 4 | 5 | # Configurações de portas 6 | NGINX_PORT=8080 7 | NGINX_SSL_PORT=8443 8 | MYSQL_PORT=3306 9 | PMA_PORT=8081 10 | 11 | # Configurações do MySQL 12 | MYSQL_ROOT_PASSWORD=root 13 | MYSQL_DATABASE=app 14 | MYSQL_USER=app 15 | MYSQL_PASSWORD=app 16 | 17 | # Outras configurações 18 | PHP_MEMORY_LIMIT=256M 19 | PHP_UPLOAD_MAX_FILESIZE=25M 20 | PHP_POST_MAX_SIZE=25M 21 | PROJECT_MODE=web 22 | PROJECT_WITH_REDIS=FALSE 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /docker/mysql/* 2 | /docker/nginx/* 3 | /docker/php/* 4 | /docker/redis/* 5 | /node_modules 6 | /vendor 7 | .phpunit.result.cache 8 | /.idea 9 | /.vscode 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Diego Brocanelli 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: up down sh 2 | 3 | PROJECT_NAME := $(shell grep ^PROJECT_NAME= .env | cut -d= -f2) 4 | PROJECT_MODE := $(shell grep ^PROJECT_MODE= .env | cut -d= -f2) 5 | PROJECT_WITH_REDIS := $(shell grep ^PROJECT_WITH_REDIS= .env | cut -d= -f2) 6 | 7 | DOCKER_COMPOSE := $(shell command -v docker-compose >/dev/null 2>&1 && echo docker-compose || echo docker compose) 8 | 9 | UP_PROFILES := --profile $(PROJECT_MODE) 10 | ifeq ($(PROJECT_WITH_REDIS),TRUE) 11 | UP_PROFILES += --profile redis 12 | endif 13 | 14 | up: 15 | @if docker ps --format '{{.Names}}' | grep -q "^$(PROJECT_NAME)-php$$"; then \ 16 | echo "O container $(PROJECT_NAME)-php já está rodando."; \ 17 | else \ 18 | $(DOCKER_COMPOSE) -p $(PROJECT_NAME) --profile $(PROJECT_MODE) $(UP_PROFILES) up -d; \ 19 | fi 20 | 21 | down: 22 | $(DOCKER_COMPOSE) -p $(PROJECT_NAME) down 23 | 24 | sh: 25 | @if ! docker ps --format '{{.Names}}' | grep -q "^$(PROJECT_NAME)-php$$"; then \ 26 | $(DOCKER_COMPOSE) -p $(PROJECT_NAME) --profile $(PROJECT_MODE) $(UP_PROFILES) up -d; \ 27 | fi; \ 28 | docker exec -it $(PROJECT_NAME)-php bash 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PHP 8.4 Docker Environment 2 | 3 | ![Banner do Projeto](docs/images/banner.png) 4 | 5 | ![PHP Version](https://img.shields.io/badge/PHP-8.4-blue) 6 | ![MySQL Version](https://img.shields.io/badge/MySQL-8.0-orange) 7 | ![Redis Version](https://img.shields.io/badge/Redis-7.0-red) 8 | 9 | Um ambiente Docker moderno e configurável para desenvolvimento PHP 8.4, oferecendo flexibilidade para diferentes necessidades de projeto. 10 | 11 | ## Objetivo 12 | 13 | Este projeto fornece um ambiente Docker pronto para desenvolvimento PHP 8.4, facilitando a configuração de projetos modernos com MySQL, Redis e Nginx, ideal para equipes e desenvolvedores individuais. 14 | 15 | ## Características 16 | 17 | - PHP 8.4 com extensões otimizadas 18 | - Suporte para ambiente CLI ou Web (com Nginx) 19 | - Banco de dados MySQL 8.0 20 | - Suporte opcional para Redis 7.0 21 | - Configuração via variáveis de ambiente 22 | - Scripts de inicialização simplificados 23 | 24 | ## Requisitos 25 | 26 | - Docker 27 | - Make 28 | 29 | ## Sumário 30 | 31 | - [Instalação Rápida](#instalação-rápida) 32 | - [Opções de Configuração](#opções-de-configuração) 33 | - [Estrutura de Diretórios](#estrutura-de-diretórios) 34 | - [Como usar](#como-usar) 35 | - [Comandos auxiliares](#comandos-auxiliares) 36 | - [Customização](#customização) 37 | - [Como contribuir](#como-contribuir) 38 | - [Licença](#licença) 39 | 40 | ## Instalação Rápida 41 | 42 | Baixe o repositório e execute o script de configuração: 43 | 44 | ```bash 45 | git clone https://github.com/Diego-Brocanelli/php-docker.git [nome_projeto] \ 46 | cd [nome_projeto] \ 47 | chmod +x setup.sh \ 48 | ./setup.sh 49 | ``` 50 | 51 | O script irá guiá-lo através do processo de configuração e inicialização dos contêineres. 52 | 53 | ## Opções de Configuração 54 | 55 | O script `setup.sh` permite personalizar seu ambiente: 56 | 57 | ```bash 58 | # Ambiente web completo (PHP + Nginx + MySQL) 59 | ./setup.sh --web 60 | 61 | # Apenas ambiente CLI (PHP + MySQL) 62 | ./setup.sh --cli 63 | 64 | # Adicionar Redis ao ambiente 65 | ./setup.sh --web --with-redis 66 | 67 | # Usar um arquivo .env específico 68 | ./setup.sh --env meu-ambiente.env 69 | ``` 70 | 71 | Para ver todas as opções disponíveis: 72 | 73 | ```bash 74 | ./setup.sh --help 75 | ``` 76 | 77 | ## Estrutura de Diretórios 78 | 79 | ``` 80 | . 81 | ├── docker/ # Diretório com arquivos Docker 82 | ├── docs/ # Diretório com a documentação do projeto 83 | ├── public/ # Raiz pública da aplicação 84 | │ └── index.php # Arquivo inicial da aplicação 85 | ├── src/ # Diretório com o código-fonte do projeto 86 | ├── tests/ # Diretório para testes automatizados 87 | ├── .env # Variáveis de ambiente do projeto 88 | ├── Makefile # Comandos utilitários para Docker Compose 89 | ├── setup.sh # Script de configuração inicial 90 | ``` 91 | 92 | ## Como usar 93 | 94 | 1. Clone o repositório e execute o script de configuração: 95 | ```bash 96 | git clone https://github.com/seu-usuario/php84-docker.git 97 | cd php84-docker 98 | chmod +x setup.sh 99 | ./setup.sh 100 | ``` 101 | 2. Siga as instruções do script para definir o nome do projeto e opções desejadas. 102 | 103 | > No final da execução do script o ambiente estará funcionando. 104 | 105 | ## Comandos auxiliares 106 | 107 | 3. Subir o ambiente: 108 | ```bash 109 | make up 110 | ``` 111 | 4. Acesse o container PHP: 112 | ```bash 113 | make sh 114 | ``` 115 | 5. Parar o ambiente: 116 | ```bash 117 | make down 118 | ``` 119 | 120 | ## Customização 121 | 122 | ### Configurações PHP 123 | 124 | Adicione arquivos `.ini` personalizados em `docker/php/conf.d/`. 125 | 126 | ### Configurações Nginx 127 | 128 | Adicione arquivos de configuração em `docker/nginx/conf.d/`. 129 | 130 | ### Scripts de Inicialização MySQL 131 | 132 | Adicione scripts SQL em `docker/mysql/initdb.d/` para serem executados na criação do banco. 133 | 134 | ## Como contribuir 135 | 136 | 1. Faça um fork deste repositório 137 | 2. Crie uma branch para sua feature ou correção (`git checkout -b minha-feature`) 138 | 3. Faça commit das suas alterações 139 | 4. Envie um pull request 140 | 141 | ## Licença 142 | 143 | Distribuído sob a licença MIT. Veja o arquivo [LICENSE](LICENSE) para mais detalhes. 144 | -------------------------------------------------------------------------------- /compose.yml: -------------------------------------------------------------------------------- 1 | # Definição de redes personalizadas para melhor isolamento 2 | networks: 3 | frontend: 4 | driver: bridge 5 | backend: 6 | driver: bridge 7 | 8 | # Definição de volumes para persistência de dados 9 | volumes: 10 | mysql_data: 11 | driver: local 12 | redis_data: 13 | driver: local 14 | 15 | services: 16 | # Aplicação PHP 17 | app: 18 | build: 19 | context: ./docker/. 20 | args: 21 | - ENVIRONMENT=${APP_ENV:-development} 22 | container_name: ${PROJECT_NAME:-app}-php 23 | restart: unless-stopped 24 | volumes: 25 | - .:/var/www/html:delegated 26 | - ./docker/php/conf.d:/usr/local/etc/php/conf.d:ro 27 | depends_on: 28 | - mysql 29 | environment: 30 | - APP_ENV=${APP_ENV:-development} 31 | - MYSQL_HOST=mysql 32 | - MYSQL_DATABASE=${MYSQL_DATABASE:-app} 33 | - MYSQL_USER=${MYSQL_USER:-app} 34 | - MYSQL_PASSWORD=${MYSQL_PASSWORD:-app} 35 | - REDIS_HOST=redis 36 | networks: 37 | - backend 38 | profiles: 39 | - cli 40 | - web 41 | 42 | # Servidor Web Nginx 43 | nginx: 44 | build: 45 | context: ./docker/nginx/. 46 | container_name: ${PROJECT_NAME:-app}-nginx 47 | restart: unless-stopped 48 | ports: 49 | - "${NGINX_PORT:-8080}:80" 50 | - "${NGINX_SSL_PORT:-8443}:443" 51 | volumes: 52 | - .:/var/www/html:delegated 53 | - ./docker/nginx/conf.d:/etc/nginx/conf.d:ro 54 | - ./docker/nginx/ssl:/etc/nginx/ssl:ro 55 | depends_on: 56 | - app 57 | networks: 58 | - frontend 59 | - backend 60 | profiles: 61 | - web 62 | 63 | # Banco de dados MySQL 64 | mysql: 65 | image: mysql:8.0 66 | container_name: ${PROJECT_NAME:-app}-mysql 67 | restart: unless-stopped 68 | ports: 69 | - "${MYSQL_PORT:-3306}:3306" 70 | volumes: 71 | - mysql_data:/var/lib/mysql 72 | - ./docker/mysql/initdb.d:/docker-entrypoint-initdb.d 73 | - ./docker/mysql/conf.d:/etc/mysql/conf.d:ro 74 | environment: 75 | MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-root} 76 | MYSQL_ROOT_HOST: "%" 77 | MYSQL_DATABASE: ${MYSQL_DATABASE:-app} 78 | MYSQL_USER: ${MYSQL_USER:-app} 79 | MYSQL_PASSWORD: ${MYSQL_PASSWORD:-app} 80 | networks: 81 | - backend 82 | command: --default-authentication-plugin=mysql_native_password 83 | profiles: 84 | - cli 85 | - web 86 | 87 | # Cache Redis 88 | redis: 89 | image: redis:7-alpine 90 | container_name: ${PROJECT_NAME:-app}-redis 91 | restart: unless-stopped 92 | volumes: 93 | - redis_data:/data 94 | - ./docker/redis/redis.conf:/usr/local/etc/redis/redis.conf:ro 95 | networks: 96 | - backend 97 | command: redis-server /usr/local/etc/redis/redis.conf --appendonly yes 98 | profiles: 99 | - redis 100 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "autoload": { 3 | "psr-4": { 4 | "": "/src" 5 | } 6 | }, 7 | "require-dev": { 8 | "phpunit/phpunit": "^9.5", 9 | "squizlabs/php_codesniffer": "^3.7", 10 | "friendsofphp/php-cs-fixer": "^3.13", 11 | "phpmd/phpmd": "^2.13", 12 | "phploc/phploc": "^7.0", 13 | "phpstan/phpstan": "^1.9", 14 | "icanhazstring/composer-unused": "^0.8.4", 15 | "vimeo/psalm": "^4.29", 16 | "vlucas/phpdotenv": "^5.5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /container: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 3 | # Este aquivo foi insperirado no repositório: 4 | # https://github.com/ricardopedias/freep-console 5 | 6 | PHP_CONTAINER='app' 7 | 8 | docker-compose up -d 1> /dev/null 2> /dev/stdout 9 | 10 | if [ "$1" == "analyse" ]; then 11 | docker run \ 12 | -e RUN_LOCAL=true \ 13 | -e VALIDATE_MARKDOWN=true \ 14 | -e MARKDOWN_CONFIG_FILE="docs/.lint.yml" \ 15 | -e FILTER_REGEX_INCLUDE="/docs/.*" \ 16 | -v "$(pwd)/docs/.lint.yml":"/action/lib/.automation/docs/.lint.yml" \ 17 | -v "$(pwd)":"/tmp/lint" github/super-linter 18 | fi 19 | 20 | docker exec -it $PHP_CONTAINER $@ -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM php:8.4-fpm 2 | 3 | LABEL maintainer="Diego Brocanelli " 4 | 5 | # Argumentos para ambiente de desenvolvimento/produção 6 | ARG ENVIRONMENT=development 7 | 8 | # Configurar timezone 9 | ENV TZ=UTC 10 | RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone 11 | 12 | # Instalar dependências em uma única camada para reduzir o tamanho da imagem 13 | RUN apt-get update -y && \ 14 | apt-get -y --no-install-recommends install \ 15 | openssl \ 16 | build-essential \ 17 | software-properties-common \ 18 | ca-certificates \ 19 | gnupg \ 20 | gettext-base \ 21 | curl \ 22 | wget \ 23 | unzip \ 24 | libicu-dev \ 25 | libpng-dev \ 26 | libjpeg-dev \ 27 | libfreetype6-dev && \ 28 | apt-get clean && \ 29 | rm -rf /var/lib/apt/lists/* 30 | 31 | # Instalar PHP extensions usando o script do mlocati 32 | ADD --chmod=755 https://github.com/mlocati/docker-php-extension-installer/releases/latest/download/install-php-extensions /usr/local/bin/ 33 | 34 | # Instalar extensões do PHP em uma única camada 35 | RUN install-php-extensions \ 36 | gd \ 37 | apcu \ 38 | pdo \ 39 | pdo_mysql \ 40 | intl \ 41 | openssl \ 42 | curl \ 43 | tokenizer \ 44 | mbstring \ 45 | zip \ 46 | exif \ 47 | opcache \ 48 | yaml \ 49 | igbinary \ 50 | redis && \ 51 | if [ "$ENVIRONMENT" = "development" ]; then \ 52 | install-php-extensions xdebug; \ 53 | fi 54 | 55 | WORKDIR /var/www/html 56 | 57 | # Instalar Composer versão mais recente 58 | COPY --from=composer:latest /usr/bin/composer /usr/local/bin/composer 59 | 60 | # Configurar PHP de acordo com o ambiente 61 | RUN if [ "$ENVIRONMENT" = "development" ]; then \ 62 | # Sobrescrever com as configurações de desenvolvimento 63 | cp /usr/local/etc/php/php.ini-development /usr/local/etc/php/php.ini && \ 64 | # Configurar Xdebug apenas no ambiente de desenvolvimento 65 | echo "xdebug.mode=debug,coverage" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \ 66 | echo "xdebug.client_host=host.docker.internal" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \ 67 | echo "xdebug.client_port=9003" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \ 68 | echo "xdebug.start_with_request=yes" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini && \ 69 | echo "xdebug.idekey=docker" >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini; \ 70 | else \ 71 | # Otimizações para produção 72 | echo "opcache.enable=1" >> /usr/local/etc/php/conf.d/opcache.ini && \ 73 | echo "opcache.memory_consumption=128" >> /usr/local/etc/php/conf.d/opcache.ini && \ 74 | echo "opcache.interned_strings_buffer=8" >> /usr/local/etc/php/conf.d/opcache.ini && \ 75 | echo "opcache.max_accelerated_files=4000" >> /usr/local/etc/php/conf.d/opcache.ini && \ 76 | echo "opcache.revalidate_freq=60" >> /usr/local/etc/php/conf.d/opcache.ini && \ 77 | echo "opcache.enable_cli=1" >> /usr/local/etc/php/conf.d/opcache.ini && \ 78 | echo "opcache.jit=1255" >> /usr/local/etc/php/conf.d/opcache.ini && \ 79 | echo "opcache.jit_buffer_size=100M" >> /usr/local/etc/php/conf.d/opcache.ini; \ 80 | fi 81 | 82 | # Instalar Deployer (apenas se for ambiente de desenvolvimento) 83 | RUN if [ "$ENVIRONMENT" = "development" ]; then \ 84 | curl -LO https://deployer.org/deployer.phar && \ 85 | mv deployer.phar /usr/local/bin/dep && \ 86 | chmod +x /usr/local/bin/dep; \ 87 | fi 88 | 89 | # Configuração de usuário não-root para melhor segurança 90 | RUN groupadd --gid 1000 appuser && \ 91 | useradd --uid 1000 --gid appuser --shell /bin/bash --create-home appuser 92 | 93 | # Garantir que a pasta de trabalho pertence ao usuário da aplicação 94 | RUN chown -R appuser:appuser /var/www/html 95 | 96 | # Configurar permissões corretas para os diretórios do PHP-FPM 97 | RUN mkdir -p /var/www/.composer && \ 98 | chown -R appuser:appuser /var/www/.composer 99 | 100 | # Mudar para o usuário não-root 101 | USER appuser 102 | 103 | # Expor a porta do PHP-FPM 104 | EXPOSE 9000 105 | 106 | # Comando de inicialização 107 | CMD ["php-fpm"] 108 | -------------------------------------------------------------------------------- /docker/nginx/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM nginx:1.24-alpine 2 | 3 | RUN apk update \ 4 | apk add bash vim 5 | 6 | RUN rm /etc/nginx/conf.d/default.conf 7 | 8 | COPY ./conf.d/default.conf /etc/nginx/conf.d 9 | -------------------------------------------------------------------------------- /docs/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diego-Brocanelli/php-docker/9dd37ed6fef6dd8b459d8de381c3a924655e48fb/docs/.gitkeep -------------------------------------------------------------------------------- /docs/images/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Diego-Brocanelli/php-docker/9dd37ed6fef6dd8b459d8de381c3a924655e48fb/docs/images/banner.png -------------------------------------------------------------------------------- /public/index.php: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | PHP 8.4 Docker Environment 7 | 8 | 126 | 127 | 128 |
129 |

Seja bem-vindo!

130 |

PHP 8.4 Docker Environment

131 |

132 | Um ambiente moderno e pronto para desenvolvimento PHP, com tudo que você precisa para criar aplicações robustas e escaláveis.
133 | Ideal para equipes e projetos individuais! 134 |

135 | 145 |
Estrutura do Projeto
146 |
147 | .
148 | ├── docker/       # Arquivos Docker
149 | ├── docs/         # Documentação do projeto
150 | ├── public/       # Raiz pública da aplicação
151 | │   └── index.php # Arquivo inicial da aplicação
152 | ├── src/          # Código-fonte do projeto
153 | ├── tests/        # Testes automatizados
154 | ├── .env          # Arquivo de variáveis de ambiente
155 | ├── Makefile      # Ferramenta auxiliar
156 | ├── setup.sh      # Script de configuração inicial
157 |         
158 |
Comandos úteis
159 |
160 | Clonar e iniciar:
161 | git clone https://github.com/Diego-Brocanelli/php-docker.git [nome_projeto]
162 | cd [nome_projeto]
163 | chmod +x setup.sh
164 | ./setup.sh 165 |

166 | Ambiente web completo:
167 | ./setup.sh --web 168 |

169 | Apenas ambiente CLI (PHP + MySQL):
170 | ./setup.sh --cli 171 |

172 | Adicionar Redis ao ambiente:
173 | ./setup.sh --web --with-redis 174 |

175 | Usar um arquivo .env específico:
176 | ./setup.sh --env meu-ambiente.env 177 |

178 | Ver todas as opções:
179 | ./setup.sh --help 180 |

181 | Comandos Makefile:
182 | make up — Sobe todos os containers
183 | make down — Para e remove todos os containers
184 | make sh — Sobe e acessa o bash do container PHP
185 |
186 | 187 | 188 | 197 | GitHub 198 | 199 | 200 | 201 | 204 | Documentação 205 | 206 |
207 | 208 | 209 | -------------------------------------------------------------------------------- /setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | # Cores para melhorar a legibilidade 5 | RED='\033[0;31m' 6 | GREEN='\033[0;32m' 7 | YELLOW='\033[1;33m' 8 | BLUE='\033[0;34m' 9 | NC='\033[0m' # No Color 10 | 11 | # Banner do projeto 12 | echo -e "${BLUE}" 13 | echo "╔═════════════════════════════════════════════╗" 14 | echo "║ ║" 15 | echo "║ PHP 8.4 Docker Setup ║" 16 | echo "║ V 2.0.0 ║" 17 | echo "║ ║" 18 | echo "╚═════════════════════════════════════════════╝" 19 | echo -e "${NC}" 20 | 21 | # Função para exibir ajuda 22 | show_help() { 23 | echo -e "${GREEN}Uso:${NC} ./setup.sh [opções]" 24 | echo "" 25 | echo "Configure e inicie um ambiente Docker para desenvolvimento PHP 8.4." 26 | echo "" 27 | echo -e "${YELLOW}Opções:${NC}" 28 | echo " --help Mostra esta mensagem de ajuda" 29 | echo " --cli Instala apenas PHP CLI (sem nginx)" 30 | echo " --web Instala PHP com Nginx (padrão)" 31 | echo " --with-redis Adiciona Redis como serviço" 32 | echo " --env FILE Usa um arquivo .env específico (padrão: .env)" 33 | echo "" 34 | echo -e "${YELLOW}Exemplos:${NC}" 35 | echo " ./setup.sh --web --with-redis # Configuração completa" 36 | echo " ./setup.sh --cli # Apenas PHP CLI + MySQL" 37 | echo "" 38 | } 39 | 40 | # Variáveis padrão 41 | MODE="web" 42 | USE_REDIS=false 43 | ENV_FILE=".env" 44 | 45 | # Processamento de argumentos 46 | while [[ $# -gt 0 ]]; do 47 | case $1 in 48 | --help) 49 | show_help 50 | exit 0 51 | ;; 52 | --cli) 53 | MODE="cli" 54 | shift 55 | ;; 56 | --web) 57 | MODE="web" 58 | shift 59 | ;; 60 | --with-redis) 61 | USE_REDIS=true 62 | shift 63 | ;; 64 | --env) 65 | ENV_FILE="$2" 66 | shift 2 67 | ;; 68 | *) 69 | echo -e "${RED}Opção desconhecida: $1${NC}" 70 | show_help 71 | exit 1 72 | ;; 73 | esac 74 | done 75 | 76 | # solicitar nome do app (padrão: meu-app) 77 | read -p "Digite o nome do app (padrão: meu-app): " PROJECT_NAME 78 | if [[ -z "${PROJECT_NAME}" ]]; then 79 | PROJECT_NAME="meu-app" 80 | echo -e "${YELLOW}Nome do app não informado. Usando padrão: ${PROJECT_NAME}.${NC}" 81 | fi 82 | 83 | # Função para converter para CamelCase 84 | to_camel_case() { 85 | local input="$1" 86 | # Remove caracteres não alfanuméricos, separa por espaço, coloca primeira letra maiúscula 87 | echo "$input" | sed -E 's/[^a-zA-Z0-9]+/ /g' | awk '{for(i=1;i<=NF;i++){ $i=toupper(substr($i,1,1)) tolower(substr($i,2)) }}1' | tr -d ' ' 88 | } 89 | 90 | # Gera o namespace padrão: Brocanelli\PROJECT_NAME (em CamelCase) 91 | PROJECT_NAME_CAMEL=$(to_camel_case "${PROJECT_NAME}") 92 | DEFAULT_NAMESPACE="${PROJECT_NAME_CAMEL}\\" 93 | AUTOLOAD_NAMESPACE="${DEFAULT_NAMESPACE}" 94 | 95 | # Escapa as barras invertidas para JSON 96 | AUTOLOAD_NAMESPACE_ESCAPED=$(printf '%s' "$AUTOLOAD_NAMESPACE" | sed 's/\\/\\/g') 97 | 98 | # Atualiza o composer.json com o autoload informado 99 | if [[ -f "composer.json" ]]; then 100 | jq --arg ns "$AUTOLOAD_NAMESPACE_ESCAPED" --arg dir "$AUTOLOAD_DIR" \ 101 | '.autoload["psr-4"] = {($ns): "/src"}' composer.json > composer.tmp && mv composer.tmp composer.json 102 | echo "Autoload PSR-4 atualizado no composer.json: \"$AUTOLOAD_NAMESPACE\": \"/src\"" 103 | fi 104 | 105 | # Verifica se o Docker está instalado 106 | if ! command -v docker &> /dev/null; then 107 | echo -e "${RED}Docker não encontrado. Por favor, instale o Docker primeiro:${NC}" 108 | echo "https://docs.docker.com/get-docker/" 109 | exit 1 110 | fi 111 | 112 | # Verifica se o Docker Compose está instalado 113 | if ! command -v docker-compose >/dev/null 2>&1 && ! docker compose version >/dev/null 2>&1; then 114 | echo "Erro: nem 'docker-compose' nem 'docker compose' estão instalados ou disponíveis no PATH." >&2 115 | exit 1 116 | fi 117 | 118 | # Verifica se estamos no diretório do projeto (com compose.yml) 119 | if [[ ! -f "compose.yml" ]]; then 120 | echo -e "${RED}O arquivo compose.yml não foi encontrado.${NC}" 121 | echo "Certifique-se de estar no diretório raiz do projeto." 122 | exit 1 123 | fi 124 | 125 | # Verificar e criar arquivo .env se necessário 126 | if [[ ! -f "${ENV_FILE}" ]]; then 127 | if [[ -f ".env.example" ]]; then 128 | echo -e "${YELLOW}Arquivo ${ENV_FILE} não encontrado. Criando a partir do exemplo...${NC}" 129 | cp .env.example "${ENV_FILE}" 130 | # Gere uma senha aleatória para o MySQL root 131 | sed -i "s/senha_segura/$(openssl rand -base64 12)/g" "${ENV_FILE}" 132 | sed -i "s/senha_app_segura/$(openssl rand -base64 12)/g" "${ENV_FILE}" 133 | else 134 | echo -e "${RED}Arquivo .env.example não encontrado. Não é possível continuar.${NC}" 135 | exit 1 136 | fi 137 | fi 138 | 139 | # Atualiza o valor de PROJECT_NAME no .env 140 | if grep -q "^PROJECT_NAME=" "${ENV_FILE}"; then 141 | sed -i "s/^PROJECT_NAME=.*/PROJECT_NAME=${PROJECT_NAME}/" "${ENV_FILE}" 142 | else 143 | echo "PROJECT_NAME=${PROJECT_NAME}" >> "${ENV_FILE}" 144 | fi 145 | 146 | # Atualiza o valor de MODE no .env 147 | if grep -q "^PROJECT_MODE=" "${ENV_FILE}"; then 148 | sed -i "s/^PROJECT_MODE=.*/MODE=${MODE}/" "${ENV_FILE}" 149 | else 150 | echo "PROJECT_MODE=${MODE}" >> "${ENV_FILE}" 151 | fi 152 | 153 | # Atualiza o valor de PROJECT_WITH_REDIS no .env 154 | if [[ "${USE_REDIS}" == true ]]; then 155 | if grep -q "^PROJECT_WITH_REDIS=" "${ENV_FILE}"; then 156 | sed -i "s/^PROJECT_WITH_REDIS=.*/PROJECT_WITH_REDIS=TRUE/" "${ENV_FILE}" 157 | else 158 | echo "PROJECT_WITH_REDIS=TRUE" >> "${ENV_FILE}" 159 | fi 160 | else 161 | if grep -q "^PROJECT_WITH_REDIS=" "${ENV_FILE}"; then 162 | sed -i "s/^PROJECT_WITH_REDIS=.*/PROJECT_WITH_REDIS=FALSE/" "${ENV_FILE}" 163 | else 164 | echo "PROJECT_WITH_REDIS=FALSE" >> "${ENV_FILE}" 165 | fi 166 | fi 167 | 168 | # Criar diretórios necessários 169 | echo -e "${BLUE}Criando diretórios necessários...${NC}" 170 | mkdir -p docker/php/conf.d 171 | mkdir -p docker/nginx/conf.d 172 | mkdir -p docker/nginx/ssl 173 | mkdir -p docker/mysql/conf.d 174 | mkdir -p docker/mysql/initdb.d 175 | mkdir -p docker/redis 176 | 177 | # Criar arquivo de configuração Redis se não existir 178 | if [[ ! -f "docker/redis/redis.conf" ]]; then 179 | echo -e "${YELLOW}Criando arquivo de configuração do Redis...${NC}" 180 | echo "# Redis configuration 181 | appendonly yes 182 | protected-mode yes 183 | port 6379 184 | tcp-backlog 511 185 | timeout 0 186 | tcp-keepalive 300 187 | daemonize no 188 | supervised no 189 | loglevel notice 190 | databases 16 191 | always-show-logo yes 192 | save 900 1 193 | save 300 10 194 | save 60 10000 195 | stop-writes-on-bgsave-error yes 196 | rdbcompression yes 197 | rdbchecksum yes 198 | dbfilename dump.rdb 199 | dir /data 200 | replica-serve-stale-data yes 201 | replica-read-only yes 202 | repl-diskless-sync no 203 | repl-diskless-sync-delay 5 204 | repl-disable-tcp-nodelay no 205 | replica-priority 100 206 | lazyfree-lazy-eviction no 207 | lazyfree-lazy-expire no 208 | lazyfree-lazy-server-del no 209 | replica-lazy-flush no 210 | appendfsync everysec 211 | no-appendfsync-on-rewrite no 212 | auto-aof-rewrite-percentage 100 213 | auto-aof-rewrite-min-size 64mb 214 | aof-load-truncated yes 215 | aof-use-rdb-preamble yes 216 | lua-time-limit 5000 217 | slowlog-log-slower-than 10000 218 | slowlog-max-len 128 219 | latency-monitor-threshold 0 220 | notify-keyspace-events \"\" 221 | hash-max-ziplist-entries 512 222 | hash-max-ziplist-value 64 223 | list-max-ziplist-size -2 224 | list-compress-depth 0 225 | set-max-intset-entries 512 226 | zset-max-ziplist-entries 128 227 | zset-max-ziplist-value 64 228 | hll-sparse-max-bytes 3000 229 | stream-node-max-bytes 4096 230 | stream-node-max-entries 100 231 | activerehashing yes 232 | client-output-buffer-limit normal 0 0 0 233 | client-output-buffer-limit replica 256mb 64mb 60 234 | client-output-buffer-limit pubsub 32mb 8mb 60 235 | hz 10 236 | dynamic-hz yes 237 | aof-rewrite-incremental-fsync yes 238 | rdb-save-incremental-fsync yes 239 | " > docker/redis/redis.conf 240 | fi 241 | 242 | # Constrói os comandos Docker Compose 243 | if command -v docker-compose >/dev/null 2>&1; then 244 | DOCKER_COMPOSE_CMD="docker-compose -p ${PROJECT_NAME} --profile ${MODE}" 245 | elif docker compose version >/dev/null 2>&1; then 246 | DOCKER_COMPOSE_CMD="docker compose -p ${PROJECT_NAME} --profile ${MODE}" 247 | else 248 | echo "Erro: nem 'docker-compose' nem 'docker compose' estão instalados ou disponíveis no PATH." >&2 249 | exit 1 250 | fi 251 | 252 | # Adiciona Redis ao comando se solicitado 253 | if [[ "${USE_REDIS}" == true ]]; then 254 | DOCKER_COMPOSE_CMD="${DOCKER_COMPOSE_CMD} --profile redis" 255 | 256 | # Ajustar a dependência do app para incluir redis 257 | if grep -q "depends_on:" compose.yml; then 258 | if ! grep -q "- redis" compose.yml; then 259 | echo -e "${YELLOW}Adicionando dependência do Redis ao serviço app...${NC}" 260 | # Este sed é simplificado, pode precisar de ajustes dependendo do formato exato 261 | sed -i '/depends_on:/a\ - redis' compose.yml 262 | fi 263 | fi 264 | else 265 | # Remove a dependência de redis do serviço app se existir 266 | if grep -q "depends_on:" compose.yml && grep -q "- redis" compose.yml; then 267 | echo -e "${YELLOW}Removendo dependência do Redis do serviço app...${NC}" 268 | sed -i '/- redis/d' compose.yml 269 | fi 270 | fi 271 | 272 | # Baixa os contêineres 273 | echo -e "${BLUE}Baixando imagens dos contêineres...${NC}" 274 | eval "${DOCKER_COMPOSE_CMD} pull" 275 | 276 | # Constrói as imagens personalizadas 277 | echo -e "${BLUE}Construindo contêineres...${NC}" 278 | eval "${DOCKER_COMPOSE_CMD} build" 279 | 280 | # Inicia os contêineres 281 | echo -e "${GREEN}Iniciando ambiente...${NC}" 282 | eval "${DOCKER_COMPOSE_CMD} up -d" 283 | 284 | # Mostra o status dos contêineres 285 | echo -e "${BLUE}Status dos contêineres:${NC}" 286 | eval "${DOCKER_COMPOSE_CMD} ps" 287 | 288 | # Instruções finais 289 | echo -e "\n${GREEN}==========================${NC}" 290 | echo -e "${GREEN}Configuração concluída!${NC}" 291 | echo -e "${GREEN}==========================${NC}" 292 | 293 | # Mostra informações de portas 294 | if [[ "${MODE}" == "web" ]]; then 295 | NGINX_PORT=$(grep "NGINX_PORT=" "${ENV_FILE}" | cut -d= -f2 || echo "8080") 296 | echo -e "${YELLOW}Aplicação web disponível em:${NC} http://localhost:${NGINX_PORT}" 297 | fi 298 | 299 | echo -e "\nPara acessar o container PHP:" 300 | echo -e "${BLUE}docker exec -it \$(docker-compose ps -q app) bash${NC}" 301 | 302 | echo -e "\nPara parar o ambiente:" 303 | echo -e "${BLUE}docker-compose down${NC}" 304 | 305 | echo -e "\n${GREEN}Obrigado por usar nosso setup!${NC}" 306 | 307 | # Remove o diretório .git para desvincular do repositório original 308 | if [[ -d ".git" ]]; then 309 | echo -e "${YELLOW}Removendo diretório .git para desvincular do repositório original...${NC}" 310 | rm -rf .git 311 | fi 312 | -------------------------------------------------------------------------------- /src/Example.php: -------------------------------------------------------------------------------- 1 | assertTrue(true); 10 | } 11 | } 12 | --------------------------------------------------------------------------------