Fedora Silverblue: Ambiente PHP com Podman - Primeira tentativa
O Podman é um mecanismo de contêiner completo e sem daemon para executar, gerenciar e depurar containers e pods compatíveis com OCI. Ele permite gerenciar containers sem a dependência do daemon e é compatível com a interface da linha de comandos do docker (CLI). O Podman também fornece uma integração aprimorada com o systemd. Com o Podman, você pode facilmente encontrar, criar, executar e compartilhar container. Mudar do Docker para o Podman é fácil e intuitivo.
O parágrafo acima foi copiado do excelente tutorial do @Danniel, por favor, leiam aqui.
Podman e Docker
O Podman é muito parecido com o Docker, e podemos criar contêineres no Podman para usarmos com o Docker e vice-versa. De fato, um dos lugares onde o Podman busca por contêineres é no docker.io. Os comandos utilizados no Podman também são praticamente os mesmos usados no Docker.
Registries
Os registries são lugares onde o podman busca por contêineres, e eles podem ser vistos no arquivo /etc/containers/registries.conf, ou com o comando podman info
. Use o arquivo de configurações se quiser adicionar ou remover algum registry. Se for apenas para consultar, use o comando podman info
:
Na imagem acima, destaquei um trecho da saída do podman info
, onde aparecem os registries:
registries: search: - registry.fedoraproject.org - registry.access.redhat.com - registry.centos.org - docker.io
Buscando por contêineres com o Podman
Vou usar um contêiner simples para introduzir o assunto e depois ir evoluindo para o uso de vários contêineres, em outros artigos. Ainda não temos um "modelo" de ambiente para desenvolvimento no Fedora Silverblue, e os usuários estão testando soluções diferentes para isso, aguns usando scripts para simulares um docker-compose, outros usando kubernetes. Como estou aprendendo a lidar com isso, vou apostar no uso de kubernetes nos próximos artigos.
Para buscar por contêineres nos registries cadastrados:
podman search lamp
Na imagem acima apareceram vários contêineres, e no caso do LAMP estão todos no docker.io. Vou escolher o que tem mais estrelas (classificação mais alta) e vou ver informações sobre ele. Para ver informações sobre um contêiner, vou usar o programa skopeo:
skopeo inspect docker://docker.io/mattrayner/lamp # Reparem no prefixo docker:// antes do endereço/usuário/contêiner
Vejamos a saída do comando acima (eu cortei a maioria das linhas em RepoTags e Layers para deixar o texto menor):
{ "Name": "docker.io/mattrayner/lamp", "Digest": "sha256:a0386b0ff145459635cd9b0fbbc1b41a3371a9b6d63ef1682842e395a98bb483", "RepoTags": [ "0.1.0", "build-153", "build-167-1604-php7", "dev", "latest" ], "Created": "2020-03-15T16:16:52.681486212Z", "DockerVersion": "17.09.0-ce", "Labels": null, "Architecture": "amd64", "Os": "linux", "Layers": [ "sha256:c64513b741452f95d8a147b69c30f403f6289542dd7b2b51dd8ba0cb35d0e08b", "sha256:01b8b12bad90b51d9f15dd4b63103ea6221b339ac3b3e75807c963e678f28624", "sha256:c5d85cf7a05fec99bb829db84dc5a21cc0aca569253f45d1ea10ca9e8a03fa9a", "sha256:5bbaab6061283824dd5472a6d038455585893ea6b638a313742ffa5338bba83c" ], "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", "DEBIAN_FRONTEND=noninteractive", "LANG=en_US.UTF-8", "LANGUAGE=en_US:en", "LC_ALL=en_US.UTF-8", "REFRESHED_AT=2019-06-11", "DOCKER_USER_ID=501", "DOCKER_USER_GID=20", "BOOT2DOCKER_ID=1000", "BOOT2DOCKER_GID=50", "PHPMYADMIN_VERSION=5.0.1", "MYSQL_PASS:-$(pwgen=-s 12 1)", "PHP_UPLOAD_MAX_FILESIZE=10M", "PHP_POST_MAX_SIZE=10M", "PHP_VERSION=7.4" ] }
Ao ver o Dockerfile do contêiner eu vi que ele vem com o ambiente que preciso. Infelizmente vem com MySQL e não com MariaDB, mas vou construir outros contêineres no futuro. Vi que ele também vem com o Composer.
Baixando o contêiner
podman pull docker.io/mattrayner/lamp
Rodando o contêiner
Para executar o contêiner em segundo plano, redirecionando a porta 8080 da máquina para a porta 80 do contêiner:
podman run -d -p 8080:80 lamp
Para ver os contêineres em execução:
podman ps
Para ver as imagens disponíveis:
podman images
Entrando no shell do contêiner
Podemos entrar no shell do contêiner (bash):
podman run -ti lamp /bin/bash
No comando acima:
- O parâmetro
-t
ou--tty
aloca um pseudo-TTY para o contêiner. - O Parâmetro
-i
ou--interactive
abre a entrada padrão STDIN do contêiner para receber comandos lamp
é o nome que dei ao contêiner no comandopodman run
feito acima./bin/bash
é o comando que quero executar no contêiner, ou seja, o shell bash para poder digitar comandos.
Vendo informações sobre o contêiner:
cat /etc/os-release
NAME="Ubuntu" VERSION="18.04.4 LTS (Bionic Beaver)" ID=ubuntu ID_LIKE=debian PRETTY_NAME="Ubuntu 18.04.4 LTS" VERSION_ID="18.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=bionic UBUNTU_CODENAME=bionic
Como estamos em um contêiner, o kernel usado é o mesmo da máquina host, ou seja, estamos num contêiner de Ubuntu, mas usando o kernel do Fedora:
uname -r
Se quiserem uma introdução sobre contêineres, vejam o curso Descomplicando o Docker, do Jefferson Fernando - LINUXtips.
Vendo o resultado no navegador
Ao acessar o navegador em http://localhost:8080, temos o servidor web rodando:
Podemos ver o phpMyAdmin rodando em http://localhost:8080/phpmyadmin
Criando usuário no MySQL
Antes de fazer o login no phpMyAdmin, vou criar um usuário no MySQL, pois o root, sem senha, não pode fazer login pela interface web. O contêiner possui um id que pode variar, no meu caso é flamboyant_ganguly, como podemos ver no resultado do comando podman ps
. Esse ID será necessário no próximo comando.
Saída do podman ps
:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES fc1f2f94b310 docker.io/mattrayner/lamp:latest /run.sh 46 minutes ago Up 46 minutes ago 0.0.0.0:8080->80/tcp flamboyant_ganguly
Criando o usuário leandro com acesso total no MySQL:
podman exec flamboyant_ganguly \ mysql -u root -e \ "GRANT ALL PRIVILEGES ON \ *.* TO 'leandro'@'%' \ IDENTIFIED BY 'senhadanasa';"
Vejam o login do usuário leandro no phpMyAdmin:
Configurando a persistência de dados
Vou reexecutar o contêiner informando volumes (lembrem-se do curso do LINUXtips se quiserem saber o que é isso) para o armazenamento do app e do banco de dados, bem como adicionando a porta do MySQL para usar programas externos ao contêiner. Mas antes disso eu preciso levar o arquivo de configuração do storage para a Home do meu usuário - para não ter problemas ao montar os volumes.
cp /etc/containers/storage.conf ~/.config/containers/storage.conf
Vou alterar as seguintes configurações no arquivo ~/.config/containers/storage.conf:
driver = "overlay" runroot = "/run/user/1000" graphroot = "/home/leo/.local/share/containers/storage" #Aqui é necessário colocar o caminho absoluto mount_program = "/usr/bin/fuse-overlayfs"
Parando e reiniciando o contêiner
Vou parar e executar novamente o contêiner:
podman stop flamboyant_ganguly
Vou criar dois diretórios dentro do meu diretório de trabalho:mkdir app
mkdir mysl
Vou iniciar o contêiner com o parâmetro --privileged
para ter permissões de escrita nos diretórios do contêiner:
podman run --privileged -d \ -p 8080:80 \ -p 3306:3306 \ -v ${PWD}/app:/app \ -v ${PWD}/mysql:/var/lib/mysql \ lamp
No comando acima, o parâmetro -v
mapeia as pastas app e mysql para as pastar correspondentes no contêiner.
Verificando as portas:
ss -ntpl
Recriando o usuário no MySQL
Preciso recriar o usuário no MySQL, pois o que foi criado anteriormente não está mais no contêiner, pois não havia persistência dos dados. Reparem que o contêiner mudou de nome, agora é peaceful_satoshi.
podman exec peaceful_satoshi mysql -u root -e "GRANT ALL PRIVILEGES ON *.* TO 'leandro'@'%' IDENTIFIED BY 'senhadanasa';"
Usando cliente externo para o acesso ao MySQL
Agora, com o usuário criado e a porta 3306 aberta, posso fazer login em clientes MySQL de fora do contêiner:
Verificando a persistência
Vou parar e iniciar novamente o contêiner
podman stop peaceful_satoshi
podman run --privileged -d \ -p 8080:80 \ -p 3306:3306 \ -v ${PWD}/app:/app \ -v ${PWD}/mysql:/var/lib/mysql \ lamp
Ao iniciar o contêiner, o usuário leandro continua com acesso ao servidor de banco de dados
Verificando a persistência dos arquivos
Vou criar um projeto Laravel no contêiner
podman exec nome-do-conteiner composer create-project laravel/laravel /app/blog
Arquivos criados no contêiner
Reiniciando o contêiner
podman stop nome-do-conteiner
podman run --privileged -d \ -p 8080:80 \ -p 3306:3306 \ -v ${PWD}/app:/app \ -v ${PWD}/mysql:/var/lib/mysql \ lamp
Ao reiniciar o contêiner, a aplicação continua gravada no disco:
E os arquivos estão gravados na pasta app do host:
Considerações finais
Coisas que preciso fazer para melhorar o procedimento:
- Criar aliases para os comandos longos
- Corrigir as permissões das pastas no host para não precisar de sudo para acessá-las
- Nomear os contêineres para não usar contêineres com nomes diferentes a cada reinício
- Melhorar o virtualhost no Apache para não precisar digitar o /public no final da URL
Mas, por enquanto, foi suficiente para mostrar um pouco do uso do podman como solução para o trablaho com contêineres para desenvolvimento.
Abraços, pessoal.
Comentários
-
Muito bom , meus parabéns .
próximo passo é fazer um podman-compose pra subir tudo0 -
Obrigado, @Danniel. Eu vou fazer um pouco diferente. Vou usar a toolbox para o PHP e NodeJS, e um contêiner para o MariaDB no Podman. Acho que vai ficar mais simples para eu entender como as coisas funcionam, e depois eu uso o podman-compose para outros serviços. Estou escrevendo a segunda tentativa agora rsrs.
0 -
@leandroramos Muito bom, Gostei me ajudou muito. Parabéns tive um pouco de dificuldades mais no final foi sucesso.
0
Salas de discussão
- 722 Todas as salas de discussão
- 5 Eventos
- 403 Fedora
- 7 CoreOS
- 138 Spins
- 11 CINNAMON
- 28 GNOME
- 64 KDE
- 10 LXDE
- 4 LXQT
- 13 MATE
- SOAS
- 3 XFCE
- 13 Server
- 84 Workstation
- 33 SilverBlue
- Atomic
- 3 Labs
- ARM®
- 3 Segurança
- 7 Servidores
- 222 Tutoriais
- 6 Críticas e Sugestões
- 16 Novidades e anuncios
- 5 CentOS
- 18 Games
- 31 Hardware
- 8 Linguagens de programação