This commit is contained in:
Ryan6981 2024-10-16 17:08:07 +08:00
commit 562fa553b7
9 changed files with 276 additions and 0 deletions

46
docker-compose.yml Normal file
View File

@ -0,0 +1,46 @@
version: '3'
services:
rabbitmq:
image: rabbitmq:3-management
container_name: rabbitmq
networks:
- rustnet
rust-compiler:
build:
context: ./rust-compiler
dockerfile: Dockerfile
container_name: rust-compiler
networks:
- rustnet
environment:
- RABBITMQ_HOST=rabbitmq
web-server:
build:
context: ./web-server
dockerfile: Dockerfile
container_name: web-server
ports:
- "5000:5000"
depends_on:
- rust-compiler
- rabbitmq
networks:
- rustnet
environment:
- RABBITMQ_HOST=rabbitmq
web-ui:
build:
context: ./web-ui
dockerfile: Dockerfile
container_name: web-ui
ports:
- "80:80"
networks:
- rustnet
networks:
rustnet:

42
redme.txt Normal file
View File

@ -0,0 +1,42 @@
你的需求是将Rust编译环境、后端Web服务器如Flask和前端Web UI分别放在三个不同的Docker镜像中。我们将使用Docker Compose来管理这些服务并确保它们能够相互通信。
项目结构
假设你的项目结构如下:
project-root/
├── docker-compose.yml
├── rust-compiler/
│ ├── Dockerfile
│ └── main.rs
├── web-server/
│ ├── Dockerfile
│ ├── app.py
│ └── requirements.txt
└── web-ui/
├── Dockerfile
└── index.html
5. 构建并运行Docker Compose
现在,你可以使用 docker-compose 来构建和运行整个应用:
bash
深色版本
docker-compose up --build
这样你将有三个独立的Docker容器
rust-compiler包含Rust编译环境的服务。
web-server包含Flask Web服务器的服务。
web-ui包含前端Web界面的服务。
用户可以通过浏览器访问 http://localhost 来使用前端Web界面输入Rust代码点击“Compile and Run”按钮然后查看编译和运行的结果。后端的Flask应用会将代码发送到Rust编译环境容器进行编译并将结果返回给前端显示。

28
rust-compiler/Dockerfile Normal file
View File

@ -0,0 +1,28 @@
# 使用官方的Rust镜像作为基础
FROM rust:latest
# 设置工作目录
WORKDIR /usr/src/rust-compiler
# 更新源列表并安装必要的依赖
RUN sed -i 's|http://deb.debian.org/debian|https://mirrors.tuna.tsinghua.edu.cn/debian|g' /etc/apt/sources.list &&
apt-get update &&
apt-get install -y --no-install-recommends curl &&
rm -rf /var/lib/apt/lists/*
# 复制编译服务代码
COPY . .
# 编译Rust程序
RUN cargo new rust-compiler-service --bin
WORKDIR /usr/src/rust-compiler/rust-compiler-service
RUN cp /usr/src/rust-compiler/main.rs .
RUN cargo build --release
# 暴露端口
EXPOSE 8080
# 启动服务
CMD ["./target/release/rust-compiler-service"]

52
rust-compiler/main.rs Normal file
View File

@ -0,0 +1,52 @@
use hyper::{Body, Request, Response, Server};
use hyper::service::{make_service_fn, service_fn};
use hyper::rt::run;
use std::fs::File;
use std::io::Write;
use std::process::Command;
use lapin::{options::*, types::FieldTable, Connection, ConnectionProperties, ExchangeKind, QueueDeclareOptions, QueueBindOptions};
async fn handle_compile(req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
let whole_body = hyper::body::to_bytes(req.into_body()).await?;
let code = String::from_utf8(whole_body.to_vec()).unwrap();
// 写入临时文件
let file_path = "/tmp/user_code.rs";
let mut file = File::create(file_path).unwrap();
file.write_all(code.as_bytes()).unwrap();
// 编译代码
let output = Command::new("rustc")
.arg(file_path)
.output()
.expect("Failed to execute rustc");
// 获取输出
let result = if output.status.success() {
// 如果编译成功,运行二进制文件
let binary_output = Command::new(&file_path.replace(".rs", ""))
.output()
.expect("Failed to run compiled binary");
format!("Compiled successfully:\n{}", String::from_utf8_lossy(&binary_output.stdout))
} else {
format!("Compilation failed:\n{}", String::from_utf8_lossy(&output.stderr))
};
// 返回结果
Ok(Response::new(Body::from(result)))
}
fn main() {
let addr = ([0, 0, 0, 0], 8080).into();
let make_svc = make_service_fn(|_conn| {
async { Ok::<_, hyper::Error>(service_fn(handle_compile)) }
});
let server = Server::bind(&addr)
.serve(make_svc);
println!("Listening on http://{}", addr);
run(server);
}

26
web-server/Dockerfile Normal file
View File

@ -0,0 +1,26 @@
# 使用官方的Python镜像作为基础
FROM python:3.8-slim
# 设置工作目录
WORKDIR /usr/src/app
# 安装系统依赖
# 更新源列表并安装必要的依赖
RUN sed -i 's|http://deb.debian.org/debian|https://mirrors.tuna.tsinghua.edu.cn/debian|g' /etc/apt/sources.list &&
apt-get update &&
apt-get install -y --no-install-recommends curl &&
rm -rf /var/lib/apt/lists/*
# 安装Python依赖
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# 复制应用程序
COPY . .
# 暴露端口
EXPOSE 5000
# 启动Flask应用
CMD ["flask", "run", "--host=0.0.0.0"]

28
web-server/app.py Normal file
View File

@ -0,0 +1,28 @@
from flask import Flask, request, jsonify
import pika
app = Flask(__name__)
# 连接到RabbitMQ
connection = pika.BlockingConnection(pika.ConnectionParameters('rabbitmq'))
channel = connection.channel()
channel.queue_declare(queue='compile_queue')
@app.route('/compile', methods=['POST'])
def compile_code():
data = request.get_json()
code = data.get('code')
# 发送编译请求到消息队列
channel.basic_publish(exchange='',
routing_key='compile_queue',
body=code)
return jsonify({'message': 'Compilation request submitted'})
@app.route('/')
def index():
return send_from_directory('../web-ui', 'index.html')
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)

View File

@ -0,0 +1,2 @@
Flask==2.0.1
requests==2.25.1

19
web-ui/Dockerfile Normal file
View File

@ -0,0 +1,19 @@
# 使用官方的 nginx:alpine 镕像作为基础镜像
FROM webdevops/nginx:latest
# 设置工作目录
WORKDIR /usr/share/nginx/html
# 复制网站内容到容器内
COPY ./html /usr/share/nginx/html
# 更新 apk 的索引并安装必要的软件包
#RUN apk update && \
# apk add --no-cache <package-name> && \
# rm -rf /var/cache/apk/*
# 暴露 80 端口
EXPOSE 80
# 启动 Nginx
CMD ["nginx", "-g", "daemon off;"]

33
web-ui/index.html Normal file
View File

@ -0,0 +1,33 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Rust Online Compiler</title>
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
</head>
<body>
<h1>Rust Online Compiler</h1>
<textarea id="codeInput" rows="10" cols="50"></textarea><br>
<button onclick="compileCode()">Compile and Run</button>
<pre id="output"></pre>
<script>
function compileCode() {
var code = $('#codeInput').val();
$.ajax({
url: '/compile',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({ code: code }),
success: function(response) {
$('#output').text(response.output);
},
error: function(error) {
console.error("Error:", error);
$('#output').text("An error occurred while compiling the code.");
}
});
}
</script>
</body>
</html>