2 Ambientes Python com systemd no Linux: Guia Completo 2025
Leitura: ~8 min
TL;DR
- Dois projetos Python isolados: criamos dois arquivos
.serviceno systemd, cada um apontando para seu própriovenv— sem conflito de dependências. - Gerenciamento nativo: o systemd reinicia os serviços automaticamente após reboot, registra logs via
journalctle expõe status em tempo real comsystemctl status. - Erro crítico mais comum: usar
ExecStartcom o Python global em vez do Python dovenv— 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.
O systemd é nativo do Linux — sem instalação extra, sem dependência adicional. Em VPS ou servidores de produção, menos dependências = menos pontos de falha. Se o seu servidor já usa systemd (verifique com
systemctl --version), não há motivo para instalar outra camada de gerenciamento.
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.
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.
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
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.
[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.
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.
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.
Para acompanhar o que cada serviço está imprimindo agora, use:
journalctl -u projeto1.service -fO
-f funciona como um tail -f — mostra as linhas novas em tempo real. Muito útil durante o deploy inicial para pegar erros de importação ou conexão.
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.py | Ponto de entrada do script |
/opt/projeto1/requirements.txt | Lista de dependências |
/etc/systemd/system/projeto1.service | Definiçã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 status | systemctl status projeto1.service |
| Reiniciar serviço | sudo systemctl restart projeto1.service |
| Parar serviço | sudo systemctl stop projeto1.service |
| Ver logs ao vivo | journalctl -u projeto1.service -f |
| Ver logs das últimas 50 linhas | journalctl -u projeto1.service -n 50 |
| Ver logs de hoje | journalctl -u projeto1.service --since today |
| Desabilitar no boot | sudo 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
Como rodar dois scripts Python com venv diferentes no mesmo servidor Linux?
O que acontece se eu usar o Python global no ExecStart em vez do venv?
Como fazer o serviço Python reiniciar automaticamente após um crash?
Como ver os logs de um serviço Python gerenciado pelo systemd?
Como passar variáveis de ambiente secretas para um serviço systemd com segurança?
Preciso usar root para criar serviços no systemd?
O serviço Python inicia automaticamente após reboot do servidor?
Fontes e Referências
Gostou do tutorial? Tem muito mais sobre Linux e Python no canal.
Ver mais no @CanalQbFeito com Master Rules Claude v8.0 · Conteúdo assistido por IA e revisado pelo @CanalQb
dddddddddddddddddddd

Comentários
Comente só assim vamos crescer juntos!