Os tempos mudam e as melhores práticas também.
A melhor maneira atual de fazer isso é executar systemctl edit myservice
, o 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ê poderá adicionar ou substituir qualquer parte da unidade enviada pela distribuição.
Por exemplo, em um arquivo /etc/systemd/system/myservice.service.d/myenv.conf
:
[Service]
Environment="SECRET=pGNqduRFkB4K9C2vijOmUDa2kPtUhArN"
Environment="ANOTHER_SECRET=JP8YLOc2bsNlrGuD6LVTq7L36obpjzxd"
Observe também que, se o diretório existir e estiver vazio, seu serviço será desativado! Se você não pretende colocar algo no diretório, verifique se ele não existe.
Para referência, o caminho antigo era:
A maneira recomendada de fazer isso é criar um arquivo /etc/sysconfig/myservice
que contenha suas variáveis e carregá-las EnvironmentFile
.
Para detalhes completos, consulte a documentação do Fedora sobre como escrever um script systemd .
sysconfig
caminho é específico para o Fedora, mas a pergunta é sobre o Arch Linux. A resposta por paluh é mais interessante eu acho/etc/sysconfig
é específico do Fedora. O AFAIR Arch Linux estava pressionando por ter os arquivos de configuração em algum lugar específico do pacote e não no/etc
local específico do Fedora. Como/etc/myservice.conf
, embora o uso de arquivo extra não pareça o caminho certo aqui.DJANGO_SETTINGS_MODULE=project.settings
um por linha.A resposta depende se a variável deve ser constante (ou seja, não deve ser modificada pelo usuário obtendo a unidade) ou variável (que deve ser definida pelo usuário).
Como é a sua unidade local, o limite é bastante desfocado e de qualquer forma funcionaria. No entanto, se você começar a distribuí-lo e ele acabar
/usr/lib/systemd/system
, isso se tornará importante.Valor constante
Se o valor não precisar mudar 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, é mais fácil mover o arquivo da unidade entre os sistemas.
Valor 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 da unidade for atualizado.
Nesse 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. Diferente de outras soluções, esse diretório é suportado pelo próprio systemd e, portanto, não possui caminhos específicos da distribuição.Nesse caso, você coloca um arquivo assim
/etc/systemd/system/myservice.service.d/local.conf
que adiciona as partes ausentes do arquivo de unidade:Depois, o systemd mescla os dois arquivos ao iniciar o serviço (lembre-se de
systemctl daemon-reload
depois de alterar um deles). E como esse caminho é usado diretamente pelo systemd, você não o usaEnvironmentFile=
.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.
fonte
systemctl daemon-reload
é o comando para recarregar systemdEnvironmentFile=
é melhor quando os valores são segredos, como senhas. Veja minha resposta para detalhes.http://0pointer.de/public/systemd-man/systemd.exec.html#Environment= - você tem duas opções (uma já apontada por Michael):
e
fonte
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 será acidentalmente comprometido com o controle de origem com o código do aplicativo.
Se é por isso que você deseja 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:
Coloquei um arquivo de configuração em
/etc/my_service/my_service.conf
e coloquei meus segredos lá:Em seguida, no meu arquivo de unidade de serviço, usei
EnvironmentFile=
:Eu verifiquei que
ps auxe
não consigo ver essas variáveis de ambiente e outros usuários não têm acesso/proc/*/environ
. Verifique seu próprio sistema, é claro.fonte
Michael deu uma solução limpa, mas eu queria obter a variável env atualizada do script. Infelizmente, executar comandos bash não é possível no arquivo de unidade systemd. Felizmente, você pode ativar 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:
fonte
/bin/bash -a -c 'source /etc/sysconfig/whatever && exec whatever-program'
. Os-a
garante o ambiente é exportado para o sub-processo (a menos que você deseja prefixar todas as variáveis emwhatever
comexport
)ExecStart=/usr/bin/env ENV=script /bin/myforegroundcmd
seja uma solução um pouco melhor neste caso.