로컬 개발 및 프로덕션 서버의 설정을 처리하는 데 권장되는 방법은 무엇입니까? 상수 등의 일부는 변경하거나 액세스 할 수 있지만 정적 파일 경로와 같은 일부는 다르게 유지해야하므로 새 코드가 배포 될 때마다 덮어 쓰지 않아야합니다.
현재 모든 상수를 추가하고 있습니다. settings.py
있습니다. 그러나 로컬에서 일부 상수를 변경할 때마다 프로덕션 서버에 복사하고 프로덕션 특정 변경 사항을 위해 파일을 편집해야합니다 … 🙁
편집 :이 질문에 대한 표준 답변이없는 것 같습니다. 가장 인기있는 방법을 수락했습니다.
답변
에서 settings.py
:
try:
from local_settings import *
except ImportError as e:
pass
필요한 것을 무시할 수 있습니다 local_settings.py
. 그런 다음 버전 관리를 벗어나야합니다. 그러나 복사에 대해 언급 했으므로 아무것도 사용하지 않는 것 같습니다.)
답변
Django의 두 가지 특종 : Django 1.5 모범 사례에서는 설정 파일에 버전 제어를 사용하고 파일을 별도의 디렉토리에 저장하는 것이 좋습니다.
project/
app1/
app2/
project/
__init__.py
settings/
__init__.py
base.py
local.py
production.py
manage.py
base.py
동안 파일 (예 : MEDIA_ROOT 또는 ADMIN 등) 일반적인 설정을 포함 local.py
하고 production.py
사이트 별 설정이 있습니다 :
기본 파일에서 settings/base.py
:
INSTALLED_APPS = (
# common apps...
)
로컬 개발 설정 파일에서 settings/local.py
:
from project.settings.base import *
DEBUG = True
INSTALLED_APPS += (
'debug_toolbar', # and other apps for local development
)
파일 제작 설정 파일에서 settings/production.py
:
from project.settings.base import *
DEBUG = False
INSTALLED_APPS += (
# other apps for production site
)
그런 다음 django를 실행할 때 --settings
옵션 을 추가하십시오 .
# Running django for local development
$ ./manage.py runserver 0:8000 --settings=project.settings.local
# Running django shell on the production site
$ ./manage.py shell --settings=project.settings.production
이 책의 저자 는 샘플 프로젝트 레이아웃 템플릿도 작성했습니다. Github에 을 .
답변
대신 settings.py
이 레이아웃을 사용하십시오.
.
└── settings/
├── __init__.py <= not versioned
├── common.py
├── dev.py
└── prod.py
common.py
대부분의 구성이있는 곳입니다.
prod.py
공통의 모든 것을 가져오고 재정의 해야하는 모든 것을 재정의합니다.
from __future__ import absolute_import # optional, but I like it
from .common import *
# Production overrides
DEBUG = False
#...
마찬가지로 dev.py
모든 항목을 가져 common.py
와서 재정의해야하는 모든 항목을 재정의합니다.
마지막으로 __init__.py
로드 할 설정을 결정하는 위치와 비밀을 저장하는 위치도 있습니다 (따라서이 파일의 버전을 지정하지 않아야 함).
from __future__ import absolute_import
from .prod import * # or .dev if you want dev
##### DJANGO SECRETS
SECRET_KEY = '(3gd6shenud@&57...'
DATABASES['default']['PASSWORD'] = 'f9kGH...'
##### OTHER SECRETS
AWS_SECRET_ACCESS_KEY = "h50fH..."
이 솔루션에서 내가 좋아하는 것은 :
- 비밀을 제외한 모든 것이 버전 관리 시스템에 있습니다.
- 대부분의 구성은 한 곳에
common.py
있습니다. - 생산물에 특정한 것들이 들어가고
prod.py
, 실체에 특정한 것들이 들어갑니다dev.py
. 간단 해. - 당신은에서 물건을 무시할 수 있습니다
common.py
에서prod.py
또는dev.py
, 당신은 아무것도를 대체 할 수 있습니다__init__.py
. - 간단한 파이썬입니다. 다시 가져 오기 해킹이 없습니다.
답변
Harper Shelby가 게시 한 “if DEBUG”스타일 설정의 약간 수정 된 버전을 사용합니다. 분명히 환경 (win / linux / etc.)에 따라 코드를 약간 조정해야 할 수도 있습니다.
과거에는 “DEBUG 인 경우”를 사용했지만 DEUBG를 False로 설정하여 테스트해야하는 경우가 있음을 알게되었습니다. 환경이 생산 또는 개발인지 구분하기를 원했기 때문에 DEBUG 수준을 자유롭게 선택할 수있었습니다.
PRODUCTION_SERVERS = ['WEBSERVER1','WEBSERVER2',]
if os.environ['COMPUTERNAME'] in PRODUCTION_SERVERS:
PRODUCTION = True
else:
PRODUCTION = False
DEBUG = not PRODUCTION
TEMPLATE_DEBUG = DEBUG
# ...
if PRODUCTION:
DATABASE_HOST = '192.168.1.1'
else:
DATABASE_HOST = 'localhost'
나는 아직도 이런 방법으로 진행중인 작업을 고려하고있다. 모든 기반을 다루는 Django 설정을 처리하는 한 가지 방법을 보지 못했지만 동시에 설정하는 데 번거 로움이 없었습니다 (5x 설정 파일 방법을 사용하지 않았습니다).
답변
settings_local.py와 settings_production.py를 사용합니다. 몇 가지 옵션을 시도한 후 두 개의 설정 파일을 갖는 것이 쉽고 빠르면 복잡한 솔루션으로 시간을 낭비하는 것이 쉽다는 것을 알았습니다.
Django 프로젝트에 mod_python / mod_wsgi를 사용할 때는 설정 파일을 가리켜 야합니다. 로컬 서버의 app / settings_local.py 및 프로덕션 서버의 app / settings_production.py를 가리키면 인생이 쉬워집니다. 적절한 설정 파일을 편집하고 서버를 다시 시작하십시오 (Django 개발 서버가 자동으로 다시 시작됨).
답변
TL; DR : 트릭을 수정하는 것입니다 os.environment
당신이 가져 오기 전에 settings/base.py
어떤에서 settings/<purpose>.py
이 크게 일을 단순화합니다.
이 모든 얽힌 파일에 대해 생각하면 두통이 생깁니다. DEBUG
나중에 설정이 변경된 경우에 이미 설정 한 내용의 조합, 가져 오기 (조건에 따라), 재정의, 패치 악몽이야!
몇 년 동안 나는 모든 다른 솔루션을 겪었습니다. 그들은 모두 다소 효과가 있지만 관리하기가 너무 고통 스럽습니다. WTF! 번거 로움이 정말로 필요한가? 하나의 settings.py
파일로 시작했습니다 . 이제이 모든 것을 올바른 순서로 올바르게 결합하기위한 문서가 필요합니다!
나는 마침내 아래 해결책으로 (내) 달콤한 자리에 도달하기를 바랍니다.
목표를 되짚어 봅시다 (일부 공통, 일부 내)
-
비밀을 비밀로 유지하십시오. 리포지토리에 저장하지 마십시오!
-
12 요인 스타일 환경 설정을 통해 키와 비밀을 설정 / 읽습니다 .
-
적절한 대체 기본값이 있습니다. 이상적으로는 로컬 개발을 위해 기본값 이외의 다른 것이 필요하지 않습니다.
-
… 기본 생산을 안전하게 유지하십시오. 프로덕션 환경에서 안전한 기본 설정을 기억해야하는 것보다 로컬에서 설정 재정의를 놓치는 것이 좋습니다.
-
전환 할 수있는 기능이
DEBUG
다른 설정에 영향을 줄 수있는 방법에 온 / 오프 (예. 압축 된 자바 스크립트를 사용하여 여부를). -
로컬 / 테스트 / 스테이징 / 프로덕션과 같은 목적 설정 간 전환은을 기반으로해야합니다
DJANGO_SETTINGS_MODULE
. -
…와 같은 환경 설정을 통해 추가 매개 변수화를 허용
DATABASE_URL
합니다. -
… 또한 서로 다른 목적 설정을 사용하고 로컬로 나란히 실행할 수 있습니다 (예 : 로컬 개발자 시스템의 프로덕션 설정, 프로덕션 데이터베이스에 액세스하거나 연기 테스트 압축 스타일 시트.
-
특히 프로덕션 환경에서 환경 변수가 명시 적으로 설정되지 않으면 (최소한 빈 값이 필요함) 실패합니다.
EMAIL_HOST_PASSWORD
. -
django-admin startproject
DJANGO_SETTINGS_MODULE
중 manage.py의 기본 설정에 응답 -
조건이있는 경우, 최소한으로 조건문을 유지 목적의 환경 유형 (예를 들면. 생산 세트의 로그 파일과의 회전), 관련 목적의 설정 파일에서 재정의 설정.
하지마
-
django가 파일에서 DJANGO_SETTINGS_MODULE 설정을 읽지 못하게하십시오.
어! 이것이 메타인지 생각하십시오. docker env와 같은 파일이 필요한 경우 django 프로세스를 시작하기 전에 환경에서 파일을 읽으십시오. -
프로젝트 / 앱 코드에서 DJANGO_SETTINGS_MODULE을 재정의하지 마십시오 (예 : 호스트 이름 또는 프로세스 이름을 기반으로합니다.
환경 변수를 설정하는 것이 게으른 경우 (예 :와 같이setup.py test
) 프로젝트 코드를 실행하기 직전에 툴링에서 환경 변수를 설정 하십시오. -
django가 설정을 읽는 방법의 마법과 패치를 피하고 설정을 사전 처리하지만 나중에 방해하지는 마십시오.
-
복잡한 논리 기반 넌센스가 없습니다. 구성은 즉시 계산되지 않고 수정되고 구체화되어야합니다. 대체 기본값을 제공하는 것만으로도 충분한 논리입니다.
로컬에서 올바른 설정 세트를 사용하지만 원격 서버, 수백 대의 머신 중 하나에서 다르게 계산 된 이유는 무엇입니까? 오! 단위 테스트? 설정? 진심이야?
해결책
내 전략은 우수한 구성 장고-와 환경 에 사용 ini
스타일 파일, 제공 os.environment
지역 개발에 대한 기본값을, 최소한의 짧은 settings/<purpose>.py
을 가진 파일
import settings/base.py
후에 이 os.environment
에서 설정 INI
파일. 이것은 효과적으로 일종의 설정 주입을 제공합니다.
여기서 트릭은 os.environment
가져 오기 전에 수정하는 것 settings/base.py
입니다.
전체 예제를 보려면 repo를 수행하십시오. https://github.com/wooyek/django-settings-strategy
.
│ manage.py
├───data
└───website
├───settings
│ │ __init__.py <-- imports local for compatibility
│ │ base.py <-- almost all the settings, reads from proces environment
│ │ local.py <-- a few modifications for local development
│ │ production.py <-- ideally is empty and everything is in base
│ │ testing.py <-- mimics production with a reasonable exeptions
│ │ .env <-- for local use, not kept in repo
│ __init__.py
│ urls.py
│ wsgi.py
설정 /.env
로컬 개발의 기본값입니다. 주로 필요한 환경 변수를 설정하는 비밀 파일. 로컬 개발에 필요하지 않은 경우 빈 값으로 설정하십시오. 우리는 여기서 기본값을 제공 settings/base.py
하며 환경에서 누락 된 경우 다른 시스템에서 실패 하지 않습니다 .
settings / local.py
여기서 발생하는 일은에서 환경을로드 settings/.env
한 다음에서 공통 설정을 가져 오는 것입니다 settings/base.py
. 그 후 지역 개발을 용이하게하기 위해 몇 가지를 재정의 할 수 있습니다.
import logging
import environ
logging.debug("Settings loading: %s" % __file__)
# This will read missing environment variables from a file
# We wan to do this before loading a base settings as they may depend on environment
environ.Env.read_env(DEBUG='True')
from .base import *
ALLOWED_HOSTS += [
'127.0.0.1',
'localhost',
'.example.com',
'vagrant',
]
# https://docs.djangoproject.com/en/1.6/topics/email/#console-backend
EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
# EMAIL_BACKEND = 'django.core.mail.backends.dummy.EmailBackend'
LOGGING['handlers']['mail_admins']['email_backend'] = 'django.core.mail.backends.dummy.EmailBackend'
# Sync task testing
# http://docs.celeryproject.org/en/2.5/configuration.html?highlight=celery_always_eager#celery-always-eager
CELERY_ALWAYS_EAGER = True
CELERY_EAGER_PROPAGATES_EXCEPTIONS = True
settings / production.py
프로덕션 환경에서는 환경 파일을 기 대해서는 안되지만 무언가를 테스트하는 경우 환경 파일이 더 쉽습니다. 그러나 어쨌든 최소한의 인라인 설정을 제공하지 않으므로 settings/base.py
그에 따라 응답 할 수 있습니다.
environ.Env.read_env(Path(__file__) / "production.env", DEBUG='False', ASSETS_DEBUG='False')
from .base import *
관심의 주요 포인트는 여기에 있습니다 DEBUG
및 ASSETS_DEBUG
재 지정, 그들은 파이썬에 적용됩니다 os.environ
들이 환경과 파일에서 누락 된 경우에만.
이것들은 프로덕션 기본값이 될 것이며, 환경이나 파일에 넣을 필요는 없지만 필요한 경우 재정의 할 수 있습니다. 산뜻한!
settings / base.py
이것들은 대부분 바닐라 장고 설정이며, 몇 가지 조건부와 환경에서 많은 것을 읽습니다. 거의 모든 것이 여기에 있으며, 모든 목적 환경을 일관되고 유사하게 유지합니다.
주요 차이점은 다음과 같습니다 (자기 설명이 필요합니다).
import environ
# https://github.com/joke2k/django-environ
env = environ.Env()
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
# Where BASE_DIR is a django source root, ROOT_DIR is a whole project root
# It may differ BASE_DIR for eg. when your django project code is in `src` folder
# This may help to separate python modules and *django apps* from other stuff
# like documentation, fixtures, docker settings
ROOT_DIR = BASE_DIR
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = env('SECRET_KEY')
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = env('DEBUG', default=False)
INTERNAL_IPS = [
'127.0.0.1',
]
ALLOWED_HOSTS = []
if 'ALLOWED_HOSTS' in os.environ:
hosts = os.environ['ALLOWED_HOSTS'].split(" ")
BASE_URL = "https://" + hosts[0]
for host in hosts:
host = host.strip()
if host:
ALLOWED_HOSTS.append(host)
SECURE_SSL_REDIRECT = env.bool('SECURE_SSL_REDIRECT', default=False)
# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
if "DATABASE_URL" in os.environ: # pragma: no cover
# Enable database config through environment
DATABASES = {
# Raises ImproperlyConfigured exception if DATABASE_URL not in os.environ
'default': env.db(),
}
# Make sure we use have all settings we need
# DATABASES['default']['ENGINE'] = 'django.contrib.gis.db.backends.postgis'
DATABASES['default']['TEST'] = {'NAME': os.environ.get("DATABASE_TEST_NAME", None)}
DATABASES['default']['OPTIONS'] = {
'options': '-c search_path=gis,public,pg_catalog',
'sslmode': 'require',
}
else:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
# 'ENGINE': 'django.contrib.gis.db.backends.spatialite',
'NAME': os.path.join(ROOT_DIR, 'data', 'db.dev.sqlite3'),
'TEST': {
'NAME': os.path.join(ROOT_DIR, 'data', 'db.test.sqlite3'),
}
}
}
STATIC_ROOT = os.path.join(ROOT_DIR, 'static')
# django-assets
# http://django-assets.readthedocs.org/en/latest/settings.html
ASSETS_LOAD_PATH = STATIC_ROOT
ASSETS_ROOT = os.path.join(ROOT_DIR, 'assets', "compressed")
ASSETS_DEBUG = env('ASSETS_DEBUG', default=DEBUG) # Disable when testing compressed file in DEBUG mode
if ASSETS_DEBUG:
ASSETS_URL = STATIC_URL
ASSETS_MANIFEST = "json:{}".format(os.path.join(ASSETS_ROOT, "manifest.json"))
else:
ASSETS_URL = STATIC_URL + "assets/compressed/"
ASSETS_MANIFEST = "json:{}".format(os.path.join(STATIC_ROOT, 'assets', "compressed", "manifest.json"))
ASSETS_AUTO_BUILD = ASSETS_DEBUG
ASSETS_MODULES = ('website.assets',)
마지막 비트는 여기에 힘을 보여줍니다. ASSETS_DEBUG
합리적인 기본값을 가지고 있으며 settings/production.py
, 환경 설정에 의해 재정의 될 수 있고 심지어 재정의 될 수도 있습니다! 예이!
사실상 우리는 중요한 계층 구조를 가지고 있습니다 :
- settings / .py-목적에 따라 기본값을 설정하고 비밀을 저장하지 않습니다
- settings / base.py-대부분 환경에 의해 제어됩니다
- 공정 환경 설정-12 단계 베이비!
- settings / .env-쉬운 시작을위한 로컬 기본값
답변
django-split-settings 의 도움으로 구성을 관리합니다 .
기본 설정을 대체합니다. 간단하지만 구성 할 수 있습니다. 기존 설정을 리팩토링 할 필요가 없습니다.
다음은 작은 예입니다 (file example/settings/__init__.py
).
from split_settings.tools import optional, include
import os
if os.environ['DJANGO_SETTINGS_MODULE'] == 'example.settings':
include(
'components/default.py',
'components/database.py',
# This file may be missing:
optional('local_settings.py'),
scope=globals()
)
그게 다야.
최신 정보
의 설정 관리에 대한 블로그 게시물을 작성했습니다 . 보세요!django
django-split-sttings