diff --git a/.gitignore b/.gitignore index f1257843d..7023d0a8b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ log dump.rdb -hiddify_usages.json \ No newline at end of file +hiddify_usages.json +docker-data \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index b71d87442..08a66b8a2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,7 +2,7 @@ FROM ubuntu:22.04 EXPOSE 80 EXPOSE 443 -RUN apt-get update && apt-get install -y whiptail apt-utils curl sudo systemd python2 xxd lsof +RUN apt-get update && apt-get install -y apt-utils curl sudo systemd xxd lsof ENV TERM xterm ENV TZ Etc/UTC @@ -11,7 +11,17 @@ ENV DEBIAN_FRONTEND noninteractive USER root WORKDIR /opt/hiddify-manager/ COPY . . + +RUN mkdir -p /hiddify-data/ssl/ && \ + ln -sf /hiddify-data/ssl /opt/hiddify-manager/ssl + # RUN mkdir -p ~/.ssh && echo "StrictHostKeyChecking no " > ~/.ssh/config -RUN bash install.sh install-docker -RUN curl -L https://raw.githubusercontent.com/gdraheim/docker-systemctl-replacement/master/files/docker/systemctl.py -o /usr/bin/systemctl -ENTRYPOINT ["/bin/bash","-c", "./apply_configs.sh && tail -f /opt/hiddify-manager/log/system/*"] +ENV HIDDIFY_PANLE_SOURCE_DIR=/opt/hiddify-manager/hiddify-panel/src/ +ENV DOCKER_MODE=true +RUN bash install.sh install-docker --no-gui +RUN curl -L https://raw.githubusercontent.com/gdraheim/docker-systemctl-replacement/master/files/docker/systemctl3.py -o /usr/bin/systemctl + + + + +ENTRYPOINT ["/bin/bash","-c", "./apply_configs.sh --no-gui && tail -f /opt/hiddify-manager/log/system/*"] diff --git a/common/jinja.py b/common/jinja.py index 2d0e9a904..950db0d59 100644 --- a/common/jinja.py +++ b/common/jinja.py @@ -39,48 +39,49 @@ def render_j2_templates(start_path): env.filters['hexencode'] = lambda s: ''.join(hex(ord(c))[2:].zfill(2) for c in s) # Dirs to ignore from Jinja2 rendering - exclude_dirs = ['/opt/hiddify-manager/singbox/configs/includes', '/opt/hiddify-manager/.venv'] + exclude_dirs = ['/opt/hiddify-manager/singbox/configs/includes', '/opt/hiddify-manager/.venv',"/opt/hiddify-manager/hiddify-panel/src/"] for root, dirs, files in os.walk(start_path): for file in files: - if file.endswith(".j2") and not any(os.path.commonpath([exclude_dir, root]) == exclude_dir for exclude_dir in exclude_dirs): - template_path = os.path.join(root, file) - - print("Rendering: " + template_path) - - # Create a template object by reading the file - template = env.get_template(template_path) - - # Render the template - rendered_content = template.render(**configs, exec=exec, os=os) - if not rendered_content: - print(f'Warning jinja2: {template_path} - Empty') - - # Write the rendered content to a new file without the .j2 extension - output_file_path = os.path.splitext(template_path)[0] - if output_file_path.endswith(".json"): - # Remove trailing comma and comments from json - try: - json5object = json5.loads(rendered_content) - rendered_content = json5.dumps( - json5object, - trailing_commas=False, - indent=2, - quote_keys=True, - ) - except Exception as e: - print(f"Error parsing json: {e}") - - with open(output_file_path, "w", encoding="utf-8") as output_file: - output_file.write(str(rendered_content)) - - input_stat = os.stat(template_path) - os.chmod(output_file_path, input_stat.st_mode) - # os.chmod(output_file_path, 0o600) - os.chown(output_file_path, input_stat.st_uid, input_stat.st_gid) - - - # print(f'Rendered and stored: {output_file_path}') + if not file.endswith(".j2"):continue + if any(exclude_dir in root for exclude_dir in exclude_dirs):continue + template_path = os.path.join(root, file) + + print("Rendering: " + template_path) + + # Create a template object by reading the file + template = env.get_template(template_path) + + # Render the template + rendered_content = template.render(**configs, exec=exec, os=os) + if not rendered_content: + print(f'Warning jinja2: {template_path} - Empty') + + # Write the rendered content to a new file without the .j2 extension + output_file_path = os.path.splitext(template_path)[0] + if output_file_path.endswith(".json"): + # Remove trailing comma and comments from json + try: + json5object = json5.loads(rendered_content) + rendered_content = json5.dumps( + json5object, + trailing_commas=False, + indent=2, + quote_keys=True, + ) + except Exception as e: + print(f"Error parsing json: {e}") + + with open(output_file_path, "w", encoding="utf-8") as output_file: + output_file.write(str(rendered_content)) + + input_stat = os.stat(template_path) + os.chmod(output_file_path, input_stat.st_mode) + # os.chmod(output_file_path, 0o600) + os.chown(output_file_path, input_stat.st_uid, input_stat.st_gid) + + + # print(f'Rendered and stored: {output_file_path}') start_path = "/opt/hiddify-manager/" diff --git a/docker-compose.yml b/docker-compose.yml index 6e35f2556..c3d7b0570 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,12 @@ -version: '3' +version: '3.8' + services: hiddify: - image: hiddify + + depends_on: + - mariadb + - redis build: . ports: - 443:443 @@ -11,5 +15,29 @@ services: # cap_add: # - NET_ADMIN volumes: - - ./hiddify-panel/hiddifypanel.db:/opt/hiddify-manager/hiddify-panel/hiddifypanel.db - - ./ssl/:/opt/hiddify-manager/ssl/ + - ./docker-data/:/hiddify-data/ + environment: + REDIS_URI_MAIN: 'redis://:REDIS_STRONG_PASS@redis:6379/0' + REDIS_URI_SSH: 'redis://:REDIS_STRONG_PASS@redis:6379/1' + SQLALCHEMY_DATABASE_URI: 'mysql+mysqldb://hiddifypanel:MYSQL_STRONG_PASS@mariadb/hiddifypanel?charset=utf8mb4' + + mariadb: + image: mariadb:latest + container_name: mariadb_container + restart: always + environment: + MARIADB_RANDOM_ROOT_PASSWORD: 1 # Root user password + MYSQL_DATABASE: hiddifypanel # Initial database name + MYSQL_USER: hiddifypanel # Custom username + MYSQL_PASSWORD: MYSQL_STRONG_PASS # Custom user password + volumes: + - ./docker-data/mariadb_data:/var/lib/mysql # Persistent storage for database files + + redis: + image: redis:latest + container_name: redis_container + restart: always + command: ["redis-server", "--requirepass", "REDIS_STRONG_PASS"] + volumes: + - ./docker-data/redis_data:/data # Persistent storage for Redis data + \ No newline at end of file diff --git a/hiddify-panel/install.sh b/hiddify-panel/install.sh index cbd321a41..2dadb8d20 100755 --- a/hiddify-panel/install.sh +++ b/hiddify-panel/install.sh @@ -1,6 +1,6 @@ source ../common/utils.sh activate_python_venv -install_package wireguard libev-dev libevdev2 default-libmysqlclient-dev build-essential pkg-config +install_package wireguard libev-dev libevdev2 default-libmysqlclient-dev build-essential pkg-config ssh-client useradd -m hiddify-panel -s /bin/bash >/dev/null 2>&1 @@ -24,7 +24,7 @@ pip uninstall -y flask-babelex >/dev/null 2>&1 if [ -n "$HIDDIFY_PANLE_SOURCE_DIR" ]; then echo "NOTICE: building hiddifypanel package from source..." echo "NOTICE: the source dir $HIDDIFY_PANLE_SOURCE_DIR" - pip install -e "$HIDDIFY_PANLE_SOURCE_DIR" + /opt/hiddify-manager/.venv/bin/pip install -e "$HIDDIFY_PANLE_SOURCE_DIR" else echo "Installing hiddifypanel with the pip" python -c "import hiddifypanel" || pip install -U hiddifypanel diff --git a/hiddify-panel/run.sh b/hiddify-panel/run.sh index b1075584d..fb43338e6 100644 --- a/hiddify-panel/run.sh +++ b/hiddify-panel/run.sh @@ -7,16 +7,24 @@ chown hiddify-panel ../log/system/panel.log chown -R hiddify-panel:hiddify-panel . >/dev/null 2>&1 chmod 600 app.cfg + # set mysql password to flask app config sed -i '/^SQLALCHEMY_DATABASE_URI/d' app.cfg -MYSQL_PASS=$(cat ../other/mysql/mysql_pass) -echo "SQLALCHEMY_DATABASE_URI = 'mysql+mysqldb://hiddifypanel:$MYSQL_PASS@127.0.0.1/hiddifypanel?charset=utf8mb4'" >>app.cfg - +if [ -z "${SQLALCHEMY_DATABASE_URI}" ]; then + MYSQL_PASS=$(cat ../other/mysql/mysql_pass) + SQLALCHEMY_DATABASE_URI = 'mysql+mysqldb://hiddifypanel:$MYSQL_PASS@127.0.0.1/hiddifypanel?charset=utf8mb4' +fi +echo "SQLALCHEMY_DATABASE_URI ='$SQLALCHEMY_DATABASE_URI'" >>app.cfg sed -i '/^REDIS_URI/d' app.cfg -REDIS_PASS=$(grep '^requirepass' "../other/redis/redis.conf" | awk '{print $2}') -echo "REDIS_URI_MAIN = 'redis://:${REDIS_PASS}@127.0.0.1:6379/0'" >>app.cfg -echo "REDIS_URI_SSH = 'redis://:${REDIS_PASS}@127.0.0.1:6379/1'" >>app.cfg +if [ -z "${REDIS_URI_MAIN}" ]; then + REDIS_PASS=$(grep '^requirepass' "../other/redis/redis.conf" | awk '{print $2}') + REDIS_URI_MAIN = 'redis://:${REDIS_PASS}@127.0.0.1:6379/0' + REDIS_URI_SSH = 'redis://:${REDIS_PASS}@127.0.0.1:6379/1' +fi + +echo "REDIS_URI_MAIN = '$REDIS_URI_MAIN'">>app.cfg +echo "REDIS_URI_SSH = '$REDIS_URI_SSH'">>app.cfg diff --git a/hiddify-panel/src b/hiddify-panel/src index bf095b490..a25f418a4 160000 --- a/hiddify-panel/src +++ b/hiddify-panel/src @@ -1 +1 @@ -Subproject commit bf095b4902af45ea42ca945cf7347b66058cea5f +Subproject commit a25f418a430b1abe4da6ed9a05da81caced0179c diff --git a/install.sh b/install.sh index 2f1db8479..8506710c6 100755 --- a/install.sh +++ b/install.sh @@ -43,9 +43,10 @@ function main() { clean_files update_progress "${PROGRESS_ACTION}" "Common Tools and Requirements" 2 runsh install.sh common - install_run other/redis - install_run other/mysql - + if [ "${DOCKER_MODE}" != "true" ];then + install_run other/redis + install_run other/mysql + fi # Because we need to generate reality pair in panel # is_installed xray || bash -c "$(curl -L https://github.com/XTLS/Xray-install/raw/main/install-release.sh)" @ install --version 1.8.4 diff --git a/other/mysql/install.sh b/other/mysql/install.sh index 9499ed320..db4c1dc93 100644 --- a/other/mysql/install.sh +++ b/other/mysql/install.sh @@ -16,7 +16,7 @@ if [ ! -f "$MARIADB_CONF" ]; then echo "MariaDB configuration file ($MARIADB_CONF) not found." fi - +sudo -u mysql mkdir /run/mysqld/ # Check if bind-address is already set to 127.0.0.1 if ! grep -q "^[^#]*bind-address\s*=\s*127.0.0.1" "$MARIADB_CONF"; then @@ -41,7 +41,7 @@ fi -if [ "$MODE" != "docker-install" ];then +if [ "$MODE" != "install-docker" ];then if [ ! -f "mysql_pass" ]; then echo "Generating a random password..." diff --git a/other/ssh/run.sh b/other/ssh/run.sh index 1b3260638..0a6d69a63 100644 --- a/other/ssh/run.sh +++ b/other/ssh/run.sh @@ -5,9 +5,13 @@ ln -sf $(pwd)/hiddify-ssh-liberty-bridge.service /etc/systemd/system/hiddify-ssh chown -R liberty-bridge host_key sed -i '/REDIS_URL/d' .env -REDIS_PASS=$(grep '^requirepass' "../redis/redis.conf" | awk '{print $2}') -echo "REDIS_URL='redis://:$REDIS_PASS@127.0.0.1:6379/1'" >>.env +if [ -z "${REDIS_URI_SSH}" ]; then + REDIS_PASS=$(grep '^requirepass' "../redis/redis.conf" | awk '{print $2}') + REDIS_URI_SSH='redis://:$REDIS_PASS@127.0.0.1:6379/1' +fi + +echo "REDIS_URL='$REDIS_URI_SSH'" >>.env chmod 600 .env*