Eu tenho um sistema Arch Linux com systemd e criei meu próprio serviço. O serviço de configuração em /etc/systemd/system/myservice.service
se parece com isso:
[Unit]
Description=My Daemon
[Service]
ExecStart=/bin/myforegroundcmd
[Install]
WantedBy=multi-user.target
Agora eu quero ter uma variável de ambiente definida para o /bin/myforegroundcmd
. Como faço isso?
Os tempos mudam e as melhores práticas também.
A melhor maneira atual de fazer isso é executar
systemctl edit myservice
, que criará um arquivo de substituição para você ou permitirá que você edite um existente.Em instalações normais, isso criará um diretório
/etc/systemd/system/myservice.service.d
e, dentro desse diretório, criará um arquivo cujo nome termina em.conf
(normalmente,override.conf
), e nesse arquivo você pode adicionar ou substituir qualquer parte da unidade enviada pela distribuição.Por exemplo, em um arquivo
/etc/systemd/system/myservice.service.d/myenv.conf
:Observe também que se o diretório existir e estiver vazio, seu serviço será desabilitado! Se você não pretende colocar algo no diretório, verifique se ele não existe.
Para referência, a maneira antiga era:
A maneira recomendada de fazer isso é criar um arquivo
/etc/sysconfig/myservice
que contenha suas variáveis e carregá-las com a extensãoEnvironmentFile
.Para detalhes completos, veja a documentação do Fedora sobre como escrever um script systemd .
A resposta depende se a variável deve ser constante (ou seja, não deve ser modificada pelo usuário que obtém a unidade) ou variável (deve ser definida pelo usuário).
Como é sua unidade local, o limite é bastante embaçado e de qualquer maneira funcionaria. No entanto, se você começasse a distribuí-lo e acabasse em
/usr/lib/systemd/system
, isso se tornaria importante.Valor constante
Se o valor não precisar ser alterado por instância, a maneira preferida seria colocá-lo como
Environment=
, diretamente no arquivo da unidade:A vantagem disso é que a variável é mantida em um único arquivo com a unidade. Portanto, o arquivo de unidade é mais fácil de mover entre os sistemas.
Valor da variável
No entanto, a solução acima não funciona bem quando o sysadmin deve alterar o valor da variável de ambiente localmente. Mais especificamente, o novo valor precisaria ser definido toda vez que o arquivo de unidade fosse atualizado.
Para este caso, um arquivo extra deve ser usado. Como — geralmente depende da política de distribuição.
Uma solução particularmente interessante é usar o
/etc/systemd/system/myservice.service.d
diretório. Ao contrário de outras soluções, esse diretório é suportado pelo próprio systemd e, portanto, não possui caminhos específicos de distribuição.Neste caso, você coloca um arquivo assim
/etc/systemd/system/myservice.service.d/local.conf
adiciona as partes que faltam do arquivo unit:Depois, o systemd mescla os dois arquivos ao iniciar o serviço (lembre-se de
systemctl daemon-reload
alterar um deles). E como esse caminho é usado diretamente pelo systemd, você não usaEnvironmentFile=
para isso.Se o valor deve ser alterado apenas em alguns dos sistemas afetados, você pode combinar as duas soluções, fornecendo um padrão diretamente na unidade e uma substituição local no outro arquivo.
http://0pointer.de/public/systemd-man/systemd.exec.html#Environment= - você tem duas opções (uma já apontada por Michael):
e
As respostas de Michael e Michał são úteis e respondem à pergunta original de como definir uma variável de ambiente para um serviço systemd. No entanto, um uso comum para variáveis de ambiente é configurar dados confidenciais, como senhas, em um local que não seja confirmado acidentalmente no controle de origem com o código do seu aplicativo.
Se é por isso que você quer passar uma variável de ambiente para o seu serviço, não use
Environment=
no arquivo de configuração da unidade. UseEnvironmentFile=
e aponte para outro arquivo de configuração que seja legível apenas pela conta de serviço (e usuários com acesso root).Os detalhes do arquivo de configuração da unidade são visíveis para qualquer usuário com este comando:
Eu coloquei um arquivo de configuração em
/etc/my_service/my_service.conf
e coloquei meus segredos lá:Então, no meu arquivo de unidade de serviço, usei
EnvironmentFile=
:Verifiquei que
ps auxe
não consigo ver essas variáveis de ambiente e outros usuários não têm acesso a arquivos/proc/*/environ
. Verifique em seu próprio sistema, é claro.Michael deu uma solução limpa, mas eu queria obter a variável env atualizada do script. Infelizmente, a execução de comandos bash não é possível no arquivo de unidade systemd. Felizmente, você pode acionar o bash dentro do ExecStart:
http://www.dsm.fordham.edu/cgi-bin/man-cgi.pl?topic=systemd.service§=5
Exemplo no nosso caso é então:
Não use Environment= ou EnvironmentFile= para credenciais/segredos.
Por https://www.freedesktop.org/software/systemd/man/systemd.exec.html#Environment
Você deveria usar
LoadCredential=, LoadCredentialEncrypted= or SetCredentialEncrypted=