学习网页应用开发 #2
这篇文章的内容
在Web应用开发学习#1中,我们记录了要实现的Web服务器和应用程序的结构。
在本文中,我们将记录这个环境的构建步骤。下图是要实现的Web应用程序的结构图的再次放映。
※ 这里补充了GitHub环境构建步骤的解释说明。
2. 环境建设
用語の定義
用語
定義
<path/to/project> 環境を構築する作業ディレクトリのルート
整个流程
2-2. 将软件安装到主机PC
↓
2-3. 在docker-compose中添加Django服务器
↓
2-4. 在docker-compose中添加PostgreSQL服务器
↓
2-5. 在docker-compose中添加Nginx服务器
2-2. 将软件包安装到主机电脑
為了啟動伺服器,將docker-compose和Django項目所需的virtualenv安裝到主機PC上。
$ sudo apt install python3-pip docker-compose
$ sudo -H pip3 install --upgrade pip
$ sudo -H pip3 install virtualenv
2-3. 将Django服务器添加到docker-compose中
Django应用服务器会从docker-compose.yml中调用Dockerfile进行图像构建和容器启动。
创建Django项目将在虚拟环境中使用virtualenv进行。
2-3-1. 创建Django项目
$ cd <path/to/project>
$ virtualenv venv
$ source venv/bin/activate
(venv)$ pip3 install django
(venv)$ mkdir django_project
(venv)$ cd django_project
(venv)$ django-admin startproject project .
(venv)$ tree .
.
├── manage.py
└── project
├── __init__.py
├── asgi.py
├── settings.py
├── urls.py
└── wsgi.py
(venv)$ deactivate
2-3-2. 添加和编辑与Docker相关的配置文件
在创建Django项目时,默认情况下会在django_project/project/settings.py文件中写入SECRET_KEY。
在生产环境中,应该将SECRET_KEY限定在企业内部或团队内部,并进行加密以确保机密性,并进行管理。
但是,在开发环境中也保持机密性可能会降低开发效率。
所以,在本次实现中,我们将引入一种机制,即在django_project / project / local_settings.py中记录开发用的SECRET_KEY。 SECRET_KEY可以使用django模块的get_random_secret_key()函数生成(我们已在GitHub上注册了示例代码)。
$ cd <path/to/project>/django_project
$ touch Dockerfile
$ touch requirements.txt
$ cd ..
$ touch docker-compose.yml
$ touch .env.dev
$ vim django_project/project/settings.py
WORKDIR /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN pip install –upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt
COPY . .
服务:
web:
构建:./django_project
命令:python manage.py runserver 0.0.0.0:8000
卷:
– ./django_project/:/usr/src/app/
端口:
– 8000:8000
环境变量文件:
– ./.env.dev
ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
+import os
from pathlib import Path
+try:
+ from .local_settings import SECRET_KEY
+except ImportError:
+ pass
+
# 以下代码用于构建项目路径,如:BASE_DIR / ‘subdir’。
BASE_DIR = Path(__file__).resolve().parent.parent
@@ -19,13 +25,10 @@ BASE_DIR = Path(__file__).resolve().parent.parent
# 快速启动开发设置-不适用于生产环境
# 更多详情请参考 https://docs.djangoproject.com/en/3.2/howto/deployment/checklist/
-# 安全警告:在生产环境中,请保持使用的密钥秘密!
-SECRET_KEY = ‘django-insecure-np7oaeipi%hbg9hd^jg+*$8dc!d(*5cnbjzid1-m-kp^fu1fbm’
–
# 安全警告:不要在生产环境中将 DEBUG 设置为 True!
-DEBUG = True
+DEBUG = os.environ.get(“DEBUG”)
-ALLOWED_HOSTS = []
+ALLOWED_HOSTS = os.environ.get(“ALLOWED_HOSTS”).split(” “)
# 应用程序定义
2-3-3. 确认火箭发动
使用下面的命令来构建Docker镜像,启动容器,并访问http://localhost:8000,可以确认Django火箭的显示。
$ cd <path/to/project>
$ docker-compose build
$ docker-compose up -d
当我们确认正在运行的容器时,我们会看到一个名为”xxx_web_1″的容器正在运行。
这里的”xxx”是指项目名称(即目录名)。
在本篇文章中,为了进行操作验证,我们使用了项目名称”test”,所以会是”test_web_1″的容器正在运行。
$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------------
test_web_1 python manage.py runserver ... Up 0.0.0.0:8000->8000/tcp,:::8000->8000/tcp
将PostgreSQL服务器添加到2-4.docker-compose中。
2-4-1. 添加PostgreSQL服务器配置
$ cd <path/to/project>
$ vim .env.dev
$ vim docker-compose.yml
$ vim django_project/Dockerfile
$ vim django_project/requirements.txt
$ vim django_project/project/settings.py
$ touch django_project/entrypoint.sh
DEBUG=True
ALLOWED_HOSTS=localhost 127.0.0.1 [::1]
SQL_DATABASE=db_name
SQL_USER=user_name
SQL_PASSWORD=password
SQL_HOST=db
SQL_PORT=5432
POSTGRES_USER=user_name
POSTGRES_PASSWORD=password
POSTGRES_DB=db_name
DATABASE=postgres
– 8000:8000
env_file:
– ./.env.dev
+ depends_on:
+ – db
+
+ db:
+ image: postgres:13.4-alpine
+ volumes:
+ – postgres_data:/var/lib/postgresql/data/
+ env_file:
+ – ./.env.dev
+
+volumes:
+ postgres_data:
+ “`
django_project/Dockerfile的编辑
@@ -5,9 +5,13 @@ 工作目录 /usr/src/app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
+RUN apk update \
+ && apk add postgresql-dev gcc python3-dev musl-dev
+
RUN pip install –upgrade pip
COPY ./requirements.txt .
RUN pip install -r requirements.txt
COPY . .
+ENTRYPOINT [“/usr/src/app/entrypoint.sh”]
“`
Django
+psycopg2-binary
DATABASES = {
‘default’: {
– ‘ENGINE’: ‘django.db.backends.sqlite3’,
– ‘NAME’: BASE_DIR / ‘db.sqlite3’,
+ ‘ENGINE’: ‘django.db.backends.postgresql_psycopg2’,
+ ‘NAME’: os.environ.get(“SQL_DATABASE”),
+ ‘USER’: os.environ.get(“SQL_USER”),
+ ‘PASSWORD’: os.environ.get(“SQL_PASSWORD”),
+ ‘HOST’: os.environ.get(“SQL_HOST”),
+ ‘PORT’: os.environ.get(“SQL_PORT”),
}
}
如果[ “$DATABASE” = “postgres” ]
那么
输出 “等待postgres启动中…”
当 ! nc -z $SQL_HOST $SQL_PORT 时,循环执行以下操作
等待 0.1s
输出 “PostgreSQL已启动”
结束
执行 “$@”
2-4-2. 确定PostgreSQL服务器工作情况
请使用以下命令进行构建和启动。
$ docker-compose build
$ docker-compose up -d
正在运行的容器添加了数据库服务器”xxx_db_1″。
$ docker-compose ps
Name Command State Ports
----------------------------------------------------------------------------------------------
test_db_1 docker-entrypoint.sh postgres Up 5432/tcp
test_web_1 /usr/src/app/entrypoint.sh ... Up 0.0.0.0:8000->8000/tcp,:::8000->8000/tcp
当迁移并检查列表时,可以以数据库列表的方式显示如下。
$ docker-compose exec web python manage.py migrate --no-input
Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying sessions.0001_initial... OK
$ docker-compose exec db psql --username=user_name --dbname=db_name
psql (13.4)
Type "help" for help.
db_name=# \l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-----------+----------+------------+------------+-------------------------
db_name | user_name | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | user_name | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | user_name | UTF8 | en_US.utf8 | en_US.utf8 | =c/user_name +
| | | | | user_name=CTc/user_name
template1 | user_name | UTF8 | en_US.utf8 | en_US.utf8 | =c/user_name +
| | | | | user_name=CTc/user_name
在docker-compose中添加Nginx服务器。
2-5-1. Gunicorn的配置
$ cd <path/to/project>
$ vim docker-compose.yml
$ vim django_project/requirements.txt
$ vim django_project/Dockerfile
服务:
网页:
构建:./django_project
– 命令:python manage.py runserver 0.0.0.0:8000
– 卷:
– – ./django_project/:/usr/src/app/
+ 命令:gunicorn project.wsgi:application –bind 0.0.0.0:8000
端口:
– 8000:8000
env文件:
Django
psycopg2-binary
+gunicorn
# 从python:3.9.7-alpine作为构建器开始
FROM python:3.9.7-alpine as builder
# 设置工作目录
WORKDIR /usr/src/app
# 更新apk并安装依赖
RUN apk update \
&& apk add postgresql-dev gcc python3-dev musl-dev
# 更新pip并安装flake8
RUN pip install –upgrade pip \
&& pip install flake8
# 将当前目录下的文件复制到工作目录
COPY . .
# 从python:3.9.7-alpine开始新的阶段
FROM python:3.9.7-alpine
# 创建/home/app目录
RUN mkdir -p /home/app
# 创建app用户和组
RUN addgroup -S app && adduser -S app -G app
# 设置HOME和APP_HOME环境变量
ENV HOME=/home/app
ENV APP_HOME=/home/app/web
RUN mkdir ${APP_HOME}
WORKDIR ${APP_HOME}
# 更新apk并安装libpq
RUN apk update && apk add libpq
# 复制构建器阶段生成的依赖库到/wheels目录
COPY –from=builder /usr/src/app/wheels /wheels
# 复制requirements.txt文件和entrypoint.sh文件到APP_HOME目录
COPY –from=builder /usr/src/app/requirements.txt .
COPY ./entrypoint.sh $APP_HOME
# 复制当前目录下的所有文件到APP_HOME目录
COPY . $APP_HOME
# 设置APP_HOME目录权限为app用户
RUN chown -R app:app $APP_HOME
# 使用app用户运行容器时的入口点
USER app
ENTRYPOINT [“/home/app/web/entrypoint.sh”]
“`
2-5-2. 添加Nginx配置
$ cd <path/to/project>
$ vim docker-compose.yml
$ mkdir nginx
$ touch nginx/Dockerfile
$ touch nginx/nginx.conf
$ vim django_project/project/settings.py
$ vim django_project/Dockerfile
services:
web:
build: ./django_project
command: gunicorn project.wsgi:application –bind 0.0.0.0:8000
volumes:
– static_volume:/home/app/web/static
ports:
– 8000
env_file:
– ./.env.dev
depends_on:
– postgres
nginx:
build: ./nginx
volumes:
– static_volume:/home/app/web/static
ports:
– 1317:80
depends_on:
– web
volumes:
postgres_data:
static_volume:
“`
运行命令删除/etc/nginx/conf.d/default.conf文件
将nginx.conf复制到/etc/nginx/conf.d中
服务器网页:8000;
}
服务器 {
监听 80;
地址 / {
代理传递 http://项目;
代理设置头部 X-Forwarded-For $proxy_add_x_forwarded_for;
代理设置头部 Host $host;
代理重定向 关闭;
}
地址 /静态/ {
别名 /home/app/web/static/;
}
}
# https://docs.djangoproject.com/en/3.2/howto/static-files/
STATIC_URL = ‘/static/’
+STATIC_ROOT = os.path.join(BASE_DIR, “static”)
# Default primary key field type
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
ENV HOME=/home/app
ENV APP_HOME=/home/app/web
运行 mkdir ${APP_HOME}
+运行 mkdir ${APP_HOME}/static
进入 ${APP_HOME}
运行 apk update && apk add libpq
2-5-3.确认行动
使用以下命令来构建镜像,启动容器,并访问http://localhost:1317,即可看到Django火箭页面。
与之前不同的是,访问的端口已经从8000改为了1317,这意味着通过浏览器访问Nginx服务器,并通过Nginx服务器经过Gunicorn访问Django Web服务器获取页面。
$ docker-compose build
$ docker-compose up -d
您可以确认已启动容器中已经添加了“xxx_nginx_1”。
$ docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------------------
test_db_1 docker-entrypoint.sh postgres Up 5432/tcp
test_nginx_1 /docker-entrypoint.sh ngin ... Up 0.0.0.0:1317->80/tcp,:::1317->80/tcp
test_web_1 /home/app/web/entrypoint.s ... Up 0.0.0.0:49153->8000/tcp,:::49153->8000/tcp
3. 最后
我已经记录了使用docker-compose构建web服务器基础环境的步骤。
接下来,我计划继续介绍引入Bootstrap和实施机器学习应用程序的步骤。
4. 相关链接 (Guanlian lianjie)
-
- Webアプリケーション開発のお勉強 目次
GitHubのReferenceを参照