Guia prático para quem precisa configurar a livraria jardim
Eu passei três dias tentando fazer a livraria jardim funcionar num servidor Debian 12 antes de perceber que o problema não era o código-fonte e sim a configuração do PostgreSQL. O sistema pede uma versão mínima de 14, mas o repositório padrão do Debian ainda traz o 15 como estável. Se você seguir o tutorial do GitHub sem verificar isso, vai receber um erro de conexão que parece ter a ver com Redis mas na verdade é só o banco não iniciando direito. Eu gastei quatro horas caçando logs de permissão no /var/log/postgresql quando bastava rodar um apt-get install postgresql-15.
O que a livraria jardim realmente faz
A livraria jardim é uma aplicação web open-source voltada para gestão de estoque e vendas de livros, desenvolvida originalmente por editores independentes brasileiros. Ela roda em Python com Django no backend e React no frontend, e a parte mais confusa pra quem chega agora é que existem pelo menos duas versões distintas: a v2.3 com suporte a NFC-e e a v2.1 que só gera NFS-e. O instalador automático não faz essa distinção e simplesmente baixa o repositório principal. Se você trabalha com comércio eletrônico de livros em São Paulo, por exemplo, vai precisar da versão com NFC-e porque a prefeitura exige emissão eletrônica em tempo real. Na prática, eu costumo baixar o código manualmente e verificar o arquivo requirements.txt antes de rodar o pip install. O sistema de inventário é onde mais gente trava. A livraria jardim usa um esquema de codificação interna baseado em ISBN-13 com checksum próprio, mas o importador padrão espera arquivos CSV com colunas exatas: SKU, título, autor, preço_custo, preço_venda, quantidade_estoque, categoria_id. Qualquer coisa fora dessa ordem gera um erro silencioso que só aparece depois de carregar centenas de registros. Minha solução foi criar um script de validação em Bash que roda antes da importação e verifica a quantidade de colunas e o formato de cada campo. Isso economiza cerca de trinta minutos por lote em vez de perder duas horas depurando depois.
Configuração passo a passo no Ubuntu 22.04
Comece instalando as dependências do sistema. O comando direto é sudo apt update e sudo apt install python3-pip postgresql redis-server git build-essential. Aqui tem uma pegadinha: o pacote build-essential é obrigatório porque o módulo de geração de PDF da livraria jardim compila extensões C nativas. Se pular isso, o ImportError vai aparecer na primeira impressão de nota fiscal e o erro não é óbvio. Eu também sempre instalo o curl e o jq porque o sistema de health-check da aplicação depende de requisições externas para validar a integração com a SEFAZ. Após isso, clone o repositório e entre na pasta. O repositório oficial fica em github.com/livraria-jardim/core mas já tive problemas de DNS com o domínio principal. Se o clone falhar, use o mirror no GitLab que tem exatamente o mesmo conteúdo e uma seção de issues mais ativa. Entre na versão certa antes de prosseguir: git checkout tags/v2.3.1. Sem o checkout, você fica na branch main que ainda está na versão 3.0 beta e tem breaking changes na API de produtos que quebram módulos legados de integração com distribuidoras.
Crie o banco de dados. Eu uso este sequence de comandos: sudo -u postgres psql, depois CREATE DATABASE livraria_jardim OWNER postgres; e GRANT ALL PRIVILEGES ON DATABASE livraria_jardim TO postgres;. O erro mais comum aqui é esquecer o GRANT. O Django cria as tabelas sem problema mas o usuário do aplicativo não consegue escrever. O resultado é um error 1045 do MySQL que na verdade é PostgreSQL e ninguém nunca acha porque o log diz "connection refused" em vez de "permission denied".
Configurando o ambiente virtual
Python virtualenv é essencial porque a livraria jardim congela versões específicas de packages que conflitam com bibliotecas do sistema. O comando é python3 -m venv venv e source venv/bin/activate. Dentro do ambiente, rode pip install -r requirements.txt. Meurequirements.txt personalizado adiciona django-environ==1.0.0 porque a versão padrão do Django não lê variáveis de ambiente corretamente quando o sistema é deployado com docker-compose, algo que eu enfrentei quando migrei meu ambiente de produção. A configuração de variáveis de ambiente fica no arquivo .env na raiz do projeto. A livraria jardim exige os seguintes campos: DJANGO_SECRET_KEY, DATABASE_URL, REDIS_URL, NFC_E_CNF_MODE, SEFAZ_INSCRICAO_ESTADUAL. O DJANGO_SECRET_KEY precisa ter pelo menos 50 caracteres e ser gerado aleatoriamente, porque o framework faz validação de integridade das sessões e senhas hashadas. Eu uso um gerador interno chamado django-admin shell_plus e executo from django.core.management.utils import get_random_secret_key para criar a chave. A URL do banco segue o padrão postgres://postgres:suasenha@localhost:5432/livraria_jardim.
O campo NFC_E_CNF_MODE recebe o valor prod ou homolog. Se você colocar qualquer outra coisa, a livraria jardim ignora e cai em modo offline, o que significa que as notas fiscais não são enviadas para a SEFAZ. Isso já me custou dois dias porque o sistema parecia funcionar mas as notas ficavam salvas localmente sem saída. A dica prática é Sempre testar no modo homolog primeiro, mesmo que seja para desenvolvimento local. A SEFAZ de SP permite até cem requisições por minuto no ambiente de homologação e nunca bloqueia o IP do desenvolvedor, o que não acontece no ambiente produtivo.
👉 Clique no botão abaixo para saber mais sobre o assunto!
Problemas comuns e soluções reais
O maior problema que eu encontrei na prática foi com a conciliação bancária automática. A livraria jardim tenta fazer match entre extratos CSV do banco e vendas registradas usando o campo data_hora com formatação padrão ISO 8601. Quando o banco fornece o arquivo com datas no formato brasileiro DD/MM/YYYY, o sistema não converte automaticamente. A solução que eu implementei foi um adaptador em Python que lê o arquivo, converte as datas e sobrescreve o CSV temporário antes da importação. Isso resolveu em quinze minutos algo que o suporte oficial recomenda resolver manualmente em seis horas. Outro problema recorrente é o timeout na geração de PDFs de notas fiscais. O módulo de PDF usa reportlab em versão antiga que trava quando o arquivo tem mais de cinqüenta linhas. No meu caso, notes fiscais de pedidos com muitas parcelas travavam o processamento e deixavam o sistema indisponível por até doze minutos. A workaround foi aumentar o timeout do Django no settings.py para 300 segundos e também configurar um worker separado com Celery para processamento assíncrono de PDFs. O tempo de geração caiu de doze minutos para cerca de quarenta segundos por nota.
A livraria jardim também tem uma limitação séria na busca de produtos por atributos customizados. O motor de busca padrão indexa apenas título, autor e ISBN. Se você precisar buscar por editora, coleção ou faixa etária, o sistema retorna resultado vazio mesmo quando os dados existem no banco. A correção exige modificações no indexes.py do módulo de search, adicionando os campos ao campo SearchField. Isso quebra o upgrade automático porque o arquivo é sobrescrito a cada atualização. Minha recomendação é usar branching e manter os patches em uma pasta separada chamada patches/ que é aplicada manualmente após cada atualização.
Deploy em produção com Docker
O Dockerfile oficial da livraria jardim funciona mas não inclui otimizações de cache. O build leva aproximadamente trinta minutos em uma máquina com 4GB de RAM porque ele baixa dependências do PyPI sem layer caching adequado. Eu modifiquei o Dockerfile copiando primeiro o requirements.txt e rodando o pip install antes de copiar o restante do código. Com essa mudança, o rebuild cai para cerca de cinco minutos e o cache do pip é aproveitado corretamente. O docker-compose.yml precisa de pelo menos dois serviços: o web app e o worker do Celery. Coloquei o banco e o Redis como serviços externos porque a livraria jardim se beneficia de ter o banco rodando fora do container para permitir backups tradicionais com pg_dump. A conexão entre os containers é feita pela rede interna do compose, o que elimina a necessidade de expor portas. Em produção, eu expus apenas a porta 8000 do container web para o host e usei um nginx reverso na frente para TLS. A livraria jardim não gerencia certificados SSL nativamente, então depende de um proxy reverso para isso.
Um ponto que merece atenção é a configuração do horário. A livraria jardim armazena datas em UTC no banco mas exibe no fuso horário configurado no settings.py. Se você colocar TIME_ZONE = America/Sao_Paulo, as notas fiscais emitidas terão datas corretas, mas o relatório de vendas diárias pode mostrar transações do dia anterior quando o horário de verão entra em vigor. Esse bug existe desde a versão 2.2 e ainda não foi corrigido na branch principal. A solução paliativa que eu uso é desconectar o sistema do horário de verão manualmente editando o arquivo de timezone e definindo fixed offset -03:00.
Manutenção e monitoramento
A livraria jardim não vem com painel de monitoramento integrado. O que eu fiz foi integrar o Prometheus com o endpoint /metrics exposto pelo Django e configurar alertas no Grafana para uso de CPU, memória e tempo de resposta das requisições de venda. O sistema gera métricas automaticamente quando o middleware de metrics está habilitado no settings. Isso permitiu que eu identificasse um gargalo no endpoint de finalização de pedido que levava em média 2,3 segundos por requisição, sendo 1,8 segundos gastos apenas na geração do PDF da nota fiscal. Backups devem ser feitos diariamente. O comando que eu uso é pg_dump livraria_jardim | gzip > /backups/livraria_jardim_$(date +%Y%m%d).sql.gz. A livraria jardim também armazena arquivos uploadados em mídia no sistema de arquivos, que precisam ser copiados separadamente. Eu configurei um rsync para copiar a pasta media/ para um bucket S3 compatível todas as noites. O tempo total de backup completo, banco mais mídia, leva cerca de vinte minutos para uma instalação com trinta mil produtos e duzentas mil vendas nos últimos doze meses.
Quando a livraria jardim precisa ser atualizada, o processo oficial recomenda backup completo, pull do repositório, migração de banco e reinício dos serviços. Na prática, migrações incrementais podem falhar se houver campos customizados adicionados manualmente ao banco. Minha estratégia é sempre criar snapshots do banco antes de atualizar e testar as migrações em ambiente de staging antes de aplicar em produção. Isso reduz significativamente o risco de downtime e garante que a livraria jardim volte ao ar rapidamente mesmo quando algo dá errado.