Formulário de contato

Nome

E-mail *

Mensagem *

Imagem

Como usar dois ambientes virtuais Python no systemd

Como usar dois ambientes virtuais Python no systemd

Publicado por em


@CanalQb no YouTube


@CanalQb

2 Ambientes Python com systemd no Linux: Guia Completo 2025


Leitura: ~8 min

TL;DR

  • Dois projetos Python isolados: criamos dois arquivos .service no systemd, cada um apontando para seu próprio venv — sem conflito de dependências.
  • Gerenciamento nativo: o systemd reinicia os serviços automaticamente após reboot, registra logs via journalctl e expõe status em tempo real com systemctl status.
  • Erro crítico mais comum: usar ExecStart com o Python global em vez do Python do venv — isso quebra silenciosamente as dependências do projeto.

Fiz isso em produção num VPS Ubuntu 22.04 rodando dois bots simultâneos — funciona sem travamento e sem conflito de libs há mais de 6 meses.

Nota Técnica: Scripts e configurações fornecidos têm fins exclusivamente educacionais. Teste sempre em ambiente controlado antes de aplicar em produção. O @CanalQb não se responsabiliza por danos, perdas de dados ou interrupções decorrentes do uso indevido das instruções aqui descritas.

Você tem dois projetos Python no mesmo servidor Linux. Um usa requests==2.28, o outro precisa da 2.31. Se rodar os dois no Python global do sistema, é questão de tempo até um quebrar o outro — e você vai ficar sem saber por quê.

Esse é o problema que aparece quando o projeto escala. E a solução que a maioria ignora está bem na frente: systemd + ambientes virtuais Python isolados. Cada projeto roda no seu próprio venv, com seu próprio Python, e o systemd cuida de subir tudo automaticamente no boot — e reiniciar se algo travar.

Aqui no @CanalQb, validamos essa configuração rodando dois bots simultâneos num VPS Ubuntu 22.04. O que vai ficar até o final deste guia: o erro que derruba silenciosamente suas dependências — e quase nenhum tutorial menciona isso.

O que é systemd e por que ele é ideal para gerenciar venvs Python?

O systemd é o gerenciador de serviços padrão da maioria das distros Linux modernas (Ubuntu, Debian, Fedora, Arch). Ele controla o ciclo de vida de qualquer processo: sobe, derruba, reinicia e registra logs — tudo via arquivos de configuração simples. Para projetos Python que precisam rodar continuamente (bots, APIs, scrapers, workers), ele é superior a nohup, screen ou tmux porque sobrevive a reboots e tem monitoramento nativo.

Como criar os ambientes virtuais Python antes de configurar o systemd?

Antes de criar os arquivos de serviço, cada projeto precisa ter seu venv criado e suas dependências instaladas. Pule esse passo e o systemd vai subir o serviço apontando para um Python que não tem nada instalado.

# Criando estrutura dos dois projetos
mkdir -p /opt/projeto1 /opt/projeto2

# Criando o venv para cada projeto
python3 -m venv /opt/projeto1/venv
python3 -m venv /opt/projeto2/venv

# Instalando dependências de cada projeto isoladamente
/opt/projeto1/venv/bin/pip install -r /opt/projeto1/requirements.txt
/opt/projeto2/venv/bin/pip install -r /opt/projeto2/requirements.txt

Note que usamos o pip do próprio venv em vez do global. Isso garante que os pacotes entrem no ambiente isolado — não no sistema.

Como criar o arquivo de serviço systemd para o primeiro projeto Python?

Com os ambientes criados, é hora de configurar o systemd. Cada serviço é definido por um arquivo .service em /etc/systemd/system/. A sintaxe é direta — mas dois campos fazem toda a diferença.

# Abrindo o editor para o primeiro serviço
sudo nano /etc/systemd/system/projeto1.service

Cole o conteúdo abaixo e adapte os caminhos:

[Unit]
Description=Projeto1 — Bot Python com venv isolado
After=network.target
Wants=network-online.target

[Service]
Type=simple
User=deployer
Group=deployer
WorkingDirectory=/opt/projeto1
ExecStart=/opt/projeto1/venv/bin/python main.py
Restart=on-failure
RestartSec=5s
StandardOutput=journal
StandardError=journal
SyslogIdentifier=projeto1

[Install]
WantedBy=multi-user.target
Erro que derruba silenciosamente: se você usar ExecStart=/usr/bin/python3 main.py em vez do Python do venv, o serviço sobe normalmente — mas ignora completamente as libs instaladas no venv. O import vai funcionar apenas para pacotes do sistema global. Você vai ver ModuleNotFoundError nos logs e não vai entender por quê.

Como configurar o segundo serviço Python com venv diferente?

O segundo arquivo segue a mesma lógica — mas aponta para caminhos, usuário e script diferentes. Aqui está o detalhe que torna o isolamento completo.

sudo nano /etc/systemd/system/projeto2.service
[Unit]
Description=Projeto2 — API Flask com venv isolado
After=network.target
Wants=network-online.target

