added Dockerfile & added --port --domain --skip-config-check flags
This commit is contained in:
parent
3ca7d57680
commit
28f71271d7
5 changed files with 249 additions and 18 deletions
32
Dockerfile
Normal file
32
Dockerfile
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# Use Alpine Linux as the base image
|
||||||
|
FROM alpine:3.20
|
||||||
|
|
||||||
|
# Update and install Golang and Git
|
||||||
|
RUN apk update && apk add --no-cache go git
|
||||||
|
|
||||||
|
# Create a new user and switch to it
|
||||||
|
RUN adduser -D myuser
|
||||||
|
USER myuser
|
||||||
|
|
||||||
|
# Set the working directory
|
||||||
|
WORKDIR /home/myuser
|
||||||
|
|
||||||
|
# Clone the Git repository
|
||||||
|
RUN git clone https://weforge.xyz/Spitfire/Search.git
|
||||||
|
|
||||||
|
# Change directory to the cloned repository
|
||||||
|
WORKDIR /home/myuser/Search
|
||||||
|
|
||||||
|
# Ensure the run.sh script is executable
|
||||||
|
RUN chmod +x run.sh
|
||||||
|
|
||||||
|
# Expose the application's port
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
# Define environment variables for port and domain with default values
|
||||||
|
ENV PORT=
|
||||||
|
ENV DOMAIN=
|
||||||
|
ENV SKIP_CONFIG="--skip-config-check"
|
||||||
|
|
||||||
|
# Run the run.sh script on container start
|
||||||
|
CMD ["sh", "-c", "./run.sh $SKIP_CONFIG --port ${PORT:-} --domain ${DOMAIN:-}"]
|
103
README.md
Normal file
103
README.md
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
<p align="center">
|
||||||
|
<img src="https://weforge.xyz/Spitfire/Branding/raw/commit/a80a6e075b8daffb54783d097ffa2da1da922128/icon11.svg" alt="Logo" width="64" height="64">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center" style="font-size: 32px;">
|
||||||
|
<strong><a href="https://qgato.xyz/">QGato Search Engine</a></strong>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p align="center">
|
||||||
|
A self-hosted private <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a> that aims to be more resource-efficient than its competition.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
# Bare in mind that this project is still WIP
|
||||||
|
|
||||||
|
## Comparison to other search engines
|
||||||
|
|
||||||
|
|
||||||
|
| Feature | Whoogle [1] | Araa-Search | LibreY | 4get | SearchXNG | *QGato* |
|
||||||
|
| :------------------------- | ------------------ | ------------------------- | ------------------------ | ------------------------ | ------------------------- | ---------------------------------------------------- |
|
||||||
|
| Works without JavaScript | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| Music search | ❓ | ❌ | ❌ | ✅ | ✅ | ✅ |
|
||||||
|
| Torrent search | ❌ | ✅ | ✅ | ❌ | ✅ | ✅ |
|
||||||
|
| API | ❌ | ❓ [2] | ✅ | ✅ | ✅ | ✅ |
|
||||||
|
| Scalable | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ |
|
||||||
|
| Not Resource Hungry | ❓ Moderate | ❌ Very resource hungry | ❌ Moderate 200-400mb~ | ❌ Moderate 200-400mb~ | ❌ Moderate 200-300MiB~ | ✅ about 15-20MiB at idle, 17-22MiB when searching |
|
||||||
|
| Result caching | ❌ | ❌ | ❓ | ❓ | ❓ | ✅ |
|
||||||
|
| Dynamic Page Loading | ❓ Not specified | ❌ | ❌ | ❌ | ✅ | ✅ |
|
||||||
|
| User themable | ❌ | ✅ | ❌ | ❌ | ✅[3] | ✅ |
|
||||||
|
| Unusual logo choice | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ |
|
||||||
|
|
||||||
|
[1]: I was not able to check this since their site does not work, same for the community instances.
|
||||||
|
|
||||||
|
[2]: In the project repo they specify that it has API, but It looks like they are no loger supporting it. Or just removed "API" button and documentation, since I was not able to find it anymore.
|
||||||
|
|
||||||
|
[3]: It is called 'User Themable' because you want to give the user freedom of choice for their theme, not by hard-setting one theme in the backend and calling it themable.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
### For Casual Users
|
||||||
|
|
||||||
|
- **Works out of the box** - No configuration required, just works by default.
|
||||||
|
- **No tracking or ads** - Fully private, ad-free experience.
|
||||||
|
- **Custom themes** - Personalize the look and feel.
|
||||||
|
- **Search suggestions** - Get faster results with helpful suggestions.
|
||||||
|
- **Privacy-first** - Open-source and transparent (unlike DuckDuckGo).
|
||||||
|
- **Annoyance-free** - No pop-ups, crypto, or clutter (I'm looking at you, Brave).
|
||||||
|
|
||||||
|
### For Self-Hosting
|
||||||
|
|
||||||
|
- **Self-hosted option** - Run on your own server for even more privacy.
|
||||||
|
- **Lightweight** - Low memory footprint (15-22MiB) even during searches.
|
||||||
|
- **Decentralized** - No single point of failure.
|
||||||
|
- **Results caching in RAM** - Faster response times through caching.
|
||||||
|
- **Configurable** - Tweak features via `config.ini`.
|
||||||
|
- **Flexible media support** - Images optionally stored on HDD/SSD for caching and improved response time.
|
||||||
|
|
||||||
|
### Results Sources
|
||||||
|
|
||||||
|
- **Search suggestions** - Sources include Yahoo, Startpage, Qwant, Ecosia, Brave, Edge, and DuckDuckGo.
|
||||||
|
- **Text search** - Google, Brave, DuckDuckGo, LibreX/Y.
|
||||||
|
- **Image search** - Sources include Qwant, Bing, and Imgur.
|
||||||
|
- **Video search** - Utilizes the Piped API.
|
||||||
|
- **Maps** - Integrated OpenStreetMap.
|
||||||
|
- **File downloads** - Access via torrent sources.
|
||||||
|
|
||||||
|
## Getting Started
|
||||||
|
|
||||||
|
### Prerequisites
|
||||||
|
|
||||||
|
- Go (version 1.18 or higher recommended)
|
||||||
|
- Git (unexpected)
|
||||||
|
- Access to the internet for fetching results (even more unexpected)
|
||||||
|
|
||||||
|
### Running the QGato
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone https://weforgecode.xyz/Spitfire/Search.git
|
||||||
|
cd Search
|
||||||
|
chmod +x ./run.sh
|
||||||
|
./run.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
git clone https://weforgecode.xyz/Spitfire/Search.git
|
||||||
|
cd Search
|
||||||
|
.\run.bat
|
||||||
|
```
|
||||||
|
|
||||||
|
*Its that easy!*
|
||||||
|
|
||||||
|
### Configuring
|
||||||
|
|
||||||
|
Configuration is done via the ``config.ini`` file.
|
||||||
|
On first start, you will be guided through the basic setup.
|
||||||
|
More advanced setup and all options will be listed here later, as this is still being updated.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[![](https://www.gnu.org/graphics/agplv3-with-text-162x68.png)](https://www.gnu.org/licenses/agpl-3.0.html)
|
41
init.go
41
init.go
|
@ -1,6 +1,8 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"flag"
|
||||||
|
"os"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -35,14 +37,43 @@ const configFilePath = "config.ini"
|
||||||
var config Config
|
var config Config
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
// Command-line flags
|
||||||
|
portFlag := flag.Int("port", 0, "Port number to run the application (overrides config)")
|
||||||
|
domainFlag := flag.String("domain", "", "Domain address for the application (overrides config)")
|
||||||
|
skipConfigFlag := flag.Bool("skip-config-check", false, "Skip interactive prompts and load config.ini")
|
||||||
|
|
||||||
|
// Parse command-line flags
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if *skipConfigFlag {
|
||||||
|
// Skip interactive configuration
|
||||||
|
if _, err := os.Stat(configFilePath); err == nil {
|
||||||
|
// Load from config file if it exists
|
||||||
|
config = loadConfig()
|
||||||
|
} else {
|
||||||
|
// Use defaults if config file does not exist
|
||||||
|
config = defaultConfig
|
||||||
|
saveConfig(config) // Save the defaults to config.ini
|
||||||
|
printInfo("Configuration saved to %s", configFilePath)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Initialize configuration interactively or from config file
|
||||||
err := initConfig()
|
err := initConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
printErr("Error during initialization:")
|
printErr("Error during initialization:")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Override with command-line arguments if provided
|
||||||
|
if *portFlag != 0 {
|
||||||
|
config.Port = *portFlag
|
||||||
|
}
|
||||||
|
if *domainFlag != "" {
|
||||||
|
config.Domain = *domainFlag
|
||||||
|
}
|
||||||
|
|
||||||
loadNodeConfig()
|
loadNodeConfig()
|
||||||
// go checkMasterHeartbeat() // Not currently used
|
|
||||||
|
|
||||||
if config.AuthCode == "" {
|
if config.AuthCode == "" {
|
||||||
config.AuthCode = generateStrongRandomString(64)
|
config.AuthCode = generateStrongRandomString(64)
|
||||||
|
@ -57,14 +88,6 @@ func main() {
|
||||||
}
|
}
|
||||||
config.PeerID = hostID
|
config.PeerID = hostID
|
||||||
|
|
||||||
// if len(config.Peers) > 0 {
|
|
||||||
// time.Sleep(2 * time.Second) // Give some time for connections to establish
|
|
||||||
// startElection()
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Start automatic update checker, not used now
|
|
||||||
//go checkForUpdates()
|
|
||||||
|
|
||||||
InitializeLanguage("en") // Initialize language before generating OpenSearch
|
InitializeLanguage("en") // Initialize language before generating OpenSearch
|
||||||
generateOpenSearchXML(config)
|
generateOpenSearchXML(config)
|
||||||
|
|
||||||
|
|
42
run.bat
42
run.bat
|
@ -1,6 +1,36 @@
|
||||||
@echo off
|
@echo off
|
||||||
setlocal enabledelayedexpansion
|
setlocal enabledelayedexpansion
|
||||||
|
|
||||||
|
rem Initialize variables
|
||||||
|
set SKIP_CONFIG=""
|
||||||
|
set PORT=""
|
||||||
|
set DOMAIN=""
|
||||||
|
|
||||||
|
rem Parse arguments
|
||||||
|
:parse_args
|
||||||
|
if "%~1"=="" goto end_parse
|
||||||
|
if "%~1"=="--port" (
|
||||||
|
set PORT=%~2
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
goto parse_args
|
||||||
|
)
|
||||||
|
if "%~1"=="--domain" (
|
||||||
|
set DOMAIN=%~2
|
||||||
|
shift
|
||||||
|
shift
|
||||||
|
goto parse_args
|
||||||
|
)
|
||||||
|
if "%~1"=="--skip-config-check" (
|
||||||
|
set SKIP_CONFIG=--skip-config-check
|
||||||
|
shift
|
||||||
|
goto parse_args
|
||||||
|
)
|
||||||
|
echo Unknown argument: %~1
|
||||||
|
exit /b 1
|
||||||
|
|
||||||
|
:end_parse
|
||||||
|
|
||||||
rem Use the current directory where the script is executed
|
rem Use the current directory where the script is executed
|
||||||
pushd %~dp0
|
pushd %~dp0
|
||||||
|
|
||||||
|
@ -10,8 +40,16 @@ for %%f in (*.go) do (
|
||||||
set GO_FILES=!GO_FILES! %%f
|
set GO_FILES=!GO_FILES! %%f
|
||||||
)
|
)
|
||||||
|
|
||||||
rem Run the Go program with all the .go files
|
rem Construct the command
|
||||||
go run !GO_FILES!
|
set CMD=go run !GO_FILES! !SKIP_CONFIG!
|
||||||
|
if not "%PORT%"=="" set CMD=!CMD! --port %PORT%
|
||||||
|
if not "%DOMAIN%"=="" set CMD=!CMD! --domain %DOMAIN%
|
||||||
|
|
||||||
|
rem Informative output
|
||||||
|
echo Starting application with command: !CMD!
|
||||||
|
|
||||||
|
rem Run the Go program with the constructed command
|
||||||
|
call !CMD!
|
||||||
|
|
||||||
rem Return to the original directory
|
rem Return to the original directory
|
||||||
popd
|
popd
|
||||||
|
|
41
run.sh
41
run.sh
|
@ -1,7 +1,42 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# List all go files in this directory
|
# Initialize variables
|
||||||
|
SKIP_CONFIG=""
|
||||||
|
PORT=""
|
||||||
|
DOMAIN=""
|
||||||
|
|
||||||
|
# Parse arguments
|
||||||
|
while [ $# -gt 0 ]; do
|
||||||
|
case $1 in
|
||||||
|
--port)
|
||||||
|
PORT=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--domain)
|
||||||
|
DOMAIN=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--skip-config-check)
|
||||||
|
SKIP_CONFIG="--skip-config-check"
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown argument: $1"
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# List all Go files in this directory
|
||||||
GO_FILES=$(find . -name '*.go' -print)
|
GO_FILES=$(find . -name '*.go' -print)
|
||||||
|
|
||||||
# Run the Go program with the specified files first, followed by the remaining files
|
# Construct the command
|
||||||
go run $FILES $GO_FILES
|
CMD="go run $GO_FILES $SKIP_CONFIG"
|
||||||
|
[ -n "$PORT" ] && CMD="$CMD --port $PORT"
|
||||||
|
[ -n "$DOMAIN" ] && CMD="$CMD --domain $DOMAIN"
|
||||||
|
|
||||||
|
# Informative output
|
||||||
|
echo "Starting application with command: $CMD"
|
||||||
|
|
||||||
|
# Run the Go program with the constructed command
|
||||||
|
eval $CMD
|
||||||
|
|
Loading…
Add table
Reference in a new issue