-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
37 changed files
with
1,248 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#!/bin/bash | ||
|
||
# Step 1: Install Gunicorn | ||
echo "Installing Gunicorn..." | ||
pip install gunicorn | ||
|
||
# Step 2: Install Nginx | ||
echo "Installing Nginx..." | ||
sudo apt update | ||
sudo apt install -y nginx | ||
|
||
# Step 3: Configure Gunicorn | ||
echo "Configuring Gunicorn..." | ||
cat <<EOF | sudo tee /etc/systemd/system/gunicorn.service > /dev/null | ||
[Unit] | ||
Description=Gunicorn instance to serve your Flask application | ||
After=network.target | ||
[Service] | ||
User=steam | ||
Group=steam | ||
WorkingDirectory=/home/app/pals | ||
Environment="PATH=/home/app/pals/venv/bin" | ||
ExecStart=/home/app/pals/venv/bin/gunicorn -w 4 -b 0.0.0.0:5000 main:create_app() | ||
[Install] | ||
WantedBy=multi-user.target | ||
EOF | ||
|
||
# Step 4: Configure Nginx | ||
echo "Configuring Nginx..." | ||
cat <<EOF | sudo tee /etc/nginx/sites-available/PalService > /dev/null | ||
server { | ||
listen 80; | ||
server_name 192.168.33.78; | ||
location / { | ||
proxy_pass http://localhost:5000; | ||
proxy_set_header Host $host; | ||
proxy_set_header X-Real-IP $remote_addr; | ||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; | ||
} | ||
location /static { | ||
alias /home/app/pals/main/static; | ||
} | ||
location /media { | ||
alias /home/app/pals/main/media; | ||
} | ||
error_page 500 502 503 504 /50x.html; | ||
location = /50x.html { | ||
root /usr/share/nginx/html; | ||
} | ||
} | ||
EOF | ||
|
||
sudo ln -s /etc/nginx/sites-available/PalService /etc/nginx/sites-enabled | ||
|
||
# Step 5: Enable and Start Services | ||
echo "Enabling and starting services..." | ||
sudo systemctl enable gunicorn | ||
sudo systemctl start gunicorn | ||
sudo systemctl enable nginx | ||
sudo systemctl start nginx | ||
|
||
# Step 6: Configure Firewall | ||
echo "Configuring firewall..." | ||
sudo ufw allow 80 | ||
#sudo ufw enable | ||
|
||
# Step 7: Add new line to sudoers using visudo | ||
echo "Adding a new line to sudoers..." | ||
echo "steam ALL=(ALL) NOPASSWD: /bin/systemctl start palworld.service, /bin/systemctl stop palworld.service, /bin/systemctl restart palworld.service, /bin/systemctl is-active palworld.service" | sudo tee -a /etc/sudoers | ||
|
||
# Step 8: Set up Python virtual environment | ||
echo "Setting up Python virtual environment..." | ||
cd /home/app/pals | ||
python3 -m venv venv | ||
source venv/bin/activate | ||
|
||
# Step 9: Install Flask and other dependencies | ||
echo "Installing Flask and dependencies..." | ||
pip install -r requirements.txt | ||
|
||
# Step 10: Deactivate virtual environment | ||
deactivate | ||
|
||
sudo systemctl restart nginx | ||
sudo systemctl restart gunicorn | ||
|
||
echo "Deployment completed!" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# Use an official Python runtime as a parent image | ||
FROM python:3.8-slim | ||
|
||
# Set the working directory in the container | ||
WORKDIR /app | ||
|
||
# Copy the current directory contents into the container at /app | ||
COPY . . | ||
|
||
# Upgrade pip | ||
RUN pip install --upgrade pip | ||
|
||
# Install Gunicorn | ||
RUN pip install gunicorn | ||
|
||
# Install any needed packages specified in requirements.txt | ||
RUN pip install --no-cache-dir -r requirements.txt | ||
|
||
# Make port 5000 available to the world outside this container | ||
EXPOSE 5000 | ||
|
||
# Run the Flask init-db command during container setup | ||
RUN flask --app main:create_app init-db | ||
|
||
# Run the Flask app using Gunicorn | ||
CMD ["gunicorn", "-b", "0.0.0.0:5000", "run:app"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Script is running |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import os | ||
from flask import Flask | ||
from .configurations.config import Config | ||
|
||
def create_app(): | ||
app = Flask(__name__, instance_relative_config=True) | ||
|
||
app.config.from_object(Config) | ||
# Load the default configuration from config.py | ||
#print(app.config) | ||
|
||
if not os.path.exists(Config.INSTANCE_PATH): | ||
os.makedirs(Config.INSTANCE_PATH) | ||
|
||
# Register blueprints and extensions | ||
from . import db | ||
db.init_app(app) | ||
|
||
from .utils import server_config | ||
app.register_blueprint(server_config.bp) | ||
|
||
from . import auth | ||
app.register_blueprint(auth.bp) | ||
|
||
from main.routes import bp as main_bp | ||
app.register_blueprint(main_bp) | ||
|
||
from .utils.service_control import service_control_bp | ||
app.register_blueprint(service_control_bp) | ||
|
||
from .configurations.config import Configs_bp | ||
app.register_blueprint(Configs_bp) | ||
|
||
return app |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
import functools | ||
|
||
from functools import wraps | ||
from flask import Blueprint, flash, g, redirect, render_template, request, session, url_for | ||
from werkzeug.security import check_password_hash, generate_password_hash | ||
|
||
from main.db import get_db | ||
|
||
bp = Blueprint('auth', __name__, url_prefix='/auth') | ||
|
||
def get_user_by_id(user_id): | ||
db = get_db() | ||
return db.execute("SELECT * FROM user WHERE id = ?", (user_id,)).fetchone() | ||
|
||
def login_required(view): | ||
@wraps(view) | ||
def wrapped_view(*args, **kwargs): | ||
if g.user is None: | ||
return redirect(url_for('auth.login')) | ||
|
||
g.user = get_user_by_id(session['user_id']) | ||
|
||
return view(*args, **kwargs) | ||
|
||
return wrapped_view | ||
|
||
def admin_required(view): | ||
@wraps(view) | ||
def wrapped_view(*args, **kwargs): | ||
if g.user is None or not g.user.get('is_admin', False): | ||
return redirect(url_for('auth.login')) | ||
return view(*args, **kwargs) | ||
|
||
return wrapped_view | ||
|
||
@bp.route('/register', methods=('GET', 'POST')) | ||
@admin_required | ||
def register(): | ||
if request.method == 'POST': | ||
username = request.form['username'] | ||
password = request.form['password'] | ||
db = get_db() | ||
error = None | ||
|
||
if not username: | ||
error = 'Username is required.' | ||
elif not password: | ||
error = 'Password is required.' | ||
|
||
if error is None: | ||
try: | ||
db.execute( | ||
"INSERT INTO user (username, password) VALUES (?, ?)", | ||
(username, generate_password_hash(password)), | ||
) | ||
db.commit() | ||
except db.IntegrityError: | ||
error = f"User {username} is already registered." | ||
else: | ||
return redirect('/') | ||
|
||
flash(error) | ||
|
||
return render_template('auth/register.html') | ||
|
||
@bp.route('/login', methods=('GET', 'POST')) | ||
def login(): | ||
if request.method == 'POST': | ||
username = request.form['username'] | ||
password = request.form['password'] | ||
db = get_db() | ||
error = None | ||
user = db.execute( | ||
'SELECT * FROM user WHERE username = ?', (username,) | ||
).fetchone() | ||
|
||
if user is None: | ||
error = 'Incorrect username.' | ||
elif not check_password_hash(user['password'], password): | ||
error = 'Incorrect password.' | ||
|
||
if error is None: | ||
session.clear() | ||
session['user_id'] = user['id'] | ||
return redirect('/') | ||
|
||
flash(error) | ||
|
||
return render_template('auth/login.html') | ||
|
||
@bp.route('/reset-password', methods=('GET', 'POST')) | ||
@login_required | ||
def reset_password(): | ||
if request.method == 'POST': | ||
current_password = request.form['current_password'] | ||
new_password = request.form['new_password'] | ||
confirm_password = request.form['confirm_password'] | ||
|
||
db = get_db() | ||
error = None | ||
|
||
if not check_password_hash(g.user['password'], current_password): | ||
error = 'Invalid current password.' | ||
elif new_password != confirm_password: | ||
error = 'New password and confirm password do not match.' | ||
else: | ||
db.execute( | ||
"UPDATE user SET password = ? WHERE id = ?", | ||
(generate_password_hash(new_password), g.user['id']), | ||
) | ||
db.commit() | ||
|
||
flash('Password reset successfully.') | ||
return redirect('/') | ||
|
||
flash(error) | ||
|
||
return render_template('auth/reset_password.html') | ||
|
||
@bp.before_app_request | ||
def load_logged_in_user(): | ||
user_id = session.get('user_id') | ||
|
||
if user_id is None: | ||
g.user = None | ||
else: | ||
user_data = get_db().execute( | ||
'SELECT id, username, is_admin FROM user WHERE id = ?', (user_id,) | ||
).fetchone() | ||
|
||
if user_data: | ||
g.user = { | ||
'id': user_data['id'], | ||
'username': user_data['username'], | ||
'is_admin': user_data['is_admin'], | ||
} | ||
else: | ||
g.user = None | ||
|
||
@bp.route('/logout') | ||
def logout(): | ||
session.clear() | ||
return redirect(url_for('auth.login')) | ||
|
||
def login_required(view): | ||
@functools.wraps(view) | ||
def wrapped_view(**kwargs): | ||
if g.user is None: | ||
return redirect(url_for('auth.login')) | ||
|
||
return view(**kwargs) | ||
|
||
return wrapped_view |
Empty file.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import os | ||
from flask import Blueprint, render_template, redirect, url_for, request, flash | ||
from main.auth import admin_required | ||
from main.db import get_db | ||
|
||
Configs_bp = Blueprint('Configs', __name__) | ||
|
||
|
||
class Config: | ||
DEBUG = True | ||
SECRET_KEY = 'your_secret_key' | ||
BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) | ||
INSTANCE_PATH=os.path.join(BASE_DIR, 'instance') | ||
DATABASE=os.path.join(BASE_DIR, INSTANCE_PATH, 'flaskr.sqlite') | ||
SCRIPT_FILE_PATH = os.path.join('/home/steam/Steam/steamapps/common/PalServer') | ||
TEMPLATE_FOLDER = os.path.join(BASE_DIR, 'templates') | ||
STATIC_FOLDER = os.path.join(BASE_DIR, 'static') | ||
####Fix data implementation of path#### | ||
#INI_FILE_PATH = os.path.join(BASE_DIR, '../PalWorldSettings.ini') | ||
#INI_FILE_PATH = os.path.join('/home/steam/Steam/steamapps/common/PalServer/Pal/Saved/Config/LinuxServer/PalWorldSettings.ini') | ||
|
||
@Configs_bp.route('/update_path/<name>', methods=['GET', 'POST']) | ||
@admin_required | ||
def update_path(name): | ||
db = get_db() | ||
|
||
existing_config = db.execute('SELECT * FROM configs WHERE name = ?', (name,)).fetchone() | ||
|
||
if existing_config is None: | ||
flash(f'Configuration with name {name} not found', 'error') | ||
return redirect(url_for('main.home')) # Redirect to another page or handle appropriately | ||
|
||
if request.method == 'POST': | ||
new_path = request.form.get('new_path') | ||
|
||
if not new_path: | ||
flash('Missing new_path parameter', 'error') | ||
return redirect(url_for('Configs.update_path', name=name)) | ||
|
||
db.execute('UPDATE configs SET path = ? WHERE name = ?', (new_path, name)) | ||
db.commit() | ||
|
||
flash(f'Path for configuration {name} updated successfully', 'success') | ||
|
||
return redirect('/') | ||
|
||
return render_template('misc/update_path.html', config_name=name) |
Oops, something went wrong.