提问人:mightycode Newton 提问时间:11/16/2023 最后编辑:mightycode Newton 更新时间:11/17/2023 访问量:78
如何使用docker compose拆分开发环境文件和生产环境文件?
How to split development env file and production env file with docker compose?
问:
我已经用nginxdockerized了django应用程序。我有两个环境文件:一个用于开发,一个用于生产。env 文件的内容是数据库的凭据。
但显然,不会执行生产环境文件中的凭据。
我的文件夹结构如下所示:
root
- welzijn
-admin
因此,当我将名为 .env 和 prod.env 的 env 文件放在根文件夹中时,它不起作用。
但是当我将带有生产凭据的 .env 文件放在 welzijn 文件夹中时,它就可以工作了。即使我将文件 prod.env 放在文件夹 welzijn 中,它也不起作用
我真的为此挠头。
所以这是 dockerfile:
# pull official base image
FROM python:3.9-alpine3.13
# ENV PATH="/scripts:${PATH}"
# set work directory
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
COPY ./requirements.txt /tmp/requirements.txt
COPY ./scripts /scripts
WORKDIR /usr/src/app
EXPOSE 8000
# install psycopg2 dependencies
ARG DEV=false
RUN python -m venv /py && \
/py/bin/pip install --upgrade pip && \
apk add --update --no-cache postgresql-client jpeg-dev && \
apk add --update --no-cache --virtual .tmp-build-deps \
build-base postgresql-dev musl-dev zlib zlib-dev linux-headers && \
/py/bin/pip install -r /tmp/requirements.txt && \
apk del .tmp-build-deps && \
adduser \
--disabled-password \
--no-create-home \
django-user
ENV PATH="/scripts:/py/bin:$PATH"
USER django-user
COPY . .
# run entrypoint.sh
CMD ["run.sh"]
和 docker-compose-deploy.yml 文件:
version: "3.9"
services:
web:
image: crdierenwelzijn.azurecr.io/web1
build:
context: ./
dockerfile: Dockerfile.prod
restart: always
command: gunicorn DierenWelzijn.wsgi:application --bind 0.0.0.0:8000
volumes:
- static_volume:/usr/src/app/staticfiles
- media_volume:/usr/src/app/media
expose:
- 8000
env_file:
- prod.env
proxy:
image: crdierenwelzijn.azurecr.io/proxy1
build:
context: ./proxy
restart: always
depends_on:
- web
ports:
- 80:80
volumes:
- static_volume:/home/app/staticfiles
- media_volume:/home/app/media
volumes:
static_volume:
media_volume:
我的nginx.conf文件看起来像这样:
upstream DierenWelzijn {
server web:8000;
}
server {
listen 80;
server_name https://dierenwelzijndocker.azurewebsites.net;
location / {
proxy_pass http://DierenWelzijn;
proxy_set_header Host $http_host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10M;
proxy_redirect off;
}
location /static/ {
alias /home/app/staticfiles/;
}
location /media/ {
alias /home/app/media/;
}
}
和 settings.py 文件的一部分:
from os import environ
from pathlib import Path
import os
import dotenv
dotenv.read_dotenv()
BASE_DIR = Path(__file__).resolve().parent.parent
https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
SECRET_KEY = os.environ.get('SECRET_KEY')
DEBUG = bool(int(os.environ.get('DEBUG', 0)))
ALLOWED_HOSTS = ['localhost', '192.168.1.135',
'dockerdierenwelzijn.azurewebsites.net', 'www.dockerdierenwelzijn.azurewebsites.net']
ALLOWED_HOSTS.extend(
filter(
None,
os.environ.get('ALLOWED_HOSTS', '').split(" "),
)
)
# SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https")
CSRF_TRUSTED_ORIGINS = [
"https://dockerdierenwelzijn.azurewebsites.net", "http://192.168.1.135:8000"]
# CSRF_TRUSTED_ORIGINS = os.listdir('CSRF_TRUSTED_ORIGINS')
# Application definition
CORS_ALLOW_CREDENTIALS = True
SECURE_CROSS_ORIGIN_OPENER_POLICY = None
DATABASES = {
'default': {
"ENGINE": 'django.db.backends.postgresql',
"HOST": os.environ.get("DB_HOST"),
"NAME": os.environ.get("DB_NAME"),
"USER": os.environ.get('DB_USER'),
'PASSWORD': os.environ.get('DB_PASS'),
"PORT": os.environ.get("DB_PORT", "5432"),
}
}
所以我现在在根文件夹中有 prod.env 文件。但这行不通。
奇怪的是,当我从根文件夹中删除 prod.env 文件并尝试构建 docker 容器时,我收到一个错误,指出该文件不存在。
问:为了执行 prod.env 文件,我必须更改什么?
答:
0赞
Moziii
11/16/2023
#1
根据您的描述,问题似乎出在 Docker 设置中如何读取和使用文件中的环境变量。以下是帮助解决此问题的一些步骤和注意事项:prod.env
- 确保文件中指令中指定的路径正确指向文件。如果文件位于根目录中,则路径应正确为 。
env_file
docker-compose-deploy.yml
prod.env
- prod.env
- 该文件需要位于 Docker 映像的生成上下文中。如果要从根目录构建映像(如 中所示),则放置在根目录中应该可以工作。
prod.env
context: ./
docker-compose-deploy.yml
prod.env
- 在 中,您正在使用 .默认情况下,此函数查找文件。如果您使用的是其他文件名(如 prod.env),则需要显式指定路径:
settings.py
dotenv.read_dotenv()
an .env
dotenv.read_dotenv(os.path.join(BASE_DIR, 'prod.env'))
确保在访问任何环境变量之前执行此代码。
- 在 Dockerfile 中,将整个项目目录复制到映像中。如果 prod.env 文件位于根目录中,则应包括该文件。但是,请注意,Dockerfile 中的 ENV 指令在构建时设置环境变量,而不是在运行时设置环境变量。你的 Django 应用在运行时读取它们。
- 确保文件中的卷挂载不会无意中覆盖 prod.env 所在的目录。
docker-compose-deploy.yml
- 生成映像后,运行容器并在其中执行,以检查 prod.env 文件是否存在于预期位置。
- 复制文件后,暂时将 Dockerfile 中的命令添加到文件中,以确保正确复制该文件。
cat
prod.env
- 用于验证撰写文件是否已正确配置并包含 prod.env 文件。
docker compose config
- 检查 prod.env 文件的权限,确保在容器内运行 Django 应用程序的用户可读取该文件。
- 每次对文件或 Docker 配置进行更改时,请确保使用 .
prod.env
docker compose up --build
评论
0赞
Elvin Jafarov
11/17/2023
docker-compose 被认为是旧技术,最好使用 docker compose。
1赞
Moziii
11/17/2023
在大多数使用 Docker Compose v2 的现代设置中,这两个命令都可能指向相同的 Docker Compose v2 功能,但这并不是普遍正确的,尤其是在仍安装了 Docker Compose v1 的环境中。你是对的; 应该最好使用,我编辑了我的答案。@ElvinJafarovdocker compose
0赞
mightycode Newton
11/17/2023
好的,但我使用的是 docker compose 而不是 docker-compose: docker compose -f docker-compose-deploy.yml build。好的,我将尝试将docker-compose-deploy文件放在一个单独的文件夹中。
评论
.env
COPY
env_file:
os.environ