云服务器相关
规划
|
1 2 3 4 5 6 7 8 9 10 |
/root/apps/ ├── nginx-proxy/ # Nginx 反向代理 │ ├── docker-compose.yml │ ├── nginx.conf │ ├── conf.d/ │ ├── ssl/ │ └── logs/ ├── go-api/ # Go API 服务(以后部署) ├── frontend/ # 前端服务(以后部署) └── ... # 其他服务 |
Nginx容器
概述
- 用于反向代理
目录结构
|
1 2 3 |
mkdir -p /root/apps/nginx-proxy/conf.d mkdir -p /root/apps/nginx-proxy/ssl mkdir -p /root/apps/nginx-proxy/logs |
主配置
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
cat > /root/apps/nginx-proxy/nginx.conf << 'EOF' user nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; keepalive_timeout 65; gzip on; gzip_types text/plain text/css application/json application/javascript text/xml; client_max_body_size 50m; include /etc/nginx/conf.d/*.conf; } EOF |
默认站点配置
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
cat > /root/apps/nginx-proxy/conf.d/default.conf << 'EOF' server { listen 80 default_server; server_name _; # 默认返回一个简单的提示页 location / { return 200 '{"status":"ok","message":"nginx proxy is running"}'; add_header Content-Type application/json; } # 健康检查 location /health { return 200 'healthy'; add_header Content-Type text/plain; } } EOF |
API 的代理配置
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
cat > /root/apps/nginx-proxy/conf.d/api.conf.bak << 'EOF' # 重命名为 api.conf 即可生效 server { listen 80; server_name api.yourdomain.com; # 改成你的域名或公网IP location / { proxy_pass http://host-gateway:8080; 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; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_connect_timeout 60s; proxy_read_timeout 60s; proxy_send_timeout 60s; } } EOF |
Docker Compose 文件
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
cat > /root/apps/nginx-proxy/docker-compose.yml << 'EOF' version: '3.8' services: nginx: image: nginx:alpine container_name: nginx-proxy ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./conf.d:/etc/nginx/conf.d:ro - ./ssl:/etc/nginx/ssl:ro - ./logs:/var/log/nginx extra_hosts: - "host-gateway:host-gateway" restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" EOF |
拉取镜像并启动
|
1 2 |
cd /root/apps/nginx-proxy docker compose up -d |
验证
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# 查看容器状态 docker compose ps # 测试配置是否正确 docker exec nginx-proxy nginx -t # 测试访问 curl http://localhost # 应该返回:{"status":"ok","message":"nginx proxy is running"} curl http://localhost/health # 应该返回:healthy |
域名相关
DNS 解析配置
- 域名管理后台(在哪买的域名就去哪配),添加以下
A记录:
| 主机记录 | 记录类型 | 记录值 |
@ |
A |
服务器公网 IP |
www |
A |
服务器公网 IP |
api |
A |
服务器公网 IP |
- 这样就有了三个可用的域名,全部指向你的服务器
qqtest.com→ 主站www.qqtest.com→ 主站api.qqtest.com→API服务
- 以后要加新服务,再加一条
A记录就行- 如果服务器在国内,域名需要完成
ICP备案才能正常访问
- 如果服务器在国内,域名需要完成
把域名配置到 Nginx
- 把域名用到
nginx上 - 修改默认配置
|
1 2 3 4 5 6 7 8 |
cat > /root/apps/nginx-proxy/conf.d/default.conf << 'EOF' # 拒绝通过 IP 直接访问(安全) server { listen 80 default_server; server_name _; return 444; } EOF |
- 配置主站
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
cat > /root/apps/nginx-proxy/conf.d/www.conf << 'EOF' server { listen 80; server_name qqtest.com www.qqtest.com; # 暂时返回一个欢迎页,以后可以改成代理前端服务 location / { return 200 '<!DOCTYPE html> <html> <head><meta charset="utf-8"><title>qqtest.com</title></head> <body><h1>Welcome to qqtest.com</h1><p>Site is running.</p></body> </html>'; add_header Content-Type text/html; } location /health { return 200 'healthy'; add_header Content-Type text/plain; } } EOF |
- 配置
API子域名
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
cat > /root/apps/nginx-proxy/conf.d/api.conf << 'EOF' server { listen 80; server_name api.qqtest.com; location / { proxy_pass http://host-gateway:8080; 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; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_connect_timeout 60s; proxy_read_timeout 60s; proxy_send_timeout 60s; } } EOF |
- 检查并重载
nginx
|
1 2 3 4 5 |
# 测试配置是否正确 docker exec nginx-proxy nginx -t # 重载配置 docker exec nginx-proxy nginx -s reload |
Mysql容器
目录结构
data/—MySQL数据持久化(容器删了数据还在)conf/— 自定义配置logs/— 日志
|
1 2 3 |
mkdir -p /root/apps/mysql/data mkdir -p /root/apps/mysql/conf mkdir -p /root/apps/mysql/logs |
自定义配置
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
cat > /root/apps/mysql/conf/my.cnf << 'EOF' [mysqld] # 字符集 character-set-server = utf8mb4 collation-server = utf8mb4_unicode_ci # 最大连接数 max_connections = 200 # 默认时区(中国) default-time-zone = '+08:00' # 日志 slow_query_log = 1 slow_query_log_file = /var/log/mysql/slow.log long_query_time = 2 # 禁止域名解析(加快连接速度) skip-name-resolve # 默认认证插件(兼容旧客户端) default_authentication_plugin = mysql_native_password [client] default-character-set = utf8mb4 [mysql] default-character-set = utf8mb4 EOF |
Docker Compose 文件
- 上面的
MYSQL_ROOT_PASSWORD、MYSQL_USER、MYSQL_PASSWORD改成自己的密码
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
cat > /root/apps/mysql/docker-compose.yml << 'EOF' version: '3.8' services: mysql: image: mysql:8.0 container_name: mysql ports: - "3306:3306" volumes: # 数据持久化 - ./data:/var/lib/mysql # 自定义配置 - ./conf/my.cnf:/etc/mysql/conf.d/my.cnf:ro # 日志 - ./logs:/var/log/mysql environment: # !!!请修改为你自己的密码!!! MYSQL_ROOT_PASSWORD: YourStrongPassword123! # 自动创建一个数据库 MYSQL_DATABASE: app_db # 创建一个普通用户(用于应用连接,不用 root) MYSQL_USER: app_user MYSQL_PASSWORD: AppUserPassword123! TZ: Asia/Shanghai command: --default-authentication-plugin=mysql_native_password restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" EOF |
拉取镜像并启动
|
1 2 3 4 |
cd /root/apps/mysql # 启动(第一次会自动拉取镜像并初始化数据库,需要等一两分钟) docker compose up -d |
查看启动状态
- 看到类似
ready for connections. Version: '8.0.xx' socket: '/var/run/mysqld/mysqld.sock' port: 3306就说明启动成功了 - 按
Ctrl+C退出日志
|
1 2 3 4 5 |
# 查看容器状态 docker compose ps # 查看启动日志(确认没有报错) docker compose logs -f |
验证 MySQL 能正常使用
- 输入设置的
MYSQL_ROOT_PASSWORD,进入后测试:
|
1 2 |
# 进入 MySQL 容器内部 docker exec -it mysql mysql -u root -p |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
-- 查看数据库 SHOW DATABASES; -- 应该能看到 app_db USE app_db; -- 查看字符集是否正确 SHOW VARIABLES LIKE 'character_set%'; -- 查看时区 SELECT NOW(); -- 退出 EXIT; |
限制远程 root 登录
|
1 2 3 4 5 6 |
docker exec -it mysql mysql -u root -p -- 只允许 root 从本地登录 DELETE FROM mysql.user WHERE User='root' AND Host NOT IN ('localhost', '127.0.0.1'); FLUSH PRIVILEGES; EXIT; |
防火墙限制 3306 端口
- 如果你不需要从外部直接连
MySQL(推荐,只让容器内部和宿主机访问)
|
1 |
# 修改 docker-compose.yml,把 ports 改为只绑定本机 |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
cat > /root/apps/mysql/docker-compose.yml << 'EOF' version: '3.8' services: mysql: image: mysql:8.0 container_name: mysql ports: # 只绑定本机,外部无法直接访问 - "127.0.0.1:3306:3306" volumes: - ./data:/var/lib/mysql - ./conf/my.cnf:/etc/mysql/conf.d/my.cnf:ro - ./logs:/var/log/mysql environment: MYSQL_ROOT_PASSWORD: YourStrongPassword123! MYSQL_DATABASE: app_db MYSQL_USER: app_user MYSQL_PASSWORD: AppUserPassword123! TZ: Asia/Shanghai command: --default-authentication-plugin=mysql_native_password restart: unless-stopped logging: driver: json-file options: max-size: "10m" max-file: "3" EOF |
重新启动
|
1 2 3 4 |
# 重新启动使配置生效 cd /root/apps/mysql docker compose down docker compose up -d |
新增服务的流程
- 流程
|
1 2 3 4 5 |
# 1. 在 conf.d 下新建一个配置文件 vim /root/apps/nginx-proxy/conf.d/新服务名.conf # 2. 重载 Nginx docker exec nginx-proxy nginx -t && docker exec nginx-proxy nginx -s reload |
- 示例
- 比如以后部署了一个后台管理系统跑在
3000端口 - 同时去
DNS后台加一条admin的A记录指向服务器IP就行 - 每个服务一个子域名,互不干扰
- 比如以后部署了一个后台管理系统跑在
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
cat > /root/apps/nginx-proxy/conf.d/admin.conf << 'EOF' server { listen 80; server_name admin.qqtest.com; location / { proxy_pass http://host-gateway:3000; 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; } } EOF docker exec nginx-proxy nginx -t && docker exec nginx-proxy nginx -s reload |
日常操作速查
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
cd /root/apps/nginx-proxy # 新增/修改代理配置后重载 docker exec nginx-proxy nginx -t && docker exec nginx-proxy nginx -s reload # 查看实时日志 tail -f logs/access.log # 重启 docker compose restart # 停止 docker compose down # 更新 Nginx 镜像版本 docker compose pull docker compose up -d |
问题
服务器拉 Docker Hub 镜像超时
- 配置镜像加速
- 第一个是腾讯云内网加速
- 后面两个是备用公共加速源
|
1 2 3 4 5 6 7 8 9 10 11 |
mkdir -p /etc/docker cat > /etc/docker/daemon.json << 'EOF' { "registry-mirrors": [ "https://mirror.ccs.tencentyun.com", "https://docker.1ms.run", "https://docker.xuanyuan.me" ] } EOF |
- 重启
Docker使配置生效
|
1 2 |
systemctl daemon-reload systemctl restart docker |
- 验证加速是否生效
- 能看到你配置的镜像地址就说明生效了
|
1 |
docker info | grep -A 5 "Registry Mirrors" |
- 重新拉取
Nginx并启动
|
1 2 |
cd /root/apps/nginx-proxy docker compose up -d |
服务器pull代码失败
- 服务器上生成
SSH密钥
|
1 2 |
ssh-keygen -t ed25519 -C "your-email@example.com" # 一路回车,不设密码 |
- 查看并复制公钥
|
1 |
cat ~/.ssh/id_ed25519.pub |
- 添加到
githubSettings→SSH and GPG Keys→New SSH Key→ 粘贴 →Add
- 测试连接
|
1 2 3 4 5 |
# Gitee ssh -T git@gitee.com # GitHub ssh -T git@github.com |
阿里云镜像源访问不了
- 先测试哪个源能用:
|
1 |
docker pull golang:1.22-alpine |
- 如果能拉下来,说明之前配的镜像加速源已经生效了,直接把
Dockerfile里的阿里云前缀去掉就行:
|
1 2 |
sed -i 's|registry.cn-hangzhou.aliyuncs.com/library/golang|golang|g' Dockerfile sed -i 's|registry.cn-hangzhou.aliyuncs.com/library/alpine|alpine|g' Dockerfile |
api容器连不上 mysql 容器
- 先排查
MySQL是否正常运行:- 发现在运行
|
1 2 |
# 看 MySQL 容器是否在跑 docker ps | grep mysql |
- 如果
MySQL在运行,问题出在网络连接方式上- 如果显示
127.0.0.1:3306,说明MySQL只绑定了本机回环地址 - 容器内的
host-gateway走的不是127.0.0.1,所以连不上
- 如果显示
|
1 2 |
# 看 MySQL 监听的是什么地址 docker port mysql |
- 解决
- 让两个容器共用
Docker网络 - 详见两个容器共用
Docker网络
- 让两个容器共用
两个容器共用 Docker 网络
- 创建一个共享网络
|
1 |
docker network create app-network |
- 修改
MySQL的docker-compose.yml- 添加了
networks - 重启
mysql
- 添加了
|
1 |
vim /root/apps/mysql/docker-compose.yml |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
services: mysql: image: mysql:8.0 container_name: mysql ports: - "127.0.0.1:3306:3306" volumes: - ./data:/var/lib/mysql - ./conf/my.cnf:/etc/mysql/conf.d/my.cnf:ro - ./logs:/var/log/mysql environment: MYSQL_ROOT_PASSWORD: YourStrongPassword123! MYSQL_DATABASE: app_db MYSQL_USER: app_user MYSQL_PASSWORD: AppUserPassword123! TZ: Asia/Shanghai command: --default-authentication-plugin=mysql_native_password restart: unless-stopped networks: - app-network networks: app-network: external: true |
|
1 2 3 |
cd /root/apps/mysql docker compose down docker compose up -d |
- 修改
Go API的docker-compose.yml- 修改
DB_HOST - 添加了
networks - 重新构建启动
- 修改
|
1 |
vim /root/apps/go_api_service/docker-compose.yml |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
services: go-api: build: context: . dockerfile: Dockerfile container_name: go-api ports: - "127.0.0.1:8080:8080" environment: # 关键:用 MySQL 容器名作为 host DB_HOST: mysql DB_PORT: "3306" DB_USER: app_user DB_PASSWORD: AppUserPassword123! DB_NAME: app_db SERVER_PORT: "8080" SERVER_ENV: production SERVER_NAME: go-api-server TZ: Asia/Shanghai restart: unless-stopped networks: - app-network networks: app-network: external: true |
|
1 2 |
cd /root/apps/go_api_service docker compose up -d --build |
请求显示502 Bad Gateway
502说明Nginx收到了请求,但转发到后端失败了- 在服务器可以访问
|
1 2 3 4 5 |
# 1. Go API 容器在跑吗? docker ps | grep go-api # 2. Go API 能直接访问吗? curl http://127.0.0.1:8080/api/health |
- 第
2步返回正常,说明问题在Nginx转发到Go API这一段- 之前配置里用的是
proxy_pass http://host-gateway:8080 - 但
Nginx容器可能没加入app-network,也解析不了host-gateway
- 之前配置里用的是
- 修改
Nginx的docker-compose.yml- 添加了
networks
- 添加了
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
cat > /root/apps/nginx-proxy/docker-compose.yml << 'EOF' services: nginx: image: nginx:alpine container_name: nginx-proxy ports: - "80:80" - "443:443" volumes: - ./nginx.conf:/etc/nginx/nginx.conf:ro - ./conf.d:/etc/nginx/conf.d:ro - ./ssl:/etc/nginx/ssl:ro - ./logs:/var/log/nginx restart: unless-stopped networks: - app-network logging: driver: json-file options: max-size: "10m" max-file: "3" networks: app-network: external: true EOF |
- 修改
api.conf,用容器名代替host-gatewayproxy_pass
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
cat > /root/apps/nginx-proxy/conf.d/api.conf << 'EOF' server { listen 80; server_name api.qqtest.com; location / { proxy_pass http://go-api:8080; 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; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_connect_timeout 60s; proxy_read_timeout 60s; proxy_send_timeout 60s; } } EOF |
- 同时修改
Go API的端口绑定- 既然走
Docker网络了,Go API就不需要绑定宿主机端口了
- 既然走
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
cat > /root/apps/go_api_service/docker-compose.yml << 'EOF' services: go-api: build: context: . dockerfile: Dockerfile container_name: go-api expose: - "8080" environment: DB_HOST: mysql DB_PORT: "3306" DB_USER: app_user DB_PASSWORD: AppUserPassword123! DB_NAME: app_db SERVER_PORT: "8080" SERVER_ENV: production SERVER_NAME: go-api-server TZ: Asia/Shanghai restart: unless-stopped networks: - app-network networks: app-network: external: true EOF |
声明:本文为原创文章,版权归Aet所有,欢迎分享本文,转载请保留出处!
你可能也喜欢
- ♥ 表_唯一约束、非空约束10/26
- ♥ 表_约束-主键10/26
- ♥ Go 基础:第三篇04/19
- ♥ 表_约束-外键10/27
- ♥ Macos网络信息相关06/06
- ♥ 表_修改表结构10/26