前几天的打底,
把 Gitlab、Jenkins 建好,
但是仍然少了最重要的主角,
要部署的服务本身,
今天我们终於要建立一个 Portal 来部署罗,
以下 Portal 建立会以 Python Django 为例,
挑选 Python Django 是因为大多数 Web 服务器都不是用 Python 所撰写,
需要另外设定接口才能够让服务器和 Python 沟通,
再加上 Python 有提供虚拟环境(Virtual Environment),
在套件管理上不需要仰赖全域的配置,
个人是觉得 Python 2 和 Python 3 有 Break 才会有这功能
很少在建置阳春的环境时,
就需要做这麽麻烦的设定,
因此很适合当作教学使用,
已经会建立专案的,
可以跳过专案建立步骤去看 EC2 和 WSGI 的配置,
如果两个都会的,
估计手动部署到 EC2 也不成问题,
可以直接跳过今天的教学休息一天。
前天 EP07 时
我们已经建立一个 portal 的 repository
接下来我们就需要再次进到 vagrant 的 project 中
把 code check out 下来
cd /vagrant_data/project/
git clone git@你的IP:ithome-ironman-2021/portal.git
cd portal
git branch develop
git push -u origin develop
当时我们挑选的 Ubuntu 20.04
已经内建 python3
不过保险起见
还是先确认版本和位置
python --version
whereis python 3
如果不幸你的 Linux 版本比较旧
都没有预先安装 Python 3
建议可参考 在Linux上安装Python 3
如果我们有一个以上的 Python 专案
此时我们就需要思考每个环境的 Python 版本和套件版本是否一致
我们在 /vagrant_data 中建立新的资料夹 venv
以便可以在 vagrant 建立的虚拟机械内外
都可以操作
cd /vagrant_data/
sudo mkdir vevn
cd venv
sudo apt-get install python3-pip
安装好後输入 pip3 指令
查看指令是否可以正常运作
pip3 --version
sudo pip3 install virtualenv
先查看 virtualenv 的位置後
pip3 show virtualenv
在用 python 执行建立 virtualenv
建立名为 ithome-ironman-portal 的虚拟环境
python3 /home/vagrant/.local/lib/python3.8/site-packages/virtualenv ithome-ironman-portal
使用 source 或是 . ithome-ironman-portal/bin/activate
都可以启动虚拟环境
source ithome-ironman-portal/bin/activate
启动後就可以看到 console 前会出现 (ithome-ironman-portal) 的字样
如果是使用 windows
无法正常启用虚拟环境
或是启用後安装套件都会把全域的套件版本盖掉的
可以参考这篇
有可能是因为在 windows 上的 path 设定了 python 的路径
导致 virtualenv 运作有问题
想知道是否有正常设置
还可以执行下列语法
pip3 list
一个乾净的 virtualenv 环境
在初始化後应该只会看到两三个基本套件
python -m pip install Django
其实只要下 django-admin startproject portal
就可以产生一个专案
不过因为我们专案是从 Gitlab 上 clone 下来的
又因为起专案时
只能指定空的资料夹
因此我们只能先在一个地方起专案後
再将专案内的东西搬移到 project 底下的 portal 里面
cd /vagrant_data
django-admin startproject portal
sudo cp -R /vagrant_data/portal/*.* /vagrant_data/project/portal
sudo cp -R /vagrant_data/portal/portal/ /vagrant_data/project/portal/
sudo rm -rf /vagrant_data/portal/
cd /vagrant_data/project/portal/
接下来只要启动
server 就可以运作了
python manage.py runserver 0.0.0.0:8000
但我们使用浏览器依旧无法看到启动的 server
此时别慌
电脑没有坏,安装过程也正常
是因为我们在虚拟机械里面起 server
但是 port 没有转发到虚拟机械外面
此时我们需要修改 Vagrantfile
在 config.vm.box 下方
新增一个 port 转发的设定
.
.
.
config.vm.box = "ubuntu/focal64"
config.vm.network "forwarded_port", guest: 8000, host: 8000
.
.
.
重启 vagrant 不需要下 vagrant halt 再 vagrant up
vagrant reload
source /vagrant_data/venv/ithome-ironman-portal/bin/activate
cd /vagrant_data/project/portal
python manage.py runserver 0.0.0.0:8000
关於 vagrant 内为什麽要 runserver 0.0.0.0:8000
大家可参考「Connection Reset when port forwarding with Vagrant」和「Connection Reset when port forwarding with Vagrant」的讨论
刚刚我们建立虚拟环境
而且还安装套件都只存在於本机
但是实际上多人协作
不会把 python 和虚拟环境进版控
而是会将套件版本记录起来进版控
在 python 中的套件管理工具是 pip
而记录这些套件的档案则是 requirements.txt
只要下个指令就可以把目前虚拟环境中的套件记录起来
pip freeze > requirements.txt
# Django #
*.log
*.pot
*.pyc
__pycache__
db.sqlite3
media
# Backup files #
*.bak
# If you are using PyCharm #
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/dictionaries
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.xml
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/gradle.xml
.idea/**/libraries
*.iws /out/
# Python #
*.py[cod]
*$py.class
# Distribution / packaging
.Python build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
.pytest_cache/
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery
celerybeat-schedule.*
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# mkdocs documentation
/site
# mypy
.mypy_cache/
# Sublime Text #
*.tmlanguage.cache
*.tmPreferences.cache
*.stTheme.cache
*.sublime-workspace
*.sublime-project
# sftp configuration file
sftp-config.json
# Package control specific files Package
Control.last-run
Control.ca-list
Control.ca-bundle
Control.system-ca-bundle
GitHub.sublime-settings
# Visual Studio Code #
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
.history
settings.py 修改 DATABASE
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': '',
'USER': '',
'PASSWORD': '',
'HOST': '',
'PORT': '5432'
}
}
requirements.txt 新增一条
psycopg2==2.8.6
已经连续教好几天要怎麽建置 EC2 了
不会还要教吧?
没关系,送佛上西天
我们直接附上解答
让你把 EC2、security group、security group rule 都配置好
比较特别的是
这里有特别加入 port 3128
因为听说 pip install 是走 3128
resource "aws_security_group" "ithome_ironman_portal" {
name = "ithome-ironman-portal"
description = "It is used for ithome ironman 2021 portal."
vpc_id = data.aws_vpc.default.id
tags = { Name = "ithome ironman 2021" }
revoke_rules_on_delete = null
}
resource "aws_security_group_rule" "ithome_ironman_igress_22" {
type = "ingress"
from_port = 22
to_port = 22
cidr_blocks = [var.personal_cidr,]
protocol = "tcp"
security_group_id = aws_security_group.ithome_ironman_portal.id
}
resource "aws_security_group_rule" "ithome_ironman_egress_22" {
type = "egress"
from_port = 22
to_port = 22
cidr_blocks = [var.personal_cidr,]
protocol = "tcp"
security_group_id = aws_security_group.ithome_ironman_portal.id
}
resource "aws_security_group_rule" "ithome_ironman_igress_80" {
type = "ingress"
from_port = 80
to_port = 80
cidr_blocks = [var.personal_cidr,]
protocol = "tcp"
security_group_id = aws_security_group.ithome_ironman_portal.id
}
resource "aws_security_group_rule" "ithome_ironman_egress_80" {
type = "egress"
from_port = 80
to_port = 80
cidr_blocks = ["0.0.0.0/0",]
protocol = "tcp"
security_group_id = aws_security_group.ithome_ironman_portal.id
}
resource "aws_security_group_rule" "ithome_ironman_igress_443" {
type = "ingress"
from_port = 443
to_port = 443
cidr_blocks = [var.personal_cidr,]
protocol = "tcp"
security_group_id = aws_security_group.ithome_ironman_portal.id
}
resource "aws_security_group_rule" "ithome_ironman_egress_443" {
type = "egress"
from_port = 443
to_port = 443
cidr_blocks = ["0.0.0.0/0",]
protocol = "tcp"
security_group_id = aws_security_group.ithome_ironman_portal.id
}
resource "aws_security_group_rule" "ithome_ironman_ingress_3128" {
type = "ingress"
from_port = 3128
to_port = 3128
cidr_blocks = ["0.0.0.0/0",]
protocol = "tcp"
security_group_id = aws_security_group.ithome_ironman_portal.id
}
resource "aws_security_group_rule" "ithome_ironman_egress_3128" {
type = "egress"
from_port = 3128
to_port = 3128
cidr_blocks = ["0.0.0.0/0",]
protocol = "tcp"
security_group_id = aws_security_group.ithome_ironman_portal.id
}
resource "tls_private_key" "ithome_ironman_portal" {
algorithm = "RSA"
rsa_bits = 4096
}
resource "aws_key_pair" "ithome_ironman_portal" {
key_name = "portal"
public_key = tls_private_key.ithome_ironman_portal.public_key_openssh
}
resource "local_file" "ithome_ironman_portal" {
content = tls_private_key.ithome_ironman_portal.private_key_pem
filename = format("%s.pem", aws_key_pair.ithome_ironman_portal.key_name)
}
resource "aws_instance" "ithome_ironman_portla" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.small"
subnet_id = sort(data.aws_subnet_ids.subnet_ids.ids)[0]
key_name = aws_key_pair.ithome_ironman_portal.key_name
vpc_security_group_ids = [ aws_security_group.ithome_ironman_portal.id ]
disable_api_termination = false
ebs_optimized = true
hibernation = false
tags = {
Name = "ithome ironman 2021 portal"
Usage = "portal"
Creator = "Terraform"
}
root_block_device {
delete_on_termination = true
encrypted = false
throughput = 0
volume_size = 9
volume_type = "gp2"
tags = {
Name = "ithome ironman 2021 portal"
Attached = "ithome ironman 2021 portal"
}
}
}
sudo chmod 400 portal.pem
ssh -i "portal.pem" ubuntu@你的HOST
sudo apt-get update
sudo apt-get upgrdae -y
sudo apt-get install apache2
sudo apt-get install python3 python3-virtualenv python3-pip libpq-dev python-dev
sudo mkdir /var/www/venv
如果不更改拥有者
或是没使用 chmod 更改资料夹/档案权限
等等在进行安装 mod_wsgi 时会失败
sudo chown -R ubuntu /var/www/venv
pip3 show virtualenv
sudo python3 /usr/lib/python3/dist-packages/virtualenv /var/www/venv/portal
source /var/www/venv/portal/bin/activate
pip install -vvv mod_wsgi
将 module 位置复制起来
等等在 confige apache 时会用上
pip show mod-wsgi
刚刚查到的 wsgi 模组位置
会用在 LoadModule wsgi_module 上
需要将路径替换掉 你的路径/mod_wsgi/server/mod_wsgi-py38.cpython-38-x86_64-linux-gnu.so
apache 的 conf 档位於 /etc/apache2/apache2.conf 中
WSGIPythonHome 是设定刚刚 virtualenv 的路径
WSGIPythonPath 则是设定专案的根目录
在 conf 底下加相对应的参数大致如下
ServerName localhost
Alias /static/ /var/www/portal/static
<Directory /var/www/portal/static>
Require all granted
</Directory>
LoadModule wsgi_module "/var/www/venv/portal/lib/python3.8/site-packages/mod_wsgi/server/mod_wsgi-py38.cpython-38-x86_64-linux-gnu.so"
WSGIPythonHome /var/www/venv/portal
WSGIPythonPath /var/www/portal
WSGIScriptAlias / /var/www/portal/portal/wsgi.py
<Directory /var/www/portal/portal>
<Files wsgi.py>
Require all granted
</Files>
</Directory>
如果直接将资料夹封存
会遇到一个问题
就是
git archive --format=tar.gz --output ./portal.tar.gz HEAD
scp -i "/vagrant_data/project/terraform/stage/portal.pem" ./portal.tar.gz ubuntu@你的HOST:~/portal.tar.gz
ssh -i "/vagrant_data/project/terraform/stage/portal.pem" ubuntu@你的HOST
sudo mkdir /var/www/portal
sudo mv ~/portal.tar.gz /var/www/portal
cd /var/www/portal
sudo tar zxvf portal.tar.gz
sudo chmod 755 -R /var/www/portal
安装套件前
记得要先启动虚拟环境
source /var/www/venv/portal/bin/activate
pip install -r /var/www/portal/requirements.txt
sudo service apache2 restart
如果重启遇到这问题
表示已经离成功不远了
这是 Django 的一个安全机制
需要在 settings.py 的 ALLOWED_HOSTS 里面加 EC2 的 IP(或是连入的HOST NAME)
加入後再 restart apache2
就可以正常启动罗
参考资料:
<<: Day 7 - 使用 AES-CBC 机制对 Message 内文进行加密
>>: [区块链&DAPP介绍 Day13] Solidity 教学 - contracts-2
列表移动过渡(List move transition) 不仅可以做出淡出与淡入,还可以改变位置,只...
今天需要疗癒的视觉效果,Menu 再等等.. 跳脱进度,想先做网站 Favicon 的设计 (其实是...
事发经过简述如下: 某天叉烧包老板收到一简讯要求回复密码,回复後发现知名 App 被入侵且友人帐号也...
想要在html表格中完成合并储存格的效果,需要用到rowspan和colspan分别为垂直和水平合并...
今天原本想开始抓个股的kbar资料及後续处理,结果在清洗Contract资料时,发现抓出来的TSE+...