From 562fa553b77a96dd98e670d362f12d425144e0d6 Mon Sep 17 00:00:00 2001 From: Ryan6981 <995559618@qq.com> Date: Wed, 16 Oct 2024 17:08:07 +0800 Subject: [PATCH] up --- docker-compose.yml | 46 ++++++++++++++++++++++++++++++++ redme.txt | 42 ++++++++++++++++++++++++++++++ rust-compiler/Dockerfile | 28 ++++++++++++++++++++ rust-compiler/main.rs | 52 +++++++++++++++++++++++++++++++++++++ web-server/Dockerfile | 26 +++++++++++++++++++ web-server/app.py | 28 ++++++++++++++++++++ web-server/requirements.txt | 2 ++ web-ui/Dockerfile | 19 ++++++++++++++ web-ui/index.html | 33 +++++++++++++++++++++++ 9 files changed, 276 insertions(+) create mode 100644 docker-compose.yml create mode 100644 redme.txt create mode 100644 rust-compiler/Dockerfile create mode 100644 rust-compiler/main.rs create mode 100644 web-server/Dockerfile create mode 100644 web-server/app.py create mode 100644 web-server/requirements.txt create mode 100644 web-ui/Dockerfile create mode 100644 web-ui/index.html diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..d96bb2a --- /dev/null +++ b/docker-compose.yml @@ -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: \ No newline at end of file diff --git a/redme.txt b/redme.txt new file mode 100644 index 0000000..2353749 --- /dev/null +++ b/redme.txt @@ -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编译环境容器进行编译,并将结果返回给前端显示。 \ No newline at end of file diff --git a/rust-compiler/Dockerfile b/rust-compiler/Dockerfile new file mode 100644 index 0000000..da1070b --- /dev/null +++ b/rust-compiler/Dockerfile @@ -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"] \ No newline at end of file diff --git a/rust-compiler/main.rs b/rust-compiler/main.rs new file mode 100644 index 0000000..d4e5146 --- /dev/null +++ b/rust-compiler/main.rs @@ -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) -> Result, 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); +} \ No newline at end of file diff --git a/web-server/Dockerfile b/web-server/Dockerfile new file mode 100644 index 0000000..36fe1e9 --- /dev/null +++ b/web-server/Dockerfile @@ -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"] \ No newline at end of file diff --git a/web-server/app.py b/web-server/app.py new file mode 100644 index 0000000..3c787cd --- /dev/null +++ b/web-server/app.py @@ -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) \ No newline at end of file diff --git a/web-server/requirements.txt b/web-server/requirements.txt new file mode 100644 index 0000000..c94490a --- /dev/null +++ b/web-server/requirements.txt @@ -0,0 +1,2 @@ +Flask==2.0.1 +requests==2.25.1 \ No newline at end of file diff --git a/web-ui/Dockerfile b/web-ui/Dockerfile new file mode 100644 index 0000000..c3729c6 --- /dev/null +++ b/web-ui/Dockerfile @@ -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 && \ +# rm -rf /var/cache/apk/* + +# 暴露 80 端口 +EXPOSE 80 + +# 启动 Nginx +CMD ["nginx", "-g", "daemon off;"] \ No newline at end of file diff --git a/web-ui/index.html b/web-ui/index.html new file mode 100644 index 0000000..3eacc16 --- /dev/null +++ b/web-ui/index.html @@ -0,0 +1,33 @@ + + + + +Rust Online Compiler + + + +

Rust Online Compiler

+
+ +

+
+
+
+
\ No newline at end of file