Este projeto consiste em criar toda a infraestrutura de componentes e programas necessárias para que um site vá (eventualmente) ao ar na internet. Ou seja, seu objetivo e ampliar nosso conhecimento de administração de sistemas utilizando o Docker.
CURSO: Engenharia de Software | 42SP
ATIVIDADE: Inception
Este projeto tem como objetivo criar toda a infraestrutura de componentes e programas necessários para que um site vá (eventualmente) ao ar na internet. Ou seja, seu objetivo é ampliar nosso conhecimento de administração de sistemas utilizando o Docker.
Como requisito, devemos construir as imagens Docker do projeto, sem a utilização, ou sem extrair imagens Docker prontas ou serviços como Docker Hub. Realizamos a configuração de um contêiner Docker que contém:
Volume que contém:
Para este projeto é recomendado aprender sobre PID 1 e as melhores práticas para escrever Dockerfiles, além da utilização para construção das imagens a penúltima versão estável do Alpine ou Debian. No caso para este projeto a penúltima versão estável, de acordo com a documentação ou os anúncios de lançamento do Debian e do Alpine, é a versão de junho de 2024, a versão estável mais recente do Debian 12 (Bookworm). Desta forma, a penúltima versão estável seria o Debian 11 (Bullseye) e para o Alpine é a versão 3.17.
o Docker é uma plataforma usada para criar e executar contêineres isolados, enquanto o Docker Compose facilita a definição e a execução de aplicativos compostos por múltiplos contêineres interconectados. Ambos são amplamente utilizados no desenvolvimento e na implantação de software moderno, proporcionando eficiência, portabilidade e consistência no gerenciamento de ambientes de aplicativos.
A principal diferença entre uma imagem Docker utilizada com Docker Compose e uma imagem Docker utilizada sem Docker Compose está no contexto de como elas são orquestradas e gerenciadas.
O Docker e as máquinas virtuais (VMs) são tecnologias que oferecem formas de isolar e gerenciar aplicações, mas elas funcionam de maneiras diferentes e têm seus próprios benefícios e casos de uso.
Docker oferece uma solução mais leve, eficiente e portátil em comparação com VMs, facilitando o desenvolvimento, teste e implantação de aplicativos. No entanto, VMs ainda têm seu lugar para casos onde o isolamento completo e a execução de diferentes sistemas operacionais são necessários. A escolha entre Docker e VMs dependerá dos requisitos específicos do seu projeto e da infraestrutura disponível.
Para o desenvolvimento deste projeto começamos criando o Makefile e o docker-compose.yml e realizando sua configuração.
O docker-compose.yml é um arquivo de configuração que define como os contêineres Docker devem ser orquestrados. Ele especifica os serviços que compõem a aplicação, as imagens Docker a serem usadas ou construídas, as redes, os volumes, as variáveis de ambiente e outras configurações.
Por requisito do projeto, este arquivo não pode conter:
O projeto exige que criemos uma rede Docker personalizada para interligar os contêineres, conforme pode ser observado no exemplo abaixo. Isso permite um controle mais granular sobre como os serviços se comunicam, simplifica a resolução de nomes de contêineres (usando DNS interno do Docker) e melhora a segurança. O docker-compose.yml deve garantir que todos os contêineres se comuniquem de forma segura e eficiente dentro de uma rede isolada.
services:
web:
image: nginx
networks:
- inception
db:
image: mariadb
networks:
- inception
networks:
inception:
Os requisitos para construção do docker-compose.yml são:
networks:
inception: # Nome da rede criada, onde os serviços poderão se comunicar
driver: bridge # Rede padrão usada para comunicação de contêineres em um único host Docker
inception: Contêineres conectados a essa rede com o driver bridge podem se comunicar diretamente, usando os nomes dos serviços como hostnames.
Os itens abaixo, não são apicaveis para a parte mandatoria do projeto
O Dockerfile é um arquivo de script utilizado pelo Docker para criar imagens de contêiner de maneira automatizada e consistente. Ele contém uma série de instruções que especificam como construir uma imagem Docker, incluindo a definição do ambiente, a instalação de dependências, a configuração de variáveis e a especificação dos comandos que serão executados dentro do contêiner. De forma geral, Dockerfile é utilizado pelo docker-compose.yml para realizar a criação das imagens Docker necessárias para os serviços definidos no arquivo de composição.
Exemplo:
FROM alpine:3.12
RUN apk add --no-cache nginx
COPY index.html /usr/share/nginx/html/index.html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Por requisito do projeto, este arquivo não pode conter:
Usar tail -f ou um loop infinito (sleep infinity, while true) como entrypoint faz com que esses comandos se tornem PID 1, o que é problemático porque eles não têm capacidade adequada para gerenciar outros processos ou sinais do sistema corretamente. Isso pode levar a problemas na hora de parar ou reiniciar os contêineres. Usar tail -f ou outros comandos de loop infinito consome recursos desnecessários do sistema sem fornecer valor real. Isso pode levar a uma utilização ineficiente dos recursos da máquina hospedeira.
O PID 1 é o primeiro processo que é iniciado dentro de um contêiner Docker. Este processo é responsável por gerenciar outros processos dentro do contêiner. Se o processo com PID 1 termina, o contêiner inteiro termina. Portanto, é crucial que o PID 1 seja um processo bem-comportado que gerencie corretamente os sinais do sistema e os processos filho. O Docker depende do comportamento adequado dos processos PID 1 para enviar sinais e parar os contêineres de forma limpa. Se o processo não responder corretamente aos sinais, pode causar interrupções e comportamento inesperado.
Para configurar o banco precisamos criar o Dockerfile para criar a imagem e o arquivo de configuração my.conf que ficará dentro da pasta conf.
conf/my.conf: O arquivo my.conf contém as configurações especificadas para garantir que o contêiner do MariaDB funcione corretamente dentro da rede Docker, permitindo a comunicação necessária entre os serviços e atendendo aos requisitos e melhores práticas delineados pelo projeto.
tools/init_mariadb.sh: O arquivo init_mariadb.sh é para automatizar a inicialização e a configuração inicial do banco de dados MariaDB
Exemplo de Dockerfile:
FROM mariadb:10.5
# Copiar arquivo de configuração personalizada
COPY ./conf/my.cnf /etc/mysql/my.cnf
# Copiar script de inicialização
COPY ./tools/init_mariadb.sh /docker-entrypoint-initdb.d/
# Definir variáveis de ambiente para configuração do banco de dados
ENV MYSQL_ROOT_PASSWORD=myrootpassword
ENV MYSQL_DATABASE=wordpress
ENV MYSQL_USER=wordpress_user
ENV MYSQL_PASSWORD=wordpress_password
# Expor a porta padrão do MariaDB
EXPOSE 3306
A utilização do ENV:
Testes Mariadb:
docker exec -it mariadb mysql -up wp_superuser -p # Acesse o Contêiner do wordpress para acessar o banco
cat /var/www/wordpress/wp-config.php # Acessar o arquivo de configuração
mysql -h $MARIADB_ROOT_HOST -u $MARIADB_USER -p$MARIADB_PASSWORD $MARIADB_DATABASE # Acessa o banco e a conexão
SHOW DATABASES; # Visualizar o banco.
USE wp;
SHOW TABLES; # Visualisar as tabelas
SELECT COUNT(*) FROM wp_comments; # Verificar numero de comentarios no wordpress
SELECT COUNT(*) FROM wp_posts; # Verificar numero de postagens***
https://lucperei.42.fr/wp-login.php
https://lucperei.42.fr/wp-admin
NGINX é uma ferramenta essencial para servir o conteúdo estático, balancear a carga de tráfego e atuar como proxy reverso, proporcionando desempenho e segurança ao site WordPress.
Para configurar o nginx precisamos criar o Dockerfile e os arquivos de configuração nginx.conf e self-signed.conf, e a geração do certificado SSL dentro da pasta tools.
conf/nginx.conf: O arquivo nginx.conf é para realizar a configuração do servidor web NGINX.
conf/self-signed.conf: O arquivo self-signed.conf realiza a configuração do uso de certificados autoassinados.
tools/ssl.sh: O arquivo ssl.sh realiza a geração do certificado SSL autoassinado.
tools/start_server.sh: O arquivo start_server.sh realiza o script de inicialização para garantir que o contêiner do NGINX inicie corretamente.
Exemplo de Dockerfile:
FROM debian:bullseye
# Instalar OpenSSL para gerar certificados
RUN apk add --no-cache openssl
# Copiar arquivos de configuração
COPY ./conf/nginx.conf /etc/nginx/nginx.conf
COPY ./conf/self-signed.conf /etc/nginx/conf.d/self-signed.conf
# Copiar scripts de inicialização e SSL
COPY ./tools/ssl.sh /usr/local/bin/ssl.sh
COPY ./tools/start_server.sh /usr/local/bin/start_server.sh
# Gerar certificados SSL autoassinados
RUN /usr/local/bin/ssl.sh
# Expor a porta padrão do NGINX (80 e 443 para HTTPS)
EXPOSE 80 443
# Definir comando de inicialização
CMD ["/usr/local/bin/start_server.sh"]
Para garantir que o NGINX esta executando na porta 443 e so indicar no comando abaixo e para testar pode colocar outras portas para ver se conecta como no exemplo abaixo:
user42@42saopaulo:~/workspace/inception$ curl -v https://lucperei.42.fr/:443
* Trying 127.0.0.1:443...
* TCP_NODELAY set
* Connected to lucperei.42.fr (127.0.0.1) port 443 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: /etc/ssl/certs/ca-certificates.crt
CApath: /etc/ssl/certs
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (OUT), TLS alert, unknown CA (560):
* SSL certificate problem: self signed certificate
* Closing connection 0
curl: (60) SSL certificate problem: self signed certificate
More details here: https://curl.haxx.se/docs/sslcerts.html
Testes no Wordpress: Login no Wordpress:
https://lucperei.42.fr/wp-login.php
Acesso a area administrativa do Wordpress:
https://lucperei.42.fr/wp-admin
Os requisitos do projeto envolvem a configuração de serviços como:
O Cache Redis é um sistema de armazenamento em memória de código aberto que pode ser usado como um cache de alto desempenho para acelerar o acesso a dados frequentemente acessados. No contexto do Site WordPress, ele é utilizado como um cache para melhorar a velocidade e o desempenho do site.
Ele armazena em pares de chaves e valores. As chaves podem representar consultas de banco de dados, resultados de consultas, objetos de cache, etc. Os valores correspondentes são os dados associados a essas chaves.
*Para usar o Redis como cache no WordPress, utilizamos de um plugin de cache compatível com Redis, como o Redis Object Cache. Este plugin se integra ao WordPress e usa Redis como backend para armazenar e recuperar dados em cache aém dos arquivos de configuração.
Testes do Redis no Wordpress para ver a configuração:
docker exec -it wordpress bash # Acesse o Contêiner do Wordpress
wp redis status --allow-root # Verifica se o comando redis está ativo e instalado.
wp plugin list --allow-root # Procure pelo plugin redis-cache na lista.
keys wp_redis_keywp:users:* # Visualiza todos usuarioskey
keys wp_redis_keywp:users:1 # Pega a chave
keys wp_redis_keywp:users:1 # Visualizar o usuario
keys wp_redis_keywp:userlogins:* # Visualizar logins
get wp_redis_keywp:userlogins:lucperei # Obter o numero de logins
Testes do Redis no Wordpress:
docker exec -it redis bash # Acesse o Contêiner do Redis
redis-cli # Conecte-se ao Redis CLI
keys * # Liste as Chaves no Redis
get wp:options:alloptions # Verifique o valor de uma chave específica apos alteração no wordpress
keys wp_redis_keywp:posts:* # Captura o numero da postagem pela chave
get wp_redis_keywp:posts:1 # Pega o posto pelo numero, no caso o numero 1 do Hello Word
Outras Chaves para visualizar
wp_redis_keywp:post_meta:1
wp_redis_keywp:comment:last_changed
wp_redis_keywp:post-queries
wp_redis_keywp:userlogins:wp_superuser
wp_redis_keywp:useremail:[email protected]
wp_redis_keywp:comment-queries
wp_redis_keywp:users
wp_redis_keywp:posts:last_changed
wp_redis_keywp:theme_files:wp_theme_patterns_twentytwentytwo
wp_redis_keywp:userlogins:wp_user
"wp_redis_keywp:comment:1
O servidor FTP, permite a transferência de arquivos de maneira segura e eficiente.
O servidor FTP utilizado é o vsftpd (Very Secure FTP Daemon), conhecido por sua simplicidade e segurança.
O Dockerfile criado para o serviço FTP realiza a instalação do vsftpd, copia os arquivos de configuração e define scripts de inicialização.
Por fim, o serviço é configurado no docker-compose.yml, com variáveis de ambiente para o usuário FTP e senha, volumes para persistência de dados e a definição da rede para comunicação.
Os arquivos configurados para o servidor FTP são:
Dockerfile: Realiza a construção da imagem personalizada com vsftpd.
vsftpd.conf: Arquivo de configuração do vsftpd.
start_ftp.sh: Script para inicializar o vsftpd.
Testes do FTP:
ftp lucperei.42.fr # Conectar com o nome do host
**Podemos ver estes arquivos baixados acessando conforme o exemplo abaixo:
docker exec -it ftp /bin/sh
ls -la /var/www/wordpress
chmod 0777 /var/www/wordpress/wp-content/uploads && clear &&
ls -la /var/www/wordpress/wp-content/uploads/2024/06 # Onde as imagens foram carregadas
O site estático criado e um pequeno blog desenvolvido e estilizado em markdown utilizando algumas ferramentas como o hugo-theme-m10c para estilização do site.
O Adminer é uma ferramenta de gerenciamento de banco de dados de código aberto, escrita em PHP. Ele oferece uma interface web única para interagir com múltiplos sistemas de banco de dados, como MySQL, PostgreSQL, SQLite, Microsoft SQL Server e outros. O Adminer é uma alternativa mais leve e eficiente ao phpMyAdmin.
Acesse a interface web do cAdvisor através da URL:
https://lucperei.42.fr/cadvisor/containers/
Acessar Métricas do Docker (dos Subcontainers):
https://lucperei.42.fr/cadvisor/containers/docker
Esta página exibe um painel com informações e gráficos sobre os contêineres em execução.
Principais Seções da Interface Web do cAdvisor
Um diagrama visual pode ajudar a entender a arquitetura do projeto, mostrando a relação entre os contêineres e os serviços.
O diagrama deve incluir os seguintes elementos:
A estrutura do projeto deve ser organizada para facilitar o desenvolvimento e a manutenção. Aqui está um exemplo de como os arquivos e diretórios podem ser organizados:
ft_irc/
│
├── Makefile
└── srcs/
├── .env
├── docker-compose.yml
└── requirements/
├── mariadb/
│ ├── Dockerfile
│ ├── conf/
│ | └── my.conf
│ └── tools/
│ └── setup_mariadb.sh
├── nginx/
│ ├── Dockerfile
│ └── conf/
│ └── nginx.conf
└── wordpress/
├── Dockerfile
└── conf/
└── wp-config.php
Para instalar e executar o projeto, siga estas etapas:
git clone <URL do repositório>
cd inception
docker-compose up --build
Para mais informações, consulte a documentação oficial das ferramentas e tecnologias utilizadas:
:octocat: Este projeto foi desenvolvido por Luciana Pereira, estudante da 42SP. Para mais informações, entre em contato comigo.
Seguir as melhores práticas de desenvolvimento Docker e manter a segurança do sistema são essenciais para o sucesso deste projeto. O uso de certificados SSL, a configuração adequada do banco de dados e a utilização de variáveis de ambiente para senhas e usuários são alguns dos pontos críticos a serem observados.
O desenvolvimento contínuo e a atualização das dependências garantirão a robustez e a segurança do sistema, proporcionando uma experiência estável e segura para os usuários finais.
O projeto, ao ser concluído, fornecerá uma plataforma WordPress segura e eficiente, pronta para produção, utilizando contêineres Docker para facilitar a implantação e o gerenciamento.