Qual é a maneira recomendada de lidar com as configurações do desenvolvimento local e do servidor de produção? Alguns deles (como constantes, etc.) podem ser alterados / acessados em ambos, mas alguns deles (como caminhos para arquivos estáticos) precisam permanecer diferentes e, portanto, não devem ser substituídos toda vez que o novo código for implantado.
Atualmente, estou adicionando todas as constantes a settings.py
. Mas sempre que altero alguma constante localmente, tenho que copiá-la para o servidor de produção e editar o arquivo para alterações específicas de produção ... :(
Edit: parece que não há resposta padrão para esta pergunta, eu aceitei o método mais popular.
python
django
deployment
akv
fonte
fonte
Respostas:
Em
settings.py
:Você pode substituir o que é necessário
local_settings.py
; deve ficar fora do seu controle de versão. Mas desde que você mencionou a cópia, acho que você não usa nenhuma;)fonte
settings_local
em vezlocal_settings
de agrupá-losettings.py
nas listagens de pastas alfabéticas. Mantenhasettings_local.py
fora do controle de versão,.gitignore
pois as credenciais não pertencem ao Git. Imagine abrir fontes por acidente. Eu mantenho no git um arquivo de modelo chamadosettings_local.py.txt
.Duas dicas do Django: Práticas recomendadas para o Django 1.5 sugerem o uso de controle de versão para seus arquivos de configurações e o armazenamento em um diretório separado:
O
base.py
arquivo contém as definições comuns (como MEDIA_ROOT ou ADMIN), enquantolocal.py
eproduction.py
tem configurações específicas do local:No arquivo base
settings/base.py
:No arquivo de configurações de desenvolvimento local
settings/local.py
:No arquivo de configurações de produção de arquivo
settings/production.py
:Então, quando você executa o django, você adiciona a
--settings
opção:Os autores do livro também colocaram um modelo de layout de projeto de amostra no Github.
fonte
--settings
sempre, você pode definir oDJANGO_SETTINGS_MODULE
envvar. Isso funciona bem com, por exemplo, o Heroku: defina-o globalmente para produção e substitua-o pelo dev no seu arquivo .env.DJANGO_SETTINGS_MODULE
env var é a melhor ideia aqui, obrigado Simon.BASE_DIR
as configurações paraos.path.dirname(os.path.realpath(os.path.dirname(__file__) + "/.."))
from django.conf import settings
um objeto que abstrai a interface e desacopla o código da localização das configurações, docs.djangoproject.com/en/dev/topics/settings/…Em vez de
settings.py
, use este layout:common.py
é onde vive a maior parte de sua configuração.prod.py
importa tudo de comum e substitui o que for necessário para substituir:Da mesma forma,
dev.py
importa tudocommon.py
e substitui o que for necessário para substituir.Por fim,
__init__.py
é onde você decide quais configurações carregar e também onde armazena segredos (portanto, esse arquivo não deve ser versionado):O que eu gosto nesta solução é:
common.py
.prod.py
, coisas específicas do Dev entramdev.py
. É simples.common.py
dentro deprod.py
ou oudev.py
substituir qualquer item__init__.py
.fonte
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "foobar.settings")
foobar é uma pasta com um__init__.py
arquivo e as configurações são uma pasta com um__init__.py
arquivo que contém meus segredos e importa dev.py, que importa o common.py. EDIT Não importa, eu não tinha um módulo instalado necessário. Foi mal! Isso funciona muito bem !!Eu uso uma versão ligeiramente modificada do estilo "if Debug" das configurações que Harper Shelby postou. Obviamente, dependendo do ambiente (win / linux / etc.), O código pode precisar ser ajustado um pouco.
Eu estava usando o "if DEBUG" no passado, mas descobri que ocasionalmente precisava fazer testes com o DEUBG definido como False. O que eu realmente queria distinguir se o ambiente fosse produção ou desenvolvimento, o que me deu a liberdade de escolher o nível DEBUG.
Eu ainda consideraria esse modo de configuração um trabalho em andamento. Eu não vi nenhuma maneira de lidar com as configurações do Django que cobriam todas as bases e, ao mesmo tempo, não era um aborrecimento total para configurar (eu não conheço os métodos dos arquivos de configurações de 5x).
fonte
os.environ['COMPUTERNAME']
infelizmente não funciona no PythonAnywhere. Você recebe um KeyError.Eu uso um settings_local.py e um settings_production.py. Depois de tentar várias opções, descobri que é fácil perder tempo com soluções complexas quando simplesmente ter dois arquivos de configuração é fácil e rápido.
Quando você usa mod_python / mod_wsgi para o seu projeto Django, você precisa apontar para o seu arquivo de configurações. Se você apontar para app / settings_local.py no servidor local e app / settings_production.py no servidor de produção, a vida se tornará fácil. Apenas edite o arquivo de configurações apropriado e reinicie o servidor (o servidor de desenvolvimento do Django será reiniciado automaticamente).
fonte
python manage.py runserver
), qual arquivo de configurações usar?TL; DR: O truque é modificar
os.environment
antes de importarsettings/base.py
em qualquersettings/<purpose>.py
, isso vai simplificar muito as coisas.Só de pensar em todos esses arquivos entrelaçados me dá dor de cabeça. Combinando, importando (às vezes condicionalmente), substituindo, corrigindo o que já foi definido, caso a
DEBUG
configuração seja alterada posteriormente. Que pesadelo!Ao longo dos anos, passei por todas as soluções diferentes. Todos eles funcionam um pouco , mas são tão difíceis de gerenciar. WTF! Realmente precisamos de todo esse aborrecimento? Começamos com apenas um
settings.py
arquivo. Agora precisamos de uma documentação apenas para combinar corretamente tudo isso em uma ordem correta!Espero finalmente chegar ao (meu) ponto ideal com a solução abaixo.
Vamos recapitular os objetivos (alguns comuns, outros meus)
Mantenha segredos em segredo - não os guarde em um repositório!
Defina / leia chaves e segredos através das configurações do ambiente, estilo de 12 fatores .
Tenha padrões de fallback sensatos. Idealmente para o desenvolvimento local, você não precisa de mais nada além dos padrões.
… Mas tente manter a produção dos padrões segura. É melhor perder uma substituição de configuração localmente do que lembrar de ajustar as configurações padrão seguras para produção.
Tem a capacidade de ligar
DEBUG
/ desligar de uma maneira que possa afetar outras configurações (por exemplo, usando javascript compactado ou não).A alternância entre as configurações de finalidade, como local / teste / preparação / produção, deve basear-se apenas em
DJANGO_SETTINGS_MODULE
nada mais.… Mas permita parametrização adicional por meio de configurações do ambiente como
DATABASE_URL
.… Também permite que eles usem configurações de finalidade diferentes e as executem localmente lado a lado, por exemplo. configuração de produção na máquina local do desenvolvedor, para acessar o banco de dados de produção ou as folhas de estilo compactadas para teste de fumaça.
Falha se uma variável de ambiente não estiver definida explicitamente (exigindo um valor vazio no mínimo), especialmente na produção, por exemplo.
EMAIL_HOST_PASSWORD
.Responda ao padrão
DJANGO_SETTINGS_MODULE
definido em manage.py durante o django-admin startprojectMantenha as condições mínimas, se a condição for o tipo de ambiente proposto (por exemplo, para o arquivo de log do conjunto de produção e sua rotação), substitua as configurações no arquivo de configurações propostas associado.
Não
Não permita que o django leia a configuração DJANGO_SETTINGS_MODULE de um arquivo.
Ugh! Pense em como isso é meta. Se você precisar de um arquivo (como o docker env), leia-o no ambiente antes de iniciar um processo de django.
Não substitua DJANGO_SETTINGS_MODULE no código do seu projeto / aplicativo, por exemplo. com base no nome do host ou no nome do processo.
Se você tem preguiça de definir variáveis de ambiente (como para
setup.py test
), faça-o em ferramentas imediatamente antes de executar o código do projeto.Evite magia e correções de como o django lê suas configurações, pré-processe as configurações, mas não interfira posteriormente.
Nenhuma lógica complicada baseada em lógica. A configuração deve ser fixa e materializada, não computada em tempo real. Fornecer padrões de fallback é apenas lógica suficiente aqui.
Deseja realmente depurar, por que localmente você tem um conjunto correto de configurações, mas em produção em um servidor remoto, em uma das cem máquinas, algo calculado de maneira diferente? Oh! Testes unitários? Para configurações? Seriamente?
Solução
Minha estratégia consiste no excelente django-environment usado com
ini
arquivos de estilo, fornecendoos.environment
padrões para o desenvolvimento local, algunssettings/<purpose>.py
arquivos mínimos e curtos que possuem umimport settings/base.py
APÓS oos.environment
conjunto foi definido a partir de umINI
arquivo. Isso efetivamente nos dá um tipo de injeção de configurações.O truque aqui é modificar
os.environment
antes de importarsettings/base.py
.Para ver o exemplo completo, faça o repo: https://github.com/wooyek/django-settings-strategy
configurações / .env
Um padrão para o desenvolvimento local. Um arquivo secreto, para definir principalmente as variáveis de ambiente necessárias. Configure-os para valores vazios se não forem necessários no desenvolvimento local. Nós fornecemos os padrões aqui e não
settings/base.py
falharemos em nenhuma outra máquina se eles estiverem ausentes no ambiente.configurações / local.py
O que acontece aqui é carregar o ambiente de
settings/.env
e importar configurações comuns desettings/base.py
. Depois disso, podemos substituir alguns para facilitar o desenvolvimento local.settings / production.py
Para produção, não devemos esperar um arquivo de ambiente, mas é mais fácil ter um se estiver testando algo. De qualquer maneira, para que não forneça alguns padrões em linha, é
settings/base.py
possível responder de acordo.O principal ponto de interesse aqui são
DEBUG
eASSETS_DEBUG
substitui, eles serão aplicados ao pythonos.environ
SOMENTE se estiverem ausentes do ambiente e do arquivo.Esses serão os padrões de produção, não é necessário colocá-los no ambiente ou no arquivo, mas podem ser substituídos, se necessário. Arrumado!
configurações / base.py
Essas são as configurações do seu baunilha, com alguns condicionais e muitas leituras do ambiente. Quase tudo está aqui, mantendo todos os ambientes propostos consistentes e o mais semelhante possível.
As principais diferenças estão abaixo (espero que sejam auto-explicativas):
O último bit mostra o poder aqui.
ASSETS_DEBUG
possui um padrão sensato, que pode ser substituídosettings/production.py
e mesmo aquele que pode ser substituído por uma configuração de ambiente! Yay!Com efeito, temos uma hierarquia mista de importância:
fonte
Eu gerencio minhas configurações com a ajuda de django-split-settings .
É um substituto para as configurações padrão. É simples, mas configurável. E a refatoração das configurações existentes não é necessária.
Aqui está um pequeno exemplo (arquivo
example/settings/__init__.py
):É isso aí.
Atualizar
Eu escrevi um post sobre
django
as configurações de gerenciamento comdjango-split-sttings
. Dar uma olhada!fonte
uwsgi.ini
arquivo tem configurações diferentes em dev / prod .. alguma idéia de como fazê-lo escolher valores do meu arquivo de configurações?O problema com a maioria dessas soluções é que você tem suas configurações locais aplicadas antes das comuns ou depois delas.
Portanto, é impossível substituir coisas como
ao mesmo tempo.
Uma solução pode ser implementada usando arquivos de configuração no estilo "ini" com a classe ConfigParser. Ele suporta vários arquivos, interpolação lenta de cadeias, valores padrão e muitas outras vantagens. Depois que vários arquivos forem carregados, mais arquivos poderão ser carregados e seus valores substituirão os anteriores, se houver.
Você carrega um ou mais arquivos de configuração, dependendo do endereço da máquina, variáveis de ambiente e valores pares nos arquivos de configuração carregados anteriormente. Depois, basta usar os valores analisados para preencher as configurações.
Uma estratégia que usei com sucesso foi:
defaults.ini
arquivo padrãonet.ini
enet.domain.ini
, em seguidanet.domain.webserver01.ini
, cada um possivelmente substituindo os valores do anterior). Essa conta também se aplica às máquinas dos desenvolvedores, para que cada um possa configurar seu driver de banco de dados preferido, etc. para desenvolvimento localcluster.cluster_name.ini
, carregue , o que pode definir coisas como IPs de banco de dados e cacheComo um exemplo de algo que você pode conseguir com isso, você pode definir um valor de "subdomínio" por env, que é usado nas configurações padrão (as
hostname: %(subdomain).whatever.net
) para definir todos os nomes de host e cookies necessários que o django precisa para funcionar.É o DRY que eu pude obter, a maioria dos arquivos (existentes) tinha apenas 3 ou 4 configurações. Além disso, eu tinha que gerenciar a configuração do cliente, para que existisse um conjunto adicional de arquivos de configuração (com nomes de banco de dados, usuários e senhas, subdomínio designado etc.), um ou mais por cliente.
Pode-se dimensionar isso para baixo ou alto, conforme necessário, basta colocar no arquivo de configuração as chaves que você deseja configurar por ambiente e, quando houver necessidade de uma nova configuração, colocar o valor anterior na configuração padrão e substituí-lo onde necessário.
Este sistema provou ser confiável e funciona bem com o controle de versão. Ele é usado há muito tempo no gerenciamento de dois clusters de aplicativos separados (15 ou mais instâncias separadas do site django por máquina), com mais de 50 clientes, nos quais os clusters estavam mudando de tamanho e membros, dependendo do humor do administrador do sistema. .
fonte
config = ConfigParser.ConfigParser()
e ler seus arquivosconfig.read(array_of_filenames)
e obter valores usandoconfig.get(section, option)
. Então, primeiro você carrega sua configuração e, em seguida, usa-a para ler os valores das configurações.Também estou trabalhando com o Laravel e gosto da implementação lá. Tentei imitá-lo e combiná-lo com a solução proposta por T. Stone (veja acima):
Talvez algo assim possa ajudá-lo.
fonte
Lembre-se de que settings.py é um arquivo de código ativo. Supondo que você não tenha DEBUG definido na produção (que é uma prática recomendada), você pode fazer algo como:
Bastante básico, mas você poderia, em teoria, subir para qualquer nível de complexidade com base apenas no valor de DEBUG - ou em qualquer outra verificação de variável ou código que desejasse usar.
fonte
Para a maioria dos meus projetos, utilizo o seguinte padrão:
from settings_base import *
)(Para executar manage.py com configurações personalizadas arquivo que você simplesmente usar --settings opção de comando:
manage.py <command> --settings=settings_you_wish_to_use.py
)fonte
Minha solução para esse problema também é uma mistura de algumas soluções já declaradas aqui:
local_settings.py
que tem o conteúdoUSING_LOCAL = True
em dev eUSING_LOCAL = False
em prodsettings.py
faço uma importação nesse arquivo para obter aUSING_LOCAL
configuraçãoBaseei todas as minhas configurações dependentes do ambiente nessa:
Prefiro isso a ter dois arquivos settings.py separados que preciso manter, pois posso manter minhas configurações estruturadas em um único arquivo mais fácil do que tê-las espalhadas por vários arquivos. Assim, quando atualizo uma configuração, não esqueço de fazê-lo nos dois ambientes.
É claro que todo método tem suas desvantagens e este não é uma exceção. O problema aqui é que não posso sobrescrever o
local_settings.py
arquivo sempre que coloco minhas alterações em produção, o que significa que não posso copiar todos os arquivos às cegas, mas é algo com o qual posso conviver.fonte
Eu uso uma variação do que jpartogi mencionado acima, que acho um pouco mais curto:
Basicamente, em cada computador (desenvolvimento ou produção), tenho o arquivo hostname_settings.py apropriado que é carregado dinamicamente.
fonte
Há também as configurações elegantes do Django. Eu pessoalmente sou um grande fã disso. Foi construído por uma das pessoas mais ativas no Django IRC. Você usaria vários ambientes para definir as coisas.
http://django-classy-settings.readthedocs.io/en/latest/
fonte
1 - Crie uma nova pasta dentro do seu aplicativo e defina as configurações de nome para ele.
2 - Agora crie um novo
__init__.py
arquivo nele e dentro dele escreva3 - Crie três novos arquivos no nome da pasta de configurações
local.py
eproduction.py
ebase.py
.4 - No interior
base.py
, copie todo o conteúdo dasettings.py
pasta anterior e renomeie-o com algo diferente, digamosold_settings.py
.5 - Em base.py, altere o caminho BASE_DIR para apontar para o novo caminho de configuração
Caminho antigo->
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Novo caminho ->
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Dessa forma, o diretório do projeto pode ser estruturado e gerenciável entre produção e desenvolvimento local.
fonte
Para usar
settings
configurações diferentes em ambientes diferentes, crie um arquivo de configurações diferentes. E no seu script de implementação, inicie o servidor usando o--settings=<my-settings.py>
parâmetro, através do qual você pode usar diferentes configurações em diferentes ambientes.Benefícios do uso dessa abordagem :
Suas configurações serão modulares com base em cada ambiente
Você pode importar o que
master_settings.py
contém a configuração básicaenvironmnet_configuration.py
e substituir os valores que deseja alterar nesse ambiente.Se você possui uma equipe enorme, cada desenvolvedor pode ter o seu, o
local_settings.py
qual pode adicionar ao repositório de códigos sem nenhum risco de modificar a configuração do servidor. Você pode adicionar essas configurações locais.gitnore
se usar o git ou.hginore
se usar o Mercurial for Version Control (ou qualquer outro). Dessa forma, as configurações locais nem farão parte da base de código real, mantendo-a limpa.fonte
Eu dividi minhas configurações da seguinte maneira
Temos 3 ambientes
Agora, obviamente, a preparação e a produção devem ter o ambiente semelhante máximo possível. Então ficamos
prod.py
com os dois.Mas houve um caso em que eu tive que identificar o servidor em execução é um servidor de produção. @T. A resposta de Stone me ajudou a escrever o cheque da seguinte forma.
fonte
Eu o diferencio em manage.py e criei dois arquivos de configurações separados: local_settings.py e prod_settings.py.
No manage.py, verifico se o servidor é servidor local ou servidor de produção. Se for um servidor local, ele carregaria local_settings.py e, como servidor de produção, carregaria prod_settings.py. Basicamente, é assim que ficaria:
Achei mais fácil separar o arquivo de configurações em dois arquivos separados, em vez de fazer muitos ifs dentro do arquivo de configurações.
fonte
Como alternativa para manter um arquivo diferente, se você quiser: Se você estiver usando o git ou qualquer outro VCS para enviar códigos do local para o servidor, o que você pode fazer é adicionar o arquivo de configurações ao .gitignore.
Isso permitirá que você tenha conteúdo diferente nos dois lugares, sem nenhum problema. SO no servidor, você pode configurar uma versão independente do settings.py e quaisquer alterações feitas no local não refletirão no servidor e vice-versa.
Além disso, ele removerá o arquivo settings.py do github também, a grande falha, que eu já vi muitos novatos fazendo.
fonte
Criar várias versões do settings.py é um antipadrão para a metodologia do 12 Factor App . use python-desacoplamento ou django-environ .
fonte
Eu acho que a melhor solução é sugerida por @T. Stone, mas não sei por que simplesmente não use a flag DEBUG no Django. Escreva o código abaixo para o meu site:
Sempre as soluções simples são melhores que as complexas.
fonte
Eu achei as respostas aqui muito úteis. (Isso foi resolvido de forma mais definitiva? A última resposta foi um ano atrás.) Depois de considerar todas as abordagens listadas, criei uma solução que não vi listada aqui.
Meus critérios foram:
Eu pensei que ligar a máquina host fazia algum sentido, mas depois percebi que o problema real aqui é configurações diferentes para ambientes diferentes , e tive um momento aha. Coloquei esse código no final do meu arquivo settings.py:
Dessa forma, o aplicativo padroniza as configurações de produção, o que significa que você está explicitamente na "lista de permissões" de seu ambiente de desenvolvimento. É muito mais seguro esquecer de definir a variável de ambiente localmente do que se fosse o contrário e você esqueceu de definir algo na produção e permitir que algumas configurações de desenvolvimento sejam usadas.
Ao desenvolver localmente, a partir do shell ou em um .bash_profile ou em qualquer outro lugar:
(Ou, se você estiver desenvolvendo no Windows, defina através do Painel de Controle ou como é chamado hoje em dia ... O Windows sempre o tornou tão obscuro que você pode definir variáveis de ambiente.
Com essa abordagem, as configurações do desenvolvedor estão todas em um local (padrão) e simplesmente substituem as configurações de produção, quando necessário. Qualquer alteração nas configurações de desenvolvimento deve ser completamente segura para se comprometer com o controle de origem, sem impacto na produção.
fonte