Server Hardening and Initial Setup
Before deploying any application, secure the underlying infrastructure. Configure cloud provider security groups to restrict inbound traffic strictly to required ports: SSH (22), HTTP (80), and HTTPS (443). Avoid exposing all ports via 0.0.0.0/0 in production—tighten rules to specific IPs or ranges where possible.
Establish a consistent shell environment:
# Connect to server
ssh root@39.99.156.25
# Initialize shell profile
echo 'export PATH=$PATH:$HOME/bin' >> ~/.bash_profile
echo 'PS1="[\u@\h \W]\$ "' >> ~/.bash_profile
source ~/.bash_profile
# Update system and install essential build toolchain
yum -y update
yum -y groupinstall "Development Tools"
yum -y install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel psmisc libffi-devel
Infrastructure Component Installation
MySQL 5.7 Server
Deploy MySQL using the official commmunity repository:
# Install repo package and MySQL server
rpm -Uvh mysql57-community-release-el7-10.noarch.rpm
yum -y install mysql-community-server
# Start and verify service
systemctl start mysqld
systemctl enable mysqld
systemctl status mysqld
# Retrieve initial root password and log in
grep 'temporary password' /var/log/mysqld.log
mysql -uroot -p
# Reset password inside MySQL CLI
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'Cql123456';
FLUSH PRIVILEGES;
Redis 5.0.5 from Source
Compile and install Redis manually for full control over configuration:
# Extract and build
tar -xf redis-5.0.5.tar.gz
cd redis-5.0.5
make
# Install binaries and configure daemon mode
mkdir -p /usr/local/redis
cp -r src/ /usr/local/redis/
cp redis.conf /usr/local/redis/
# Edit /usr/local/redis/redis.conf:
# daemonize yes
# bind 127.0.0.1
# protected-mode yes
# Create symlinks
ln -sf /usr/local/redis/src/redis-server /usr/bin/redis-server
ln -sf /usr/local/redis/src/redis-cli /usr/bin/redis-cli
# Launch as background service
redis-server /usr/local/redis/redis.conf
Python 3.6.7 Compilation
Build Python from source to avoid distribution-specific limitations:
# Build and install
tar -xf Python-3.6.7.tar.xz
cd Python-3.6.7
./configure --prefix=/usr/local/python3 --enable-optimizations
make -j$(nproc) && make install
# Set up global symlinks
ln -sf /usr/local/python3/bin/python3.6 /usr/bin/python3
ln -sf /usr/local/python3/bin/pip3.6 /usr/bin/pip3
# Configure pip mirror for faster dependency resolution
mkdir -p ~/.pip
cat > ~/.pip/pip.conf << 'EOF'
[global]
index-url = https://pypi.tuna.tsinghua.edu.cn/simple/
trusted-host = pypi.tuna.tsinghua.edu.cn
EOF
uWSGI and Virtual Environment Tooling
Install uWSGI and virtual environment managers:
# Install core tools
pip3 install uwsgi virtualenv virtualenvwrapper
# Configure virtualenvwrapper in ~/.bash_profile
echo 'export WORKON_HOME=$HOME/.virtualenvs' >> ~/.bash_profile
echo 'export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3' >> ~/.bash_profile
echo 'source /usr/local/python3/bin/virtualenvwrapper.sh' >> ~/.bash_profile
source ~/.bash_profile
Nginx 1.13.7 Compilation
Compile Nginx with custom prefix for isolation and maintainability:
# Build and install
tar -xf nginx-1.13.7.tar.gz
cd nginx-1.13.7
./configure --prefix=/usr/local/nginx --with-http_ssl_module
make && make install
# Symlink binary
ln -sf /usr/local/nginx/sbin/nginx /usr/bin/nginx
# Verify installation
nginx -t
Application Deployment Workflow
Frontend (Vue.js) Hosting
Configure Nginx to serve static assets with SPA-friendly routing:
# Build frontend locally, then upload
scp -r dist/ root@39.99.156.25:/home/html/
# Edit /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
server {
listen 80;
server_name 39.99.156.25;
charset utf-8;
location / {
root /home/html;
index index.html;
try_files $uri $uri/ /index.html;
}
# Static file handling for API requests
location /api/ {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
}
Backend (Django) Deployment
Deploy Django using uWSGI behind Nginx reverse proxy:
- Set
DEBUG = Falseand defineALLOWED_HOSTS = ['39.99.156.25']inprod_settings.py. - Create dedicated database and user:
mysql -uroot -pCql123456 -e "
CREATE DATABASE luffyapi CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CREATE USER 'luffy_user'@'localhost' IDENTIFIED BY 'SecurePass123!';
GRANT ALL ON luffyapi.* TO 'luffy_user'@'localhost';
FLUSH PRIVILEGES;"
Create uWSGI configuration (/home/project/luffyapi/uwsgi.ini):
[uwsgi]
socket = 127.0.0.1:8808
chdir = /home/project/luffyapi
module = luffyapi.wsgi:application
master = true
processes = 4
threads = 2
max-requests = 5000
vacuum = true
die-on-term = true
logto = /var/log/uwsgi/luffyapi.log
pidfile = /var/run/uwsgi/luffyapi.pid
Update Nginx to proxy API requests:
server {
listen 8000;
server_name 39.99.156.25;
location / {
include uwsgi_params;
uwsgi_pass 127.0.0.1:8808;
uwsgi_read_timeout 300;
}
# Static file offloading
location /static/ {
alias /home/project/luffyapi/static/;
}
}
Finalize backend setup:
# Create virtual environment and install dependencies
mkvirtualenv --python=/usr/bin/python3 luffyapi
workon luffyapi
pip install -r /home/project/luffyapi/requirements.txt
# Collect static files
python /home/project/luffyapi/prod_manage.py collectstatic --noinput
# Run migrations and create superuser
python /home/project/luffyapi/prod_manage.py migrate
python /home/project/luffyapi/prod_manage.py createsuperuser
# Start uWSGI
uwsgi --ini /home/project/luffyapi/uwsgi.ini
# Reload Nginx config
nginx -s reload