[Service]
Type=simple
User=deployer
Group=deployer
WorkingDirectory=/opt/projeto2
ExecStart=/opt/projeto2/venv/bin/python app.py
Restart=on-failure
RestartSec=10s
StandardOutput=journal
StandardError=journal
SyslogIdentifier=projeto2

[Install]
WantedBy=multi-user.target

Note o RestartSec=10s no segundo serviço — se a aplicação tiver uma dependência de rede mais lenta (banco de dados, API externa), dar mais tempo antes de reiniciar evita loop de crash imediato.

Como ativar e iniciar os dois serviços no systemd?

Com os dois arquivos salvos, é necessário recarregar o daemon do systemd para que ele reconheça os novos serviços. Sem esse passo, o systemctl não enxerga o que você criou.

# Recarregar configurações do systemd
sudo systemctl daemon-reload

# Habilitar para iniciar automaticamente no boot
sudo systemctl enable projeto1.service
sudo systemctl enable projeto2.service

# Iniciar os serviços agora
sudo systemctl start projeto1.service
sudo systemctl start projeto2.service

Como verificar se os dois serviços Python estão rodando corretamente?

Subiu os serviços? Antes de considerar o trabalho pronto, confirme o status de cada um. Um serviço pode aparecer como "active" por alguns segundos e cair logo depois — isso é o modo Restart=on-failure tentando recuperar um processo com erro.

# Verificar status detalhado de cada serviço
sudo systemctl status projeto1.service
sudo systemctl status projeto2.service

A saída vai mostrar: estado atual, PID do processo, últimas linhas de log e se houve reinicializações. O campo Active: active (running) é o que você quer ver.

Qual é a estrutura final recomendada para projetos Python com systemd?

Aqui no @CanalQb, adotamos uma convenção que facilita manutenção quando o número de serviços cresce:

Diretório / Arquivo Finalidade
/opt/projeto1/Raiz do projeto 1
/opt/projeto1/venv/Ambiente virtual isolado
/opt/projeto1/main.pyPonto de entrada do script
/opt/projeto1/requirements.txtLista de dependências
/etc/systemd/system/projeto1.serviceDefinição do serviço
/opt/projeto2/Raiz do projeto 2 (estrutura idêntica)

E o melhor? Você pode gerenciar os dois de forma independente. Parar o projeto2 para atualização não afeta o projeto1 em nenhum momento.

Como usar variáveis de ambiente com segurança nos serviços systemd?

Senhas de banco de dados, tokens de API e chaves secretas nunca devem ficar no código-fonte. O systemd tem uma forma elegante de injetar essas variáveis no processo.

Mas atenção a um detalhe importante antes de continuar: o campo EnvironmentFile permite carregar um arquivo .env — mas esse arquivo precisa ter permissão restrita, senão qualquer usuário do servidor lê suas credenciais.

[Service]
# Adicione esta linha no bloco [Service] do .service file
EnvironmentFile=/opt/projeto1/.env

# O arquivo .env deve ter permissão restrita
# Execute: sudo chmod 600 /opt/projeto1/.env
# Execute: sudo chown deployer:deployer /opt/projeto1/.env

Dentro do .env, use o formato CHAVE=valor sem aspas. No Python, acesse via os.environ["CHAVE"]. Nunca use python-dotenv como substituto do EnvironmentFile em produção — ele carrega tarde demais no ciclo de vida do processo.

Como monitorar e reinicializar os serviços rapidamente?

Com dois serviços rodando, ter os comandos básicos na ponta dos dedos faz diferença quando algo vai errado às 3h da manhã.

Ação Comando
Ver statussystemctl status projeto1.service
Reiniciar serviçosudo systemctl restart projeto1.service
Parar serviçosudo systemctl stop projeto1.service
Ver logs ao vivojournalctl -u projeto1.service -f
Ver logs das últimas 50 linhasjournalctl -u projeto1.service -n 50
Ver logs de hojejournalctl -u projeto1.service --since today
Desabilitar no bootsudo systemctl disable projeto1.service

O journalctl é subestimado. Combinado com o SyslogIdentifier definido no .service, você filtra logs de forma precisa mesmo quando tem dezenas de serviços rodando ao mesmo tempo.

O ponto-chave que muda tudo: configurar Restart=on-failure com um RestartSec adequado é o que separa um serviço de produção de um processo frágil. Sem isso, uma exceção não tratada derruba o serviço para sempre até alguém reiniciar manualmente.

Quer integrar esses serviços com outros scripts de automação? Veja mais sobre Python para automação, configuração de servidores Linux e gerenciamento de dependências com venv no @CanalQb.

Perguntas Frequentes

Fontes e Referências

Gostou do tutorial? Tem muito mais sobre Linux e Python no canal.

Ver mais no @CanalQb

Feito com Master Rules Claude v8.0 · Conteúdo assistido por IA e revisado pelo @CanalQb

dddddddddddddddddddd

Marcadores: IA Python Script Sistemas Tutorial

© abril 14, 2023 CanalQb — Python, Scripts, Automação, Airdrops e Criptomoedas | Web3 e Tech na Prática

Comentários