前言
搭建一个简单的私人用服务,包括文件以及影音服务。
影音服务使用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服务是简单易用的,展示一下页面: