简单的外网到内网管理服务搭建


前言

搭建一个简单的私人用服务,包括文件以及影音服务。
影音服务使用jellyfin,文件服务使用简单的flask框架编写(待完成)
能容器化就使用容器化方式搭建。

环境

1、一个内网服务器
2、一个外网服务器
已完成内网穿透

一、内网服务器搭建

安装docker

apt install docker

安装nginx代理

docker pull nginx

编写nginx.conf,首先做一个文件服务代理。

worker_processes 1;

events { worker_connections 1024; }

http {

    sendfile on;

    server {

        listen 9890;

        location / {
            root /datas/;    //文件目录位置 自定义
            autoindex on;
            autoindex_exact_size off;
            charset utf-8;
        }
    }
}  

编写Dockerfile 使用这个镜像

FROM nginx:latest
COPY nginx.conf /etc/nginx/nginx.conf

docker 构建镜像

docker build -t file-nginx:latest .

docker 把要挂载的文件目录挂载上 并且开放9890端口。

docker run  -v /datas:/datas -d -p 9890:9890 --name file-server file-nginx

jellyfin安装 (最好用容器 我太懒了)

apt install jellyfin

具体jellyfin配置挺多文章的,可以去查阅下,这里不多赘述,只是给一种思路。记得jellyfin端口就可以 我是8096端口。

二、外网服务器搭建

nginx.conf配置类似如下:
做一下内网的端口映射就行

worker_processes 1;

events { worker_connections 1024; }

http {

    sendfile on;

    server {

        listen 7080;

        location / {
            proxy_pass http://{内网ip}:8096;
            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_intercept_errors on;
        }
    }
    server {
       listen 7081;

       location / {
           proxy_pass http://{内网ip}:9890;
            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_intercept_errors on;
       }

    }

}

同样制作为镜像。这里不多赘述
容器运行如下:

docker run -d  -p 7080:7080 -p 7081:7081 --name my-nginx my-nginx

使用web服务使得访问更加便捷,使用python flask框架进行快速开发,后期使用Mysql数据库进行用户管理。代码示例如下:

from flask import Flask, render_template, request, redirect, url_for, session, flash

app = Flask(__name__)
app.secret_key = 'your_secret_key'  # 用于会话安全

# 假设的用户数据库
users = {'Username': 'password'}

@app.route('/')
def index():
    if 'username' in session:
        return redirect(url_for('dashboard'))
    return render_template('login.html')

@app.route('/login', methods=['POST'])
def login():
    username = request.form['username']
    password = request.form['password']
    if username in users and users[username] == password:
        session['username'] = username
        return redirect(url_for('dashboard'))
    else:
        flash('Invalid username or password')
        return redirect(url_for('index'))

@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect(url_for('index'))

@app.route('/dashboard')
def dashboard():
    if 'username' not in session:
        return redirect(url_for('index'))
    return render_template('dashboard.html')

if __name__ == '__main__':
    app.run(debug=True,port=80,host='0.0.0.0')

默认开放80端口,给出一个简单的html模板,templates/login.html 代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Login</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
        <h2 class="text-center">Login</h2>
        <form method="post" action="{{ url_for('login') }}">
            <div class="mb-3">
                <label for="username" class="form-label">Username</label>
                <input type="text" class="form-control" id="username" name="username" required>
            </div>
            <div class="mb-3">
                <label for="password" class="form-label">Password</label>
                <input type="password" class="form-control" id="password" name="password" required>
            </div>
            <button type="submit" class="btn btn-primary">Login</button>
        </form>
        {% with messages = get_flashed_messages() %}
            {% if messages %}
                <ul class="mt-3">
                {% for message in messages %}
                    <li class="text-danger">{{ message }}</li>
                {% endfor %}
                </ul>
            {% endif %}
        {% endwith %}
    </div>
</body>
</html>

templates/dashboard.html如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dashboard</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .service-card {
            margin-top: 20px;
        }
    </style>
</head>
<body>
    <div class="container mt-5">
        <h2 class="text-center">Dashboard</h2>
        <div class="row mt-4">
            <div class="col-md-4">
                <div class="card service-card">
                    <div class="card-body">
                        <h5 class="card-title">文件服务</h5>
                        <p class="card-text">管理你的文件和文档。</p>
                        <a href="http://{ip}:7081" class="btn btn-primary">访问文件服务</a>
                    </div>
                </div>
            </div>
            <div class="col-md-4">
                <div class="card service-card">
                    <div class="card-body">
                        <h5 class="card-title">影音服务</h5>
                        <p class="card-text">观看和管理你的视频和音频文件。</p>
                        <a href="http://{ip}:7080" class="btn btn-primary">访问影音服务</a>
                    </div>
                </div>
            </div>
            <!-- 可以根据需要添加更多服务 -->
        </div>
    </div>


    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

使用python main.py 运行服务吧。至此一个简单的内网管理服务完成,还有很多可以发展和优化的点。


总结

使用python flask 框架搭建web服务是简单易用的,展示一下页面:

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值