Commit 09766d68 authored by xiezhi's avatar xiezhi

Initial commit: C++ 12.2.0 HTTP server template

- Add hello_world.cpp with HTTP server implementation
- Add Dockerfile for containerization
- Add docker-entrypoint.sh for deployment
- Add Makefile for build automation
- Add .eazy configuration file
- Add .resource directory with dev config
- Add comprehensive README.md
- Support environment variable port configuration
- Ready for production deployment
parents
{
"version": "1.0.0",
"name": "C++ 12.2.0 HTTP服务器",
"tags": ["cpp", "c++", "http", "web", "server", "native"],
"description": "基于C++ 12.2.0的简单HTTP服务器应用",
"init_commands": ["make install"],
"start_commands": ["make run"],
"stop_commands": ["make stop"],
"mapping_ports": {
"APP_PORT_1": 8000,
"APP_PORT_2": 8001,
"APP_PORT_3": 8002,
"APP_PORT_4": 8003
},
"deploy": [
{
"image_name": "cpp12.2.0-hello-world",
"app_access_entry": true,
"ports": [
{
"name": "APP_PORT_1",
"main_port": true,
"inner_access_env_key": "API_URL",
"open_access": true,
"open_access_env_key": "API_DOMAIN"
},
{
"name": "APP_PORT_2",
"main_port": false,
"inner_access_env_key": null,
"open_access": false,
"open_access_env_key": null
}
],
"docker_file_dir": "./",
"deploy_resources": {
"cpu_limit": 0.5,
"memory_limit": 2,
"storage_limit": 1
}
}
]
}
# 依赖文件
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# 环境变量文件
.env
.env.local
.env.development.local
.env.test.local
.env.production.local
# 构建输出
dist/
build/
out/
# 日志文件
*.log
# 运行时数据
pids
*.pid
*.seed
*.pid.lock
# 覆盖率目录
coverage/
.nyc_output
# 依赖目录
jspm_packages/
# 可选的npm缓存目录
.npm
# 可选的eslint缓存
.eslintcache
# 可选的REPL历史
.node_repl_history
# 输出目录
*.tgz
# Yarn完整性文件
.yarn-integrity
# dotenv环境变量文件
.env
# 编辑器目录和文件
.idea/
*.swp
*.swo
*~
# 操作系统生成的文件
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
# 临时文件
*.tmp
*.temp
# 备份文件
*.bak
*.backup
{
"recommendations": [
"pomdtr.excalidraw-editor",
"editorconfig.editorconfig",
"lokalise.i18n-ally",
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
"ms-vscode.cpptools-themes",
"formulahendry.code-runner"
]
}
\ No newline at end of file
# 使用C++ 12.2.0作为基础镜像
FROM hb.eazytec-cloud.com/eazytec/eazydevelop-cpp:ubuntu22.04-cpp12.2.0-latest
# 设置工作目录
WORKDIR /app
# 复制源代码
COPY . ./
# 设置启动脚本权限
RUN chmod +x docker-entrypoint.sh
# 设置环境变量
ENV APP_PORT_1=8000
# 暴露端口
EXPOSE $APP_PORT_1
# 运行程序(让entrypoint脚本处理编译和运行)
ENTRYPOINT ["./docker-entrypoint.sh", "production"]
# 变量定义
APP_NAME = cpp12.2.0-hello-world
CPP_VERSION = 12.2.0
BUILD_DIR = build
BINARY_FILE = $(BUILD_DIR)/hello_world
APP_PORT = $(or $(APP_PORT_1),8000)
LOG_FILE = $(abspath $(dir $(lastword $(MAKEFILE_LIST))))/.logs/app.log
PID_FILE = $(abspath $(dir $(lastword $(MAKEFILE_LIST))))/.logs/app.pid
# C++编译器设置
CXX = g++
CXXFLAGS = -Wall -Wextra -std=c++17 -O2
LDFLAGS = -pthread
# 默认目标
.PHONY: all
all: install
# 安装命令
.PHONY: install
install:
@echo "检查 C++ 编译器版本..."
@$(CXX) --version
@echo "检查项目是否已编译..."
@if [ ! -f "$(BINARY_FILE)" ]; then \
echo "正在编译C++源代码..."; \
mkdir -p $(BUILD_DIR); \
$(CXX) $(CXXFLAGS) -o $(BINARY_FILE) hello_world.cpp $(LDFLAGS); \
echo "✅ C++源代码编译完成"; \
else \
echo "✅ C++源代码已编译"; \
fi
@echo "✅ 安装完成!C++项目已准备就绪"
# 运行命令(后台运行HTTP服务器)
.PHONY: run
run: install
@echo "正在启动 C++ HTTP 服务器..."
@mkdir -p $(dir $(LOG_FILE))
@if [ -f "$(PID_FILE)" ]; then \
echo "服务器已在运行中,PID: $$(cat $(PID_FILE))"; \
exit 1; \
fi
@echo "启动服务器在端口 $(APP_PORT)..."
@APP_PORT_1=$(APP_PORT) nohup $(BINARY_FILE) > $(LOG_FILE) 2>&1 & echo $$! > $(PID_FILE)
@echo "✅ C++ HTTP 服务器已启动,PID: $$(cat $(PID_FILE))"
@echo "服务器运行在: http://localhost:$(APP_PORT)/"
@echo "查看日志: tail -f $(LOG_FILE)"
# 停止命令
.PHONY: stop
stop: kill
# 强制杀死所有相关C++进程
.PHONY: kill
kill:
@echo "正在查找并杀死所有相关的C++进程..."
@PIDS=$$(ps aux | grep -E "hello_world|$(APP_NAME)" | grep -v grep | awk '{print $$2}'); \
if [ -n "$$PIDS" ]; then \
echo "找到相关进程: $$PIDS"; \
for PID in $$PIDS; do \
echo "正在杀死进程 $$PID..."; \
kill -9 $$PID 2>/dev/null || true; \
done; \
sleep 1; \
echo "✅ 所有相关C++进程已被强制停止"; \
else \
echo "未找到相关的C++进程"; \
fi
@rm -f $(PID_FILE)
@echo "✅ 强制停止操作完成"
# 重启命令
.PHONY: restart
restart: stop run
# 查看状态
.PHONY: status
status:
@if [ -f "$(PID_FILE)" ]; then \
PID=$$(cat $(PID_FILE)); \
if ps -p $$PID > /dev/null 2>&1; then \
echo "✅ 服务器正在运行,PID: $$PID"; \
echo "端口: $(APP_PORT)"; \
echo "日志: $(LOG_FILE)"; \
else \
echo "❌ 服务器未运行(PID文件存在但进程不存在)"; \
rm -f $(PID_FILE); \
fi; \
else \
echo "❌ 服务器未运行"; \
fi
# 开发模式运行
.PHONY: dev
dev:
@echo "开发模式运行C++程序..."
@APP_PORT_1=$(APP_PORT) $(BINARY_FILE)
# 调试模式编译
.PHONY: debug
debug:
@echo "调试模式编译C++程序..."
@mkdir -p $(BUILD_DIR)
@$(CXX) $(CXXFLAGS) -g -DDEBUG -o $(BINARY_FILE) hello_world.cpp $(LDFLAGS)
@echo "✅ 调试版本编译完成"
# 清理编译文件
.PHONY: clean
clean:
@echo "清理编译文件..."
rm -rf $(BUILD_DIR)
@echo "清理完成!"
# 显示帮助信息
.PHONY: help
help:
@echo "C++ 12.2.0 HTTP 服务器项目"
@echo ""
@echo "可用命令:"
@echo " make install - 安装依赖并编译项目"
@echo " make run - 启动HTTP服务器(后台运行)"
@echo " make stop - 停止HTTP服务器(优雅停止)"
@echo " make kill - 强制杀死所有相关C++进程"
@echo " make restart - 重启HTTP服务器"
@echo " make status - 查看服务器状态"
@echo " make dev - 开发模式运行"
@echo " make debug - 调试模式编译"
@echo " make clean - 清理编译文件"
@echo " make help - 显示此帮助信息"
@echo ""
@echo "示例:"
@echo " make run # 启动服务器"
@echo " make status # 查看状态"
@echo " make stop # 优雅停止服务器"
@echo " make kill # 强制停止所有相关进程"
@echo " make restart # 重启服务器"
@echo " make dev # 开发模式运行"
@echo " make debug # 编译调试版本"
@echo ""
@echo "环境变量:"
@echo " APP_PORT_1 - 服务器端口(默认: 8000)"
# C++ 12.2.0 HTTP 服务器模板
一个基于 C++ 12.2.0 的简单 HTTP 服务器应用模板,支持环境变量配置和 Docker 容器化部署。
## 🚀 项目特性
- **C++ 12.2.0**: 使用最新的 C++ 语言版本
- **HTTP 服务器**: 提供简单的 HTTP 服务
- **环境变量配置**: 支持通过环境变量配置端口
- **Docker 支持**: 完整的容器化部署方案
- **Makefile 构建**: 便捷的构建和运行命令
- **生产就绪**: 支持开发和生产环境
- **原生性能**: 高性能的 C++ 语言实现
## 📁 项目结构
```
c-plus12.2.0-template/
├── hello_world.cpp # 主程序文件
├── Dockerfile # Docker 镜像构建文件
├── docker-entrypoint.sh # Docker 启动脚本
├── Makefile # 构建脚本
├── .eazy # 应用配置文件
├── .resource/
│ ├── resource_dev.json # 开发环境资源配置
│ └── resource_deploy.json # 部署环境资源配置
├── .vscode/ # VS Code 配置
└── README.md # 项目说明文档
```
## 🛠️ 环境要求
- C++ 12.2.0 或更高版本 (GCC)
- Docker (可选,用于容器化部署)
- Make (可选,用于使用 Makefile 命令)
## 📦 快速开始
### 1. 克隆项目
```bash
git clone <repository-url>
cd c-plus12.2.0-template
```
### 2. 使用 Makefile 运行
```bash
# 安装依赖并编译
make install
# 启动服务器(后台运行)
make run
# 开发模式运行
make dev
# 调试模式编译
make debug
# 查看服务器状态
make status
# 停止服务器
make stop
# 重启服务器
make restart
# 清理编译文件
make clean
# 查看帮助
make help
```
### 3. 直接使用 GCC 命令
```bash
# 编译程序
g++ -Wall -Wextra -std=c++17 -O2 -o hello_world hello_world.cpp -pthread
# 运行程序
./hello_world
```
## ⚙️ 配置说明
### 环境变量
| 变量名 | 默认值 | 说明 |
|--------|--------|------|
| `APP_PORT_1` | 8000 | HTTP 服务器监听端口 |
| `PORT` | 8000 | 兼容旧版本的环境变量 |
### 端口配置
应用支持多个端口配置:
- `APP_PORT_1`: 主端口 (默认: 8000)
- `APP_PORT_2`: 备用端口 (默认: 8001)
- `APP_PORT_3`: 备用端口 (默认: 8002)
- `APP_PORT_4`: 备用端口 (默认: 8003)
## 🐳 Docker 部署
### 构建镜像
```bash
docker build -t c-plus12.2.0-hello-world .
```
### 运行容器
```bash
# 使用默认端口
docker run -p 8000:8000 c-plus12.2.0-hello-world
# 使用自定义端口
docker run -p 9000:9000 -e APP_PORT_1=9000 c-plus12.2.0-hello-world
```
### 开发环境运行
```bash
# 开发模式(直接运行源码)
docker run -p 8000:8000 c-plus12.2.0-hello-world development
```
## 🔧 开发指南
### 项目结构说明
- `hello_world.cpp`: 主程序入口,包含 HTTP 服务器逻辑
- `docker-entrypoint.sh`: Docker 启动脚本,支持开发和生产环境
- `Makefile`: 构建和运行脚本
- `.eazy`: 应用配置文件,包含部署信息
### 添加新功能
1.`hello_world.cpp` 中添加新的路由处理函数
2. 修改 HTTP 响应处理逻辑
3. 重新编译和运行
示例:
```cpp
// 添加新的响应处理
std::string custom_response = "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: 15\r\n"
"Connection: close\r\n"
"\r\n"
"Custom Response!";
```
### 环境变量使用
在代码中获取环境变量:
```cpp
const char* env_port = std::getenv("APP_PORT_1");
if (env_port != nullptr) {
int port = std::atoi(env_port);
// 使用端口
}
```
## 📊 监控和日志
### 查看日志
```bash
# 使用 Makefile 查看日志
tail -f .logs/app.log
# 查看服务器状态
make status
```
### 健康检查
访问以下端点进行健康检查:
- `GET /`: 返回 "Hello, World!"
## 🚀 部署到生产环境
### 使用 Docker
1. 构建生产镜像:
```bash
docker build -t c-plus12.2.0-hello-world:latest .
```
2. 运行生产容器:
```bash
docker run -d \
--name cpp-app \
-p 8000:8000 \
-e APP_PORT_1=8000 \
c-plus12.2.0-hello-world:latest
```
### 使用 Makefile
```bash
# 生产环境运行
make run
```
## 🔍 故障排除
### 常见问题
1. **端口被占用**
```bash
# 查看端口占用
lsof -i :8000
# 停止占用端口的进程
make stop
```
2. **编译错误**
```bash
# 清理并重新编译
make clean
make install
```
3. **Docker 构建失败**
```bash
# 检查 Dockerfile 语法
docker build --no-cache -t test .
```
### 调试模式
```bash
# 调试模式编译
make debug
# 开发模式运行(显示详细日志)
make dev
# 直接运行 C++ 程序
./hello_world
```
## 📝 API 文档
### 端点列表
| 方法 | 路径 | 描述 | 响应 |
|------|------|------|------|
| GET | `/` | 健康检查 | "Hello, World!" |
### 响应格式
所有响应都是纯文本格式。
## 🎯 性能特性
- **原生性能**: 使用 C++ 语言实现,性能优异
- **内存效率**: 低内存占用
- **现代C++**: 使用 C++17 标准
- **线程安全**: 支持多线程处理
## 🤝 贡献指南
1. Fork 项目
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 打开 Pull Request
## 📄 许可证
本项目采用 MIT 许可证 - 查看 [LICENSE](LICENSE) 文件了解详情。
## 📞 支持
如果您遇到任何问题或有任何建议,请:
1. 查看 [故障排除](#故障排除) 部分
2. 创建 [Issue](../../issues)
3. 联系维护者
---
**注意**: 这是一个模板项目,您可以根据实际需求进行修改和扩展。
#!/bin/bash
# 设置错误时退出
set -e
# 获取环境变量,默认为production
app_env=${1:-production}
# 定义构建目标
build_target="hello_world"
# 获取端口号,优先使用环境变量
APP_PORT=${APP_PORT_1:-8000}
# 开发环境命令
dev_commands() {
echo "🚀 运行开发环境命令..."
echo "📝 使用端口: $APP_PORT"
echo "🔧 直接运行C++程序..."
APP_PORT_1=$APP_PORT ./$build_target
}
# 生产环境命令
prod_commands() {
echo "🚀 运行生产环境命令..."
echo "📝 使用端口: $APP_PORT"
# 检查是否已经编译过
if [ ! -f "$build_target" ]; then
echo "🔨 编译C++程序..."
g++ -Wall -Wextra -std=c++17 -O2 -o $build_target hello_world.cpp -pthread
echo "✅ 编译完成"
else
echo "✅ 程序已编译,直接运行"
fi
# 运行编译后的程序
echo "🎯 启动HTTP服务器..."
APP_PORT_1=$APP_PORT ./$build_target
}
# 显示启动信息
echo "=========================================="
echo "⚡ C++ 12.2.0 HTTP 服务器启动脚本"
echo "=========================================="
echo "环境: $app_env"
echo "端口: $APP_PORT"
echo "时间: $(date)"
echo "=========================================="
# 根据环境变量决定运行模式
if [ "$app_env" = "production" ] || [ "$app_env" = "prod" ]; then
echo "🏭 检测到生产环境"
prod_commands
else
echo "🛠️ 检测到开发环境"
dev_commands
fi
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
/**
* 从环境变量获取端口号
* 优先使用APP_PORT_1,如果不存在则使用PORT,最后使用默认值8000
* @return 端口号
*/
int get_port() {
const char* env_port = std::getenv("APP_PORT_1");
if (env_port != nullptr) {
return std::atoi(env_port);
}
// 兼容旧的PORT环境变量
env_port = std::getenv("PORT");
if (env_port != nullptr) {
return std::atoi(env_port);
}
// 默认端口8000
return 8000;
}
int main() {
// 获取端口号
int port = get_port();
// Create socket
int server_fd = socket(AF_INET, SOCK_STREAM, 0);
if (server_fd < 0) {
std::cerr << "Failed to create socket" << std::endl;
return 1;
}
// Set socket options
int opt = 1;
if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) {
std::cerr << "Failed to set socket options" << std::endl;
return 1;
}
// Configure address
struct sockaddr_in address;
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY; // 0.0.0.0
address.sin_port = htons(port);
// Bind socket
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
std::cerr << "Failed to bind to port" << std::endl;
return 1;
}
// Listen for connections
if (listen(server_fd, 3) < 0) {
std::cerr << "Listen failed" << std::endl;
return 1;
}
std::cout << "Server listening on 0.0.0.0:" << port << std::endl;
while (true) {
// Accept connection
int socket = accept(server_fd, NULL, NULL);
if (socket < 0) {
std::cerr << "Accept failed" << std::endl;
continue;
}
// Prepare HTTP response
std::string hello = "Hello, World!";
std::string http_response =
"HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n"
"Content-Length: " + std::to_string(hello.length()) + "\r\n"
"Connection: close\r\n"
"\r\n" +
hello;
// Send response
send(socket, http_response.c_str(), http_response.length(), 0);
// Close connection
close(socket);
}
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment