¿Cuál es la forma recomendada de manejar la configuración para el desarrollo local y el servidor de producción? Algunos de ellos (como las constantes, etc.) se pueden cambiar / acceder en ambos, pero algunos de ellos (como las rutas a los archivos estáticos) deben permanecer diferentes y, por lo tanto, no se deben sobrescribir cada vez que se implementa el nuevo código.
Actualmente, estoy agregando todas las constantes a settings.py
. Pero cada vez que cambio algo constante localmente, tengo que copiarlo al servidor de producción y editar el archivo para cambios específicos de producción ... :(
Editar: parece que no hay una respuesta estándar a esta pregunta, acepté el método más popular.
python
django
deployment
akv
fuente
fuente
Respuestas:
En
settings.py
:Puede anular lo que necesita en
local_settings.py
; entonces debería mantenerse fuera de su control de versiones. Pero como mencionas copiar, supongo que no usas ninguno;)fuente
settings_local
en lugar delocal_settings
para agruparlo con lossettings.py
de las listas de carpetas por orden alfabético. Manténgasesettings_local.py
fuera del control de versiones,.gitignore
ya que las credenciales no pertenecen a Git. Imagínese abierto abasteciéndolos por accidente. Sigo en git un archivo de plantilla llamado en susettings_local.py.txt
lugar.Dos primicias de Django: las mejores prácticas para Django 1.5 sugiere usar el control de versiones para sus archivos de configuración y almacenar los archivos en un directorio separado:
El
base.py
archivo contiene valores comunes (como MEDIA_ROOT o ADMIN), mientras quelocal.py
yproduction.py
tener configuraciones específicas de sitio:En el archivo base
settings/base.py
:En el archivo de configuración de desarrollo local
settings/local.py
:En el archivo de configuración de producción de archivos
settings/production.py
:Luego, cuando ejecuta django, agrega la
--settings
opción:Los autores del libro también han puesto una plantilla de diseño de proyecto de muestra en Github.
fuente
--settings
cada vez, puede configurar elDJANGO_SETTINGS_MODULE
envvar. Esto funciona muy bien con, por ejemplo, Heroku: configúrelo globalmente en producción, luego anúlelo con dev en su archivo .env.DJANGO_SETTINGS_MODULE
env var es la mejor idea aquí, gracias Simon.BASE_DIR
configuración aos.path.dirname(os.path.realpath(os.path.dirname(__file__) + "/.."))
from django.conf import settings
que es un objeto que abstrae la interfaz y desacopla el código de la ubicación de la configuración, docs.djangoproject.com/en/dev/topics/settings/…En lugar de
settings.py
usar este diseño:common.py
es donde vive la mayor parte de su configuración.prod.py
importa todo de común, y anula lo que sea necesario para anular:Del mismo modo,
dev.py
importa todocommon.py
y anula todo lo que necesita anular.Finalmente,
__init__.py
es donde usted decide qué configuraciones cargar, y también es donde almacena los secretos (por lo tanto, este archivo no debe ser versionado):Lo que me gusta de esta solución es:
common.py
.prod.py
, las cosas específicas del desarrollador entrandev.py
. Es sencillo.common.py
adentroprod.py
odev.py
, y puede anular cualquier cosa en__init__.py
.fuente
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "foobar.settings")
foobar es una carpeta con un__init__.py
archivo y la configuración es una carpeta con un__init__.py
archivo que contiene mis secretos e importa dev.py, que luego importa common.py. EDITAR No importa, no tenía un módulo instalado que fuera necesario. ¡Culpa mía! ¡Esto funciona muy bien!Utilizo una versión ligeramente modificada del estilo de configuración "if DEBUG" que publicó Harper Shelby. Obviamente, dependiendo del entorno (win / linux / etc.), es posible que el código deba modificarse un poco.
En el pasado estaba usando "if DEBUG" pero descubrí que ocasionalmente necesitaba hacer pruebas con DEUBG configurado en False. Lo que realmente quería distinguir si el entorno era producción o desarrollo, lo que me dio la libertad de elegir el nivel DEPURAR.
Todavía consideraría esta forma de configuración un trabajo en progreso. No he visto ninguna forma de manejar la configuración de Django que cubriera todas las bases y al mismo tiempo no fuera una molestia total de configuración (no estoy caído con los métodos de archivos de configuración 5x).
fuente
os.environ['COMPUTERNAME']
desafortunadamente no funciona en PythonAnywhere. Obtienes un KeyError.Yo uso settings_local.py y settings_production.py. Después de probar varias opciones, descubrí que es fácil perder el tiempo con soluciones complejas cuando simplemente tener dos archivos de configuración se siente fácil y rápido.
Cuando usa mod_python / mod_wsgi para su proyecto Django, debe apuntarlo a su archivo de configuración. Si lo señala a app / settings_local.py en su servidor local y app / settings_production.py en su servidor de producción, entonces la vida se vuelve más fácil. Simplemente edite el archivo de configuración apropiado y reinicie el servidor (el servidor de desarrollo de Django se reiniciará automáticamente).
fuente
python manage.py runserver
), qué archivo de configuración usar?TL; DR: El truco es modificar
os.environment
antes de importarsettings/base.py
en cualquierasettings/<purpose>.py
, esto simplificará enormemente las cosas.Solo pensar en todos estos archivos entrelazados me da dolor de cabeza. Combinar, importar (a veces condicionalmente), anular, parchear lo que ya estaba configurado en caso de que la
DEBUG
configuración cambie más adelante. ¡Qué pesadilla!A través de los años pasé por diferentes soluciones. Todos funcionan de alguna manera , pero son muy dolorosos de manejar. WTF! ¿Realmente necesitamos toda esa molestia? Comenzamos con solo un
settings.py
archivo. ¡Ahora necesitamos una documentación solo para combinar correctamente todo esto en un orden correcto!Espero finalmente alcanzar el (mi) punto dulce con la solución a continuación.
Recapitulemos los objetivos (algunos comunes, algunos míos)
Mantenga los secretos en secreto: ¡no los guarde en un repositorio!
Establecer / leer claves y secretos a través de la configuración del entorno, estilo de 12 factores .
Tener valores predeterminados razonables. Idealmente para el desarrollo local, no necesita nada más aparte de los valores predeterminados.
… Pero trate de mantener segura la producción predeterminada. Es mejor omitir una anulación de configuración localmente, que tener que recordar ajustar la configuración predeterminada de forma segura para la producción.
Tener la capacidad de encender
DEBUG
/ apagar de una manera que pueda tener un efecto en otras configuraciones (por ejemplo, usando JavaScript comprimido o no).El cambio entre configuraciones de propósito, como local / testing / puesta en escena / producción, debe basarse solo en
DJANGO_SETTINGS_MODULE
nada más.... pero permitir necesidad de parametrización a través de la configuración del entorno como
DATABASE_URL
.… También les permite usar configuraciones de propósito diferente y ejecutarlas localmente lado a lado, por ejemplo. configuración de producción en la máquina del desarrollador local, para acceder a la base de datos de producción o las hojas de estilo comprimidas de prueba de humo.
Falla si una variable de entorno no se establece explícitamente (lo que requiere un valor vacío como mínimo), especialmente en producción, por ejemplo.
EMAIL_HOST_PASSWORD
.Responda al
DJANGO_SETTINGS_MODULE
conjunto predeterminado en manage.py durante el proyecto de inicio django-adminMantenga los condicionales al mínimo, si la condición es el tipo de entorno intencionado (por ejemplo, para el archivo de registro del conjunto de producción y su rotación), anule la configuración en el archivo de configuración intencionado asociado.
No
No permita que django lea la configuración DJANGO_SETTINGS_MODULE de un archivo.
Ugh! Piensa en lo meta que es esto. Si necesita tener un archivo (como docker env), léalo en el entorno antes de iniciar un proceso de django.
No anule DJANGO_SETTINGS_MODULE en su proyecto / código de aplicación, por ejemplo. basado en el nombre de host o el nombre del proceso.
Si tiene pereza para establecer una variable de entorno (como for
setup.py test
), hágalo en herramientas justo antes de ejecutar el código del proyecto.Evite la magia y los parches de cómo django lee su configuración, preprocese la configuración pero no interfiera después.
Sin complicaciones lógicas basadas en tonterías. La configuración debe ser fija y materializada, no calculada sobre la marcha. Proporcionar valores predeterminados alternativos es suficiente lógica aquí.
¿Realmente desea depurar? ¿Por qué localmente tiene la configuración correcta pero en producción en un servidor remoto, en una de cientos de máquinas, algo calculado de manera diferente? Oh! Pruebas unitarias? Para la configuración? ¿Seriamente?
Solución
Mi estrategia consiste en excelente django-Environ se utiliza con
ini
archivos de estilo, que proporcionaos.environment
valores por defecto para el desarrollo local, algunos mínimos y cortassettings/<purpose>.py
archivos que tienen unaimport settings/base.py
DESPUÉS elos.environment
se estableció a partir de unINI
archivo. Esto efectivamente nos da un tipo de ajustes de inyección.El truco aquí es modificar
os.environment
antes de importarsettings/base.py
.Para ver el ejemplo completo, vaya al repositorio: https://github.com/wooyek/django-settings-strategy
settings / .env
A por defecto para el desarrollo local. Un archivo secreto, para establecer principalmente las variables de entorno requeridas. Póngalos en valores vacíos si no son necesarios en el desarrollo local. Proporcionamos valores predeterminados aquí y no
settings/base.py
fallar en ninguna otra máquina si faltan en el entorno.settings / local.py
Lo que sucede aquí es cargar el entorno desde
settings/.env
y luego importar configuraciones comunes desdesettings/base.py
. Después de eso, podemos anular algunos para facilitar el desarrollo local.settings / production.py
Para la producción no deberíamos esperar un archivo de entorno, pero es más fácil tener uno si estamos probando algo. Pero de todos modos, no proporcionamos algunos valores predeterminados en línea, por lo que
settings/base.py
podemos responder en consecuencia.El principal punto de interés aquí son
DEBUG
yASSETS_DEBUG
reemplaza, se aplicarán a la pitónos.environ
SOLAMENTE si faltan del entorno y el archivo.Estos serán nuestros valores predeterminados de producción, no es necesario ponerlos en el entorno o archivo, pero pueden anularse si es necesario. ¡Ordenado!
settings / base.py
Estas son sus configuraciones de django en su mayoría de vainilla, con algunos condicionales y muchas lecturas del entorno. Casi todo está aquí, manteniendo todos los entornos propuestos consistentes y lo más similares posible.
Las principales diferencias están a continuación (espero que se expliquen por sí mismas):
El último bit muestra el poder aquí.
ASSETS_DEBUG
tiene un valor predeterminado sensible, que puede ser anuladosettings/production.py
e incluso eso puede ser anulado por una configuración de entorno. ¡Hurra!En efecto, tenemos una jerarquía mixta de importancia:
fuente
Administro mis configuraciones con la ayuda de django-split-settings .
Es un reemplazo directo para la configuración predeterminada. Es simple, pero configurable. Y no se requiere refactorizar sus configuraciones existentes.
Aquí hay un pequeño ejemplo (archivo
example/settings/__init__.py
):Eso es.
Actualizar
Escribí una publicación de blog sobre cómo administrar
django
la configuración dedjango-split-sttings
. ¡Echar un vistazo!fuente
uwsgi.ini
archivo tiene diferentes configuraciones en dev / prod ... ¿alguna idea de cómo hacer que elija valores de mi archivo de configuración?El problema con la mayoría de estas soluciones es que tiene su configuración local aplicada antes que las comunes, o después de ellas.
Entonces es imposible anular cosas como
al mismo tiempo.
Se puede implementar una solución utilizando archivos de configuración de estilo "ini" con la clase ConfigParser. Admite múltiples archivos, interpolación de cadenas diferidas, valores predeterminados y muchas otras ventajas. Una vez que se han cargado varios archivos, se pueden cargar más archivos y sus valores anularán los anteriores, si los hay.
Carga uno o más archivos de configuración, dependiendo de la dirección de la máquina, las variables de entorno e incluso los valores en los archivos de configuración cargados previamente. Luego, solo usa los valores analizados para completar la configuración.
Una estrategia que he usado con éxito ha sido:
defaults.ini
archivo predeterminadonet.ini
, a continuaciónnet.domain.ini
, a continuaciónnet.domain.webserver01.ini
, cada uno de ellos posiblemente valores de la anterior anulando). Esta cuenta también es para máquinas de desarrolladores, por lo que cada uno podría configurar su controlador de base de datos preferido, etc. para el desarrollo localcluster.cluster_name.ini
, cargue , lo que puede definir cosas como IP de base de datos y cachéComo ejemplo de algo que puede lograr con esto, puede definir un valor de "subdominio" por env, que luego se utiliza en la configuración predeterminada (as
hostname: %(subdomain).whatever.net
) para definir todos los nombres de host y cookies necesarios que django necesita para funcionar.Esto es lo más SECO que pude obtener, la mayoría de los archivos (existentes) tenían solo 3 o 4 configuraciones. Además de esto, tuve que administrar la configuración del cliente, por lo que existía un conjunto adicional de archivos de configuración (con cosas como nombres de bases de datos, usuarios y contraseñas, subdominios asignados, etc.), uno o más por cliente.
Uno puede escalar esto tan bajo o tan alto como sea necesario, solo tiene que poner en el archivo de configuración las claves que desea configurar por entorno, y una vez que haya necesidad de una nueva configuración, coloque el valor anterior en la configuración predeterminada y lo anule donde sea necesario.
Este sistema ha demostrado ser confiable y funciona bien con el control de versiones. Se ha utilizado durante mucho tiempo administrando dos grupos de aplicaciones separados (15 o más instancias separadas del sitio django por máquina), con más de 50 clientes, donde los grupos estaban cambiando de tamaño y miembros dependiendo del estado de ánimo del administrador del sistema. .
fuente
config = ConfigParser.ConfigParser()
luego leer sus archivosconfig.read(array_of_filenames)
y obtener valores utilizandoconfig.get(section, option)
. Entonces, primero carga su configuración, y luego la usa para leer valores para la configuración.También estoy trabajando con Laravel y me gusta la implementación allí. Traté de imitarlo y combinarlo con la solución propuesta por T. Stone (ver arriba):
Tal vez algo como esto te ayudaría.
fuente
Recuerde que settings.py es un archivo de código en vivo. Suponiendo que no tiene DEBUG configurado en producción (que es una práctica recomendada), puede hacer algo como:
Bastante básico, pero podría, en teoría, subir a cualquier nivel de complejidad basado solo en el valor de DEBUG, o cualquier otra variable o verificación de código que desee usar.
fuente
Para la mayoría de mis proyectos utilizo el siguiente patrón:
from settings_base import *
)(Para ejecutar manage.py con una configuración personalizada de archivos sólo tiene que utilizar --settings opción de comando:
manage.py <command> --settings=settings_you_wish_to_use.py
)fuente
Mi solución a ese problema también es una mezcla de algunas soluciones ya mencionadas aquí:
local_settings.py
que tiene el contenidoUSING_LOCAL = True
en dev yUSING_LOCAL = False
en prodsettings.py
hago una importación en ese archivo para obtener laUSING_LOCAL
configuraciónLuego baso todas mis configuraciones dependientes del entorno en esa:
Prefiero esto a tener dos archivos settings.py separados que necesito mantener, ya que puedo mantener mi configuración estructurada en un solo archivo más fácilmente que distribuirlos en varios archivos. De esta manera, cuando actualizo una configuración, no me olvido de hacerlo para ambos entornos.
Por supuesto, cada método tiene sus desventajas y este no es una excepción. El problema aquí es que no puedo sobrescribir el
local_settings.py
archivo cada vez que empujo mis cambios a producción, lo que significa que no puedo copiar todos los archivos a ciegas, pero eso es algo con lo que puedo vivir.fuente
Utilizo una variación de lo que jpartogi mencionó anteriormente, que encuentro un poco más corto:
Básicamente, en cada computadora (desarrollo o producción) tengo el archivo hostname_settings.py apropiado que se carga dinámicamente.
fuente
También hay configuraciones con clase de Django. Personalmente soy un gran admirador. Está construido por una de las personas más activas en el IRC de Django. Usaría variables de entorno para configurar las cosas.
http://django-classy-settings.readthedocs.io/en/latest/
fuente
1 - Crea una nueva carpeta dentro de tu aplicación y ponle nombre.
2 - Ahora crea un nuevo
__init__.py
archivo y escribe dentro3 - Cree tres archivos nuevos en el nombre de la carpeta de configuración
local.py
yproduction.py
ybase.py
.4 - Dentro
base.py
, copia todo el contenido de lasettings.py
carpeta anterior y renómbralo con algo diferente, digamosold_settings.py
.5 - En base.py cambia tu ruta BASE_DIR para que apunte a tu nueva ruta de configuración
Camino viejo->
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
Nuevo camino ->
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
De esta manera, el directorio del proyecto puede estructurarse y ser manejable entre la producción y el desarrollo local.
fuente
Para utilizar una
settings
configuración diferente en un entorno diferente, cree un archivo de configuración diferente. Y en su secuencia de comandos de implementación, inicie el servidor usando el--settings=<my-settings.py>
parámetro, a través del cual puede usar diferentes configuraciones en diferentes entornos.Beneficios de usar este enfoque :
Su configuración será modular en función de cada entorno.
Puede importar el que
master_settings.py
contiene la configuración base en elenvironmnet_configuration.py
y anular los valores que desea cambiar en ese entorno.Si tiene un equipo enorme, cada desarrollador puede tener el suyo propio
local_settings.py
que puede agregar al repositorio de código sin riesgo de modificar la configuración del servidor. Puede agregar estas configuraciones locales.gitnore
si usa git o.hginore
si usa Mercurial para Control de versiones (o cualquier otro). De esa forma, la configuración local ni siquiera formará parte de la base de código real que la mantiene limpia.fuente
Tenía mi configuración dividida de la siguiente manera
Tenemos 3 ambientes
Ahora, obviamente, la puesta en escena y la producción deben tener el máximo entorno similar posible. Así que nos quedamos
prod.py
para los dos.Pero hubo un caso en el que tuve que identificar que el servidor en ejecución es un servidor de producción. @T. La respuesta de Stone me ayudó a escribir el cheque de la siguiente manera.
fuente
Lo distingo en manage.py y creé dos archivos de configuración separados: local_settings.py y prod_settings.py.
En manage.py verifico si el servidor es un servidor local o un servidor de producción. Si es un servidor local, cargaría local_settings.py y es un servidor de producción, cargaría prod_settings.py. Básicamente así es como se vería:
Descubrí que es más fácil separar el archivo de configuración en dos archivos separados en lugar de hacer muchos ifs dentro del archivo de configuración.
fuente
Como alternativa para mantener un archivo diferente si lo desea: si está utilizando git o cualquier otro VCS para insertar códigos de local a servidor, lo que puede hacer es agregar el archivo de configuración a .gitignore.
Esto le permitirá tener contenido diferente en ambos lugares sin ningún problema. SO en el servidor puede configurar una versión independiente de settings.py y cualquier cambio realizado en el local no se reflejará en el servidor y viceversa.
Además, eliminará el archivo settings.py de github también, la gran falla, que he visto hacer a muchos novatos.
fuente
Hacer múltiples versiones de settings.py es un anti patrón para la metodología 12 Factor App . use python-decouple o django-environment en su lugar.
fuente
Creo que @T sugiere la mejor solución. Stone, pero no sé por qué no usar la bandera DEBUG en Django. Escribo el siguiente código para mi sitio web:
Siempre las soluciones simples son mejores que las complejas.
fuente
Encontré las respuestas aquí muy útiles. (¿Se resolvió esto de manera más definitiva? La última respuesta fue hace un año). Después de considerar todos los enfoques enumerados, se me ocurrió una solución que no vi enumerada aquí.
Mis criterios fueron:
Pensé que encender la máquina host tenía sentido, pero luego pensé que el problema real aquí es la configuración diferente para diferentes entornos , y tuve un momento aha. Pongo este código al final de mi archivo settings.py:
De esta manera, la aplicación adopta de manera predeterminada la configuración de producción, lo que significa que está "listando" explícitamente su entorno de desarrollo. Es mucho más seguro olvidarse de establecer la variable de entorno localmente que si fuera al revés y olvidarse de establecer algo en producción y dejar que se usen algunas configuraciones de desarrollo.
Al desarrollar localmente, ya sea desde el shell o en un .bash_profile o donde sea:
(O si está desarrollando en Windows, configúrelo a través del Panel de control o como se llame en estos días ... Windows siempre lo hizo tan oscuro que podía establecer variables de entorno).
Con este enfoque, las configuraciones de desarrollo están todas en un lugar (estándar) y simplemente anulan las de producción cuando es necesario. Cualquier cambio en la configuración de desarrollo debe ser completamente seguro para comprometerse con el control de origen sin impacto en la producción.
fuente