django-sspanel
django-sspanel copied to clipboard
Incorrect string value: '\\xE7\\x94\\xA8\\xE6\\x88\\xB7'
I am adapting the Ubuntu 20.04 instructions from the wiki page 在 ubuntu 20.04 上部署面板 so that they will work on AlmaLinux 8, CentOS 8, or Rocky Linux 8. I am also translating the instructions into English.
When I attempt to create the database tables:
python3 manage.py migrate
I get an error:
django.db.utils.OperationalError: (1366, "Incorrect string value: '\xE7\x94\xA8\xE6\x88\xB7' for column sspanel.auth_permission.name at row 1")
Steps to reproduce:
1. Obtain Domain Name
Purchase a domain name from the registrar of your choice. You can alternatively obtain a free domain name from https://freenom.com.
2. Rent Server
You will need to rent a server, which is usually a VPS. These instructions are for AlmaLinux 8, CentOS 8, or Rocky Linux 8. This post was developed and tested on a 1 GB VPS running AlmaLinux 8.
3. Create DNS Record
Create a DNS record type A pointing from your server hostname to your server IP address. When we need an example in what follows, we will specify the hostname as djsspanel.example.com.
4. Prepare Server
SSH into the server as root:
ssh [email protected]
Update all the existing packages on the server:
yum update -y
Install Python 3.9 in preference to Python 3.6 (which would be the default). As per https://www.python.org/downloads, version 3.9.13 was released May 17, 2022. Version 3.9 will be supported until 2025-10.
yum groupinstall "Development tools" -y
yum install wget openssl-devel bzip2-devel libffi-devel -y
cd ~
curl https://www.python.org/ftp/python/3.9.13/Python-3.9.13.tgz -O
tar -xvf Python-3.9.13.tgz
cd Python-3.9.13
./configure --enable-optimizations
make install
The make install takes about 10 minutes. After the installation is finished, you can verify the installation like this:
python3 -V
The output should look like this:
Python 3.9.13
Install the firewall daemon:
yum install firewalld -y
systemctl start firewalld
systemctl enable firewalld
Open the firewall for the HTTP and HTTPS services:
firewall-cmd --zone=public --add-service=http
firewall-cmd --zone=public --add-service=https
firewall-cmd --zone=public --list-all
Make sure you can still get back in before you make any new rules permanent. Also test that you can get back in after a reboot.
exit
ssh [email protected]
firewall-cmd --runtime-to-permanent
reboot
ssh [email protected]
Install the enhanced editor:
yum install vim-enhanced -y
Configure the enhanced editor:
vim ~/.vimrc
Add settings for the editor:
set mouse-=a
syntax on
Save the file. Add an alias from vi to vim:
alias vi=vim
5. Install Nginx and MariaDB
yum install nginx -y
systemctl start nginx
systemctl enable nginx
systemctl status nginx
yum install mariadb-server -y
systemctl start mariadb
systemctl enable mariadb
systemctl status mariadb
Secure installation:
mysql_secure_installation
6. Create Site
Create the root web directory for Django-SSPanel as follows:
mkdir -p /var/www/djsspanel
Enable this directory for the web server:
chcon -R -t httpd_sys_content_t /var/www/djsspanel
Create a site configuration file:
vi /etc/nginx/conf.d/djsspanel.conf
Insert contents based on the template below. At a minimum, change the server_name to match your actual server name.
server {
listen 80;
listen [::]:80;
server_name djsspanel.example.com;
root /var/www/djsspanel;
include /etc/nginx/default.d/*.conf;
location / {
}
}
Save the file.
Reload Nginx with this new configuration:
systemctl reload nginx
Create a test page:
cp /usr/share/nginx/html/* /var/www/djsspanel/
Save the file. Test your basic site in a browser:
http://djsspanel.example.com
7. Get TLS Certificate
Follow the instructions from https://certbot.eff.org for Nginx on CentOS 8:
yum install epel-release -y
yum upgrade -y
If either of the above gives an error Out of memory allocating nnn,nnn,nnn bytes! Aborted, then reboot and repeat the commands.
Install snapd daemon for containerized software packages:
yum install snapd -y
systemctl enable --now snapd.socket
ln -s /var/lib/snapd/snap /snap
snap install core; snap refresh core
If the last command produces an error, too early for operation, device not yet seeded or device model not acknowledged, then wait a few minutes and repeat the command.
Use snap to install certbot Automatic Certificate Management Environment (ACME) client.
snap install --classic certbot
ln -s /snap/bin/certbot /usr/bin/certbot
Run certbot for Nginx web server:
certbot --nginx
certbot renew --dry-run
See if the HTTPS page displays in a browser:
https://djsspanel.example.com
After it's working, delete the test files:
rm /var/www/djsspanel/*
8. Create MySQL Database, User, and Password
You must change the password in the user-creation command below to a password of your own choosing.
mysql -u root
create database sspanel;
create user 'djsspanel'@'localhost' identified by '00Aq2Dr20yeyFJuHFu8Q76ZIhibHZpRA';
grant all privileges on *.* to 'djsspanel'@'localhost' with grant option;
flush privileges;
quit
9. Install Prerequsites
Now for the prerequisites. First the Nginx extras:
yum install https://extras.getpagespeed.com/release-latest.rpm -y
yum groupinstall "nginx extras recommended" -y
Development tools should have already been installed. It does no harm to check:
yum groupinstall "Development tools" -y
Install other dependencies:
yum install python39-pip python39-devel mariadb-devel openssl-devel git screen -y
/usr/local/bin/python3.9 -m pip install --upgrade pip
pip3 install virtualenv
10. Download Django-SSPanel Source
Get Django-SSPanel from GitHub.
cd ~
git clone https://github.com/Ehco1996/django-sspanel.git
11. Specify Database Username and Password
cd django-sspanel
cp .env.sample .env
Edit the .env file:
vi .env
As shown in the example below, please fill in the three values MYSQL_USER, MYSQL_PASSWORD, and HOST.
#--->服务端口 nginx
port=80
#--->mysql
#mysql数据库设置 db.py
MYSQL_USER=djsspanel
MYSQL_PASSWORD=00Aq2Dr20yeyFJuHFu8Q76ZIhibHZpRA
# mysql服务设置
# mysql host默认请保持注释*
# MYSQL_HOST=mysql
#--->网站定制 sites.py
# 网站域名设置(请正确填写,不然订阅功能会失效:
HOST=https://djsspanel.example.com:443
# 网站密钥
SECRET_KEY=aasdasdas
# 是否开启注册
ALLOW_REGISTER=True
# 默认的theme
# 可选列表在 apps/constants.py 里的THEME_CHOICES里
DEFAULT_THEME=default
# 默认加密混淆协议
DEFAULT_METHOD=aes-256-cfb
# 签到流量设置
MIN_CHECKIN_TRAFFIC=10485760
# 10 * 1024 * 1024 (10MB)
MAX_CHECKIN_TRAFFIC=209715200
# 200 * 1024 * 1024 (200MB)
# 网站title
TITLE=谜之屋
SUBTITLE=秘密的小屋
KEYWORDS=秘密的小屋
DESCRIPTION=秘密的小屋
# 用户邀请返利比例
INVITE_PERCENT=0.2
# 用户能生成的邀请码数量
INVITE_NUM=5
# 网站邀请页提示语
INVITEINFO=邀请码实时更新,如果用完了就没了
# 部分API接口TOKEN
TOKEN=youowntoken
# SHORT_URL_ALPHABET 请随机生成,且不要重复
DEFAULT_ALPHABET=qwertyuiopasdfghjklzxcvbnm
# FOR SIMPLE UI
SIMPLEUI_HOME_INFO=False
SIMPLEUI_DEFAULT_ICON=False
# 是否开启用户到期邮件通知
EXPIRE_EMAIL_NOTICE=False
#--->邮箱设置 email.py
# 是否开启邮件功能
USE_SMTP=True
EMAIL_USE_SSL=True
EMAIL_HOST=smtp.163.com
EMAIL_PORT=465
EMAIL_HOST_USER=user
EMAIL_HOST_PASSWORD=yourpass
DEFAULT_FROM_EMAIL=user
#可以与EMAIL_HOST_USER一致
# FOR mailgun*
# MAILGUN_API_KEY=key
# MAILGUN_SENDER_DOMAIN=domain
#--->支付宝对接 pay.py*
#USE_ALIPAY=False
#CHECK_PAY_REQ_IP_FROM_CN=False
#ALIPAY_APP_ID=XXXXXXXX
#ALIPAY_APP_PRIVATE_KEY_STRING="-----BEGIN RSA PRIVATE KEY-----
#-----END RSA PRIVATE KEY-----"
#ALIPAY_PUBLIC_KEY_STRING="-----BEGIN PUBLIC KEY-----
#-----END PUBLIC KEY-----"
ALIPAY_TRADE_INFO="{}元充值码"
#--->其他*
# 时区
#TZ=Asia/Shanghai
# msyql host
#MYSQL_HOST=mysql
# redis host
#REDIS_HOST=redis
# production不开启debug,development开启debug
#DJANGO_ENV=production
Save the file and quit the editor.
Also edit configs/default/db.py.
vi configs/default/db.py
- Replace the value of
MYSQL_USERwithdjsspanel - Replace the value of
MYSQL_PASSWORDwith your actual MySQL password (00Aq2Dr20yeyFJuHFu8Q76ZIhibHZpRAin our examples)
import os
if os.getenv("DJANGO_ENV") != "ci":
# mysql 设置
DATABASES = {
"default": {
"ENGINE": "django_prometheus.db.backends.mysql",
"NAME": "sspanel",
"PASSWORD": os.getenv("MYSQL_PASSWORD", "00Aq2Dr20yeyFJuHFu8Q76ZIhibHZpRA"),
"HOST": os.getenv("MYSQL_HOST", "127.0.0.1"),
"USER": os.getenv("MYSQL_USER", "djsspanel"),
"OPTIONS": {
"autocommit": True,
"init_command": "SET sql_mode='STRICT_TRANS_TABLES'",
"charset": "utf8mb4",
},
}
}
Save the file.
12. Create Load Env Module
Create a module file named load_env.py:
vi load_env.py
Add the following content:
import re, os
# 读取的 str 转换为字典
def file_to_dict( file_path ):
res = {}
with open( file_path, "r" ) as text:
for line in text:
line.strip()
if line[0] == '#' :
continue
index = line.find('#')
if index != -1 :
line = line[:index]
str_list = line.split('=')
if len(str_list) != 2 :
continue
res[ str_list[0].strip() ] = str_list[1].strip()
for key, value in res.items() :
m = re.search('^\${(\s|\w)+}$', value)
if m == None :
continue
begin, end = m.span()
key2 = value[begin+2:end-1].strip()
if key2 in res :
res[key] = res[key2]
return res
dic = file_to_dict('.env')
for key, value in dic.items() :
os.environ[key] = value
13. Modify Manage Module
The manage.py file seems to be already okay -- are any changes required?
#!/usr/bin/env python
import os
import sys
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "configs")
try:
from django.core.management import execute_from_command_line
except ImportError:
# The above import may fail for some other reason. Ensure that the
# issue is really that Django is missing to avoid masking other
# exceptions on Python 2.
try:
pass
except ImportError:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
)
raise
execute_from_command_line(sys.argv)
14. Create Module Dependency File
vi requirements.txt
Insert contents:
Django==3.2
django-anymail==8.2
django-countries==7.1
django-prometheus==2.1.0
django-simpleui==2021.4.1
flask>=0.11
Markdown==3.3.4
mysqlclient==2.0.3
python-alipay-sdk==3.0.1
sentry-sdk==1.0.0
short-url==1.2.2
tomd==0.1.3
uWSGI==2.0.19.1
pendulum==2.1.2
redis==3.5.3
celery==5.0.5
black==20.8b1
django-debug-toolbar==3.2.1
isort==5.8.0
autoflake==1.4
pip-upgrader==1.4.15
Save the file.
15. Add Proxy Pass to Nginx
Edit the Nginx site configuration file:
vi /etc/nginx/conf.d/djsspanel.conf
In the server block listening on port 443, in the block for location /, add a proxy_pass to localhost port 8002.
Here's what the entire file looks like after your addition:
server {
server_name djsspanel.example.com;
root /var/www/sspanel;
include /etc/nginx/default.d/*.conf;
location / {
proxy_pass http://localhost:8002/;
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
listen [::]:443 ssl ipv6only=on; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/djsspanel.example.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/djsspanel.example.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = djsspanel.example.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen [::]:80;
server_name djsspanel.example.com;
return 404; # managed by Certbot
}
Save the file.
Restart Nginx with the new configuration.
systemctl restart nginx
16. Start Site
Run the screen command to create the sspanel session. This way, even if you accidentally disconnect the network from this host, the currently running program will not be killed by the system.
screen -R sspanel
The -R option for screen means "reattach a session and, if necessary, detach or even create it first."
Create a relatively isolated python virtual environment:
virtualenv --python=python3 venv
Start the python virtual environment:
source venv/bin/activate
Install the dependent component packages required for the website to run in the virtual environment:
pip3 install -r requirements.txt
Collect static resources:
python3 manage.py collectstatic --noinput
Create database tables:
python3 manage.py migrate
The above command results in an error:
django.db.utils.OperationalError: (1366, "Incorrect string value: '\xE7\x94\xA8\xE6\x88\xB7' for column sspanel.auth_permission.name at row 1")