| 软件 | 版本要求 |
|---|
| Python | 3.9 - 3.10 |
| MySQL | 5.7+ / 8.0 |
| Redis | 5.0+ |
| Nginx | 1.18+ |
| 软件 | 版本要求 |
|---|
| Node.js | 18.0+ |
| pnpm | 9.0+ |
pip install poetry
cd salted-fish-api
poetry install
poetry shell
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'salted_fish',
'USER': 'your_username',
'PASSWORD': 'your_password',
'HOST': 'localhost',
'PORT': '3306',
'OPTIONS': {
'charset': 'utf8mb4',
}
}
}
CREATE DATABASE salted_fish CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
CACHES = {
'default': {
'BACKEND': 'django_redis.cache.RedisCache',
'LOCATION': 'redis://127.0.0.1:6379/0',
'OPTIONS': {
'CLIENT_CLASS': 'django_redis.client.DefaultClient',
}
}
}
CELERY_BROKER_URL = 'redis://127.0.0.1:6379/1'
CELERY_RESULT_BACKEND = 'django-db'
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser
python manage.py collectstatic
pip install gunicorn
gunicorn SaltedFish.wsgi:application \
--bind 0.0.0.0:8000 \
--workers 4 \
--timeout 120 \
--access-logfile logs/access.log \
--error-logfile logs/error.log
celery -A SaltedFish beat -l info \
--logfile=Log/CeleryTask/celery_beat.log
celery -A SaltedFish worker -l info \
--logfile=Log/CeleryTask/celery_worker.log \
-P eventlet
[program:salted-fish-api]
command=/path/to/venv/bin/gunicorn SaltedFish.wsgi:application --bind 0.0.0.0:8000 --workers 4
directory=/path/to/salted-fish-api
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/supervisor/salted-fish-api.log
[program:celery-worker]
command=/path/to/venv/bin/celery -A SaltedFish worker -l info -P eventlet
directory=/path/to/salted-fish-api
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/supervisor/celery-worker.log
[program:celery-beat]
command=/path/to/venv/bin/celery -A SaltedFish beat -l info
directory=/path/to/salted-fish-api
user=www-data
autostart=true
autorestart=true
redirect_stderr=true
stdout_logfile=/var/log/supervisor/celery-beat.log
sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start all
cd salted-fish-web
pnpm install
pnpm build
cd salted-fish-mobile
npm install
npm run build
upstream salted_fish_api {
server 127.0.0.1:8000;
}
server {
listen 80;
server_name admin.example.com;
root /var/www/salted-fish-web/apps/web-antd/dist;
index index.html;
gzip on;
gzip_types text/plain text/css application/json application/javascript;
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://salted_fish_api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /media/ {
alias /var/www/salted-fish-api/media/;
expires 7d;
}
}
server {
listen 80;
server_name m.example.com;
root /var/www/salted-fish-mobile/dist;
index index.html;
gzip on;
gzip_types text/plain text/css application/json application/javascript;
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
}
location / {
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://salted_fish_api;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
sudo ln -s /etc/nginx/sites-available/salted-fish /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
version: '3.8'
services:
mysql:
image: mysql:8.0
container_name: salted-fish-mysql
environment:
MYSQL_ROOT_PASSWORD: root_password
MYSQL_DATABASE: salted_fish
MYSQL_USER: salted_fish
MYSQL_PASSWORD: your_password
volumes:
- mysql_data:/var/lib/mysql
ports:
- "3306:3306"
restart: always
redis:
image: redis:7-alpine
container_name: salted-fish-redis
volumes:
- redis_data:/data
ports:
- "6379:6379"
restart: always
api:
build:
context: ./salted-fish-api
dockerfile: Dockerfile
container_name: salted-fish-api
depends_on:
- mysql
- redis
environment:
- DEBUG=False
- DATABASE_URL=mysql://salted_fish:your_password@mysql:3306/salted_fish
- REDIS_URL=redis://redis:6379/0
volumes:
- ./salted-fish-api/media:/app/media
- ./salted-fish-api/Log:/app/Log
ports:
- "8000:8000"
restart: always
celery-worker:
build:
context: ./salted-fish-api
dockerfile: Dockerfile
container_name: salted-fish-celery-worker
command: celery -A SaltedFish worker -l info -P eventlet
depends_on:
- api
- redis
environment:
- DEBUG=False
- DATABASE_URL=mysql://salted_fish:your_password@mysql:3306/salted_fish
- REDIS_URL=redis://redis:6379/0
volumes:
- ./salted-fish-api/Log:/app/Log
restart: always
celery-beat:
build:
context: ./salted-fish-api
dockerfile: Dockerfile
container_name: salted-fish-celery-beat
command: celery -A SaltedFish beat -l info
depends_on:
- api
- redis
environment:
- DEBUG=False
- DATABASE_URL=mysql://salted_fish:your_password@mysql:3306/salted_fish
- REDIS_URL=redis://redis:6379/0
restart: always
nginx:
image: nginx:alpine
container_name: salted-fish-nginx
depends_on:
- api
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./salted-fish-web/apps/web-antd/dist:/var/www/web
- ./salted-fish-mobile/dist:/var/www/mobile
- ./salted-fish-api/media:/var/www/media
ports:
- "80:80"
- "443:443"
restart: always
volumes:
mysql_data:
redis_data:
FROM python:3.10-slim
WORKDIR /app
RUN apt-get update && apt-get install -y \
gcc \
default-libmysqlclient-dev \
pkg-config \
&& rm -rf /var/lib/apt/lists/*
RUN pip install poetry
COPY pyproject.toml poetry.lock ./
RUN poetry config virtualenvs.create false \
&& poetry install --no-dev --no-interaction --no-ansi
COPY . .
RUN python manage.py collectstatic --noinput
CMD ["gunicorn", "SaltedFish.wsgi:application", "--bind", "0.0.0.0:8000", "--workers", "4"]
docker-compose up -d --build
docker-compose logs -f
docker-compose down
sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d admin.example.com -d m.example.com
sudo certbot renew --dry-run
/var/log/nginx/ # Nginx 日志
/var/log/supervisor/ # Supervisor 日志
/path/to/salted-fish-api/Log/
├── RunLog/ # 应用运行日志
└── CeleryTask/ # Celery 任务日志
# /etc/logrotate.d/salted-fish
/path/to/salted-fish-api/Log/*.log {
daily
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 www-data www-data
}
sudo supervisorctl status
sudo supervisorctl restart salted-fish-api
tail -f /var/log/nginx/error.log
tail -f /path/to/salted-fish-api/Log/CeleryTask/celery_worker.log
python manage.py clearsessions
mysqldump -u root -p salted_fish > backup_$(date +%Y%m%d).sql