Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 12 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 14 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 15 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 27 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 29 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 30 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 12 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 14 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 15 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 27 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 29 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 30 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 12 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 14 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 15 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 27 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 29 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 30 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 12 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 14 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 15 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 27 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 29 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 30 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 12 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 14 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 15 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 27 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 29 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 30 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 12 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 14 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 15 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag template invalid in Entity, line: 27 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag svg invalid in Entity, line: 29 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Warning: DOMDocument::loadHTML(): Tag path invalid in Entity, line: 30 in /home/samu/public_html/blog/wp-content/plugins/gistpress-master/includes/class-gistpress.php on line 473
Para meus últimos projetos, uma das práticas que mais gostei foi a da utilização de containers para o desenvolvimento web. Dessa forma tinhamos um controle muito maior do nosso ambiente de desenvolvimento, e conseguimos garantir que o ambiente de produção esteja com as mesmas configurações do servidor de desenvolvimento, espelhando as bibliotecas e permitindo que trabalhe com “linux” dentro do “windows”, sem a necessidade de criação de máquinas virtuais, agilizando o desenvolvimento do projeto.
Uma outra facilidade, é o deploy dessa aplicação para servidores como a digitalocean por exemplo
Para facilitar minha vida, criei um boilerplate bem simples e configurável para toda vez que for iniciar um projeto, eu já inicie com ele. É super simples, e ele instala os pacotes abaixo.
- Apache/2.4.25 (Debian)
- MySQL Server 5.6.41
- PHP 7.2.12
Vamos lá, é super simples, tão simples que você não precisa nem de ter seu ambiente configurado localmente, o que pode ser uma dor de cabeça para algumas pessoas.
Para funcionar precisaremos de ter instalado no computador o git [ubuntu|windows], e o docker + docker-compose
Uma outra coisa que recomendo fortemente, é criar 1 grupo para o docker, para não precisar ficar digitando sudo todas as vezes que precisar digitar um comando.
Vamos a instalação e customização.
1. Baixe o repositório
git clone https://github.com/samhk222/Docker-LAMP-Boilerplate |
2. Altere os arquivos listados abaixo, para atender suas necessidades específicas.
![]() | bin | Diretório onde ficarão as configurações do php, mysql e apache |
bin > mysql > Dockerfile | É a imagem que iremos utilizar. Recomendo a 5.6 para manter a compatibilidade com sistemas legados. Dentro desse arquivo, tem um linha comentada, que é o script inicial do nosso banco de dados. Ela copia um .sql para o entrypoint, e será executado quando montar a imagem. Caso já tenha um dump do seu banco, adicione ele nesse folder, e descomente a linha | |
bin > mysql > extra.cnf | Configurações extras do mysql, caso queira fazer alguma customização | |
bin > webserver > Dockerfile | Imagem do php, instalando as principais extensões, juntamente com o composer. | |
config > php > php.ini | Configurações extras do php.ini | |
config > vhosts > 000-laracast.conf | Configuração inicial do apache. Caso queira rodar outros servidores, ou incluir um endpoint para sua API, copiei esse arquivo, altere, e não esqueça de alterar seu /etc/hosts localmente | |
data > mysql | Aqui fica seu banco de dados. Mais a frente nesse post explicarei sobre os volumes. | |
logs | Ficam os logs do apache e do mysql, caso precise debugar alguma coisa, ou ver algum erro específico | |
.docs | Caso queira deixar alguma documentação do seu projeto. | |
public_html | Onde seus arquivos ficarão. Coloquei a princípio um teste do banco de dados e o php.ini para teste de configurações. | |
docker.compose.yml | Arquivo que monta os serviços do docker, com seus volumes, nomes e variáveis, que serão explicados no passo 3 desse artigo. |
3. Agora vamos configurar o docker-compose.yml, pois ele será o responsável por montar nossos serviços que utilizaremos durante o desenvolvimento. Nele temos 3 serviços, o servidor (php7.2 + apache), o mysql, e o phpmyadmin caso precise.
Algumas configurações importantes nesse arquivo são:
- build > context: Indica de qual Dockerfile iremos montar nossa imagem
- container_name: Nome do container, que será utilizado caso precisemos conectar nele posteriormente
- ports: Indica qual porta utilizaremos “fora do container” e para qual porta ela aponta para “dentro do container”. Nesse caso temos duas portas cadastradas, a 8877:80 e a 443:443. Nesse caso, quando subirmos o container, devemos digitar no chrome 0.0.0.0:8877 porque ela apontará para a porta 80 de dentro do container.
- Volumes: Grosseiramente falando, volumes são montados para compartilhar dados e arquivos do seu ambiente local com o container. Seguindo a mesma sintaxe das portas, ela indica “diretório local”:”diretório no container”. Eles permitem persistimos os dados, ou seja, se colocarmos um volume mysql apontando para local:container, quando matarmos essa imagem os dados estarão persistidos em nossa máquina local. Exemplo ./public_html:/var/www/html nesse caso falamos que tudo que está dentro da pasta public_html (local) será refletido para dentro da pasta /var/www/html do container, ou seja, qualquer alteração que fizermos localmente já estarão sendo refletidas automaticamente dentro do container. Nâo é uma cópia de arquivo, é um link mesmo para ele. Veja que eu monto os volumes com os dados de configuração, logs, etc
- environment: Para setar variáveis de ambiente
Não se esqueça de colocar as variáveis de ambiente corretamente no environment do serviço mysql
environment: | |
MYSQL_ROOT_PASSWORD: password | |
DB_HOST: SERVER-5.6-mysql | |
DB_PORT: 3306 | |
DB_DATABASE: SERVER | |
DB_USERNAME: root | |
DB_PASSWORD: password | |
DOCKER_WEB_PORT: 8877 |
4. Chega de configurações! Vamos por a mão na massa! Para subir seu serviço, vá no diretório onde está o arquivo docker-compose.yml e digite
docker-compose build |
Dessa forma as imagens serão baixadas, e seu container será montado, mas ele ainda não estará estartado, apenas pronto para ser utilizado.
5. Para subir o container.
docker-compose up |
Dica: quando você sobe um container, o sysout fica na tela, e seu terminal travado (caso feche o terminal, você mata o container. Para subir em background, ou de forma detached, utilize o parâmetro -d depois do up
docker-compose up -d |
Caso tudo dê certo, você verá seus três serviços com “done” em verde. Caso contrário, tente rodar o mesmo comando acima, sem a opção -d e veja o log de erros.
6. Dicas
Para ver os serviços rodando, digite docker-compose ps ou apenas docker ps (eu prefiro a primeira versão por achá-la visualmente mais bonita)
Para acessar um desses serviços, digite o comando abaixo para entrar dentro do container.
docker exec -it SERVER-7.2.x-webserver bash |
Na imagem acima, você verá que eu acessei o container, e listei minha pasta /www dentro do servidor. Mas lembre-se, como nós adicionamos essa pasta a um volume, será necessário acessar muito pouco esse serviço.
Para matar os containers que estão rodando em detached mode (parâmetro -d no docker-compose up), digite docker-compose down dentro da pasta onde está o docker-compose.yml.
Caso não esteja rodando em detached mode (ou seja, os sysouts estão saindo na tela), apenas dê um control+c para matar os serviços.