forked from Archives/searxng
Merge branch 'master' into duckduckgo_correction
This commit is contained in:
commit
93cbd85b8a
55
.config.sh
Normal file
55
.config.sh
Normal file
@ -0,0 +1,55 @@
|
||||
# -*- coding: utf-8; mode: sh -*-
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# shellcheck shell=bash disable=SC2034
|
||||
#
|
||||
# This environment is used by ./utils scripts like filtron.sh or searx.sh. The
|
||||
# default values are *most flexible* and *best maintained*, you normally not
|
||||
# need to change the defaults (except PUBLIC_URL).
|
||||
#
|
||||
# Before you change any value here you have to uninstall any previous
|
||||
# installation. Further is it recommended to backup your changes simply by
|
||||
# adding them to you local brand (git branch)::
|
||||
#
|
||||
# git add .config
|
||||
|
||||
# The public URL of the searx instance: PUBLIC_URL="https://mydomain.xy/searx"
|
||||
# The default is taken from ./utils/brand.env.
|
||||
|
||||
PUBLIC_URL="${SEARX_URL}"
|
||||
|
||||
if [[ ${PUBLIC_URL} == "https://searx.me" ]]; then
|
||||
# hint: Linux containers do not have DNS entries, lets use IPs
|
||||
PUBLIC_URL="http://$(primary_ip)/searx"
|
||||
fi
|
||||
|
||||
# searx.sh
|
||||
# ---------
|
||||
|
||||
# SEARX_INTERNAL_URL="127.0.0.1:8888"
|
||||
|
||||
# Only change, if you maintain a searx brand in your searx fork.
|
||||
# GIT_BRANCH="${GIT_BRANCH:-master}"
|
||||
|
||||
# filtron.sh
|
||||
# ----------
|
||||
|
||||
# FILTRON_API="127.0.0.1:4005"
|
||||
# FILTRON_LISTEN="127.0.0.1:4004"
|
||||
# FILTRON_TARGET="127.0.0.1:8888"
|
||||
|
||||
# morty.sh
|
||||
# --------
|
||||
|
||||
# morty listen address
|
||||
# MORTY_LISTEN="127.0.0.1:3000"
|
||||
# PUBLIC_URL_PATH_MORTY="/morty/"
|
||||
|
||||
# system services
|
||||
# ---------------
|
||||
|
||||
# Common $HOME folder of the service accounts
|
||||
# SERVICE_HOME_BASE="/usr/local"
|
||||
|
||||
# **experimental**: Set SERVICE_USER to run all services by one account, but be
|
||||
# aware that removing discrete components might conflict!
|
||||
# SERVICE_USER=searx
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
# to sync with .dockerignore
|
||||
.coverage
|
||||
coverage/
|
||||
cache/
|
||||
.installed.cfg
|
||||
engines.cfg
|
||||
env
|
||||
|
65
Makefile
65
Makefile
@ -1,24 +1,31 @@
|
||||
# -*- coding: utf-8; mode: makefile-gmake -*-
|
||||
.DEFAULT_GOAL=help
|
||||
|
||||
# START Makefile setup
|
||||
export GIT_URL=https://github.com/asciimoo/searx
|
||||
export GIT_BRANCH=master
|
||||
export SEARX_URL=https://searx.me
|
||||
export DOCS_URL=https://asciimoo.github.io/searx
|
||||
# END Makefile setup
|
||||
|
||||
include utils/makefile.include
|
||||
|
||||
PYOBJECTS = searx
|
||||
DOC = docs
|
||||
PY_SETUP_EXTRAS ?= \[test\]
|
||||
|
||||
PYDIST=./dist/py
|
||||
PYBUILD=./build/py
|
||||
|
||||
include utils/makefile.include
|
||||
include utils/makefile.python
|
||||
include utils/makefile.sphinx
|
||||
|
||||
all: clean install
|
||||
|
||||
PHONY += help
|
||||
help:
|
||||
PHONY += help-min help-all help
|
||||
|
||||
help: help-min
|
||||
@echo ''
|
||||
@echo 'to get more help: make help-all'
|
||||
|
||||
help-min:
|
||||
@echo ' test - run developer tests'
|
||||
@echo ' docs - build documentation'
|
||||
@echo ' docs-live - autobuild HTML documentation while editing'
|
||||
@ -33,9 +40,18 @@ help:
|
||||
@echo ' docker - build Docker image'
|
||||
@echo ' node.env - download & install npm dependencies locally'
|
||||
@echo ''
|
||||
@$(MAKE) -s -f utils/makefile.include make-help
|
||||
@echo 'environment'
|
||||
@echo ' SEARX_URL = $(SEARX_URL)'
|
||||
@echo ' GIT_URL = $(GIT_URL)'
|
||||
@echo ' DOCS_URL = $(DOCS_URL)'
|
||||
@echo ''
|
||||
@$(MAKE) -s -f utils/makefile.python python-help
|
||||
@$(MAKE) -e -s make-help
|
||||
|
||||
help-all: help-min
|
||||
@echo ''
|
||||
@$(MAKE) -e -s python-help
|
||||
@echo ''
|
||||
@$(MAKE) -e -s docs-help
|
||||
|
||||
PHONY += install
|
||||
install: buildenv pyenvinstall
|
||||
@ -44,7 +60,7 @@ PHONY += uninstall
|
||||
uninstall: pyenvuninstall
|
||||
|
||||
PHONY += clean
|
||||
clean: pyclean node.clean test.clean
|
||||
clean: pyclean docs-clean node.clean test.clean
|
||||
$(call cmd,common_clean)
|
||||
|
||||
PHONY += run
|
||||
@ -61,14 +77,24 @@ run: buildenv pyenvinstall
|
||||
# docs
|
||||
# ----
|
||||
|
||||
sphinx-doc-prebuilds:: buildenv pyenvinstall prebuild-includes
|
||||
|
||||
PHONY += docs
|
||||
docs: buildenv pyenvinstall sphinx-doc
|
||||
docs: sphinx-doc-prebuilds sphinx-doc
|
||||
$(call cmd,sphinx,html,docs,docs)
|
||||
|
||||
PHONY += docs-live
|
||||
docs-live: buildenv pyenvinstall sphinx-live
|
||||
docs-live: sphinx-doc-prebuilds sphinx-live
|
||||
$(call cmd,sphinx_autobuild,html,docs,docs)
|
||||
|
||||
PHONY += prebuild-includes
|
||||
prebuild-includes:
|
||||
$(Q)mkdir -p $(DOCS_BUILD)/includes
|
||||
$(Q)./utils/searx.sh doc | cat > $(DOCS_BUILD)/includes/searx.rst
|
||||
$(Q)./utils/filtron.sh doc | cat > $(DOCS_BUILD)/includes/filtron.rst
|
||||
$(Q)./utils/morty.sh doc | cat > $(DOCS_BUILD)/includes/morty.rst
|
||||
|
||||
|
||||
$(GH_PAGES)::
|
||||
@echo "doc available at --> $(DOCS_URL)"
|
||||
|
||||
@ -94,12 +120,14 @@ useragents.update: pyenvinstall
|
||||
buildenv:
|
||||
$(Q)echo "build searx/brand.py"
|
||||
$(Q)echo "GIT_URL = '$(GIT_URL)'" > searx/brand.py
|
||||
$(Q)echo "GIT_BRANCH = '$(GIT_BRANCH)'" >> searx/brand.py
|
||||
$(Q)echo "ISSUE_URL = 'https://github.com/asciimoo/searx/issues'" >> searx/brand.py
|
||||
$(Q)echo "SEARX_URL = '$(SEARX_URL)'" >> searx/brand.py
|
||||
$(Q)echo "DOCS_URL = '$(DOCS_URL)'" >> searx/brand.py
|
||||
$(Q)echo "PUBLIC_INSTANCES = 'https://searx.space'" >> searx/brand.py
|
||||
$(Q)echo "build utils/brand.env"
|
||||
$(Q)echo "export GIT_URL='$(GIT_URL)'" > utils/brand.env
|
||||
$(Q)echo "export GIT_BRANCH='$(GIT_BRANCH)'" >> utils/brand.env
|
||||
$(Q)echo "export ISSUE_URL='https://github.com/asciimoo/searx/issues'" >> utils/brand.env
|
||||
$(Q)echo "export SEARX_URL='$(SEARX_URL)'" >> utils/brand.env
|
||||
$(Q)echo "export DOCS_URL='$(DOCS_URL)'" >> utils/brand.env
|
||||
@ -182,8 +210,7 @@ gecko.driver:
|
||||
# test
|
||||
# ----
|
||||
|
||||
PHONY += test test.pylint test.pep8 test.unit test.coverage test.robot
|
||||
|
||||
PHONY += test test.sh test.pylint test.pep8 test.unit test.coverage test.robot
|
||||
test: buildenv test.pylint test.pep8 test.unit gecko.driver test.robot
|
||||
|
||||
ifeq ($(PY),2)
|
||||
@ -191,6 +218,7 @@ test.pylint:
|
||||
@echo "LINT skip liniting py2"
|
||||
else
|
||||
# TODO: balance linting with pylint
|
||||
|
||||
test.pylint: pyenvinstall
|
||||
$(call cmd,pylint,\
|
||||
searx/preferences.py \
|
||||
@ -202,6 +230,17 @@ endif
|
||||
# E402 module level import not at top of file
|
||||
# W503 line break before binary operator
|
||||
|
||||
# ubu1604: uses shellcheck v0.3.7 (from 04/2015), no longer supported!
|
||||
test.sh:
|
||||
shellcheck -x -s bash utils/brand.env
|
||||
shellcheck -x utils/lib.sh
|
||||
shellcheck -x utils/filtron.sh
|
||||
shellcheck -x utils/searx.sh
|
||||
shellcheck -x utils/morty.sh
|
||||
shellcheck -x utils/lxc.sh
|
||||
shellcheck -x utils/lxc-searx.env
|
||||
shellcheck -x .config.sh
|
||||
|
||||
test.pep8: pyenvinstall
|
||||
@echo "TEST pep8"
|
||||
$(Q)$(PY_ENV_ACT); pep8 --exclude=searx/static --max-line-length=120 --ignore "E402,W503" searx tests
|
||||
|
41
docs/_themes/searx/static/searx.css
vendored
41
docs/_themes/searx/static/searx.css
vendored
@ -33,7 +33,7 @@ p.sidebar-title, .sidebar p {
|
||||
/* admonitions
|
||||
*/
|
||||
|
||||
div.admonition, div.topic {
|
||||
div.admonition, div.topic, div.toctree-wrapper {
|
||||
background-color: #fafafa;
|
||||
margin: 8px 0px;
|
||||
padding: 1em;
|
||||
@ -42,6 +42,16 @@ div.admonition, div.topic {
|
||||
border-right: none;
|
||||
border-bottom: none;
|
||||
border-left: 5pt solid #ccc;
|
||||
list-style-type: disclosure-closed;
|
||||
}
|
||||
|
||||
div.toctree-wrapper p.caption {
|
||||
font-weight: normal;
|
||||
font-size: 24px;
|
||||
margin: 0 0 10px 0;
|
||||
padding: 0;
|
||||
line-height: 1;
|
||||
display: inline;
|
||||
}
|
||||
|
||||
p.admonition-title:after {
|
||||
@ -128,3 +138,32 @@ caption {
|
||||
caption-side: top;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/* bugs since sphinx 3.1
|
||||
|
||||
See sphinx-doc project, PR 7838 & 7484 with elementary patch to the basic CSS:
|
||||
|
||||
- https://github.com/sphinx-doc/sphinx/issues/7838#issuecomment-646009605
|
||||
- https://github.com/sphinx-doc/sphinx/pull/7484#issuecomment-646058972
|
||||
|
||||
*/
|
||||
|
||||
li > p:first-child {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
li > p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.admonition dl {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
div.sidebar {
|
||||
clear: none;
|
||||
}
|
||||
|
||||
div.admonition, div.topic, pre {
|
||||
clear: none;
|
||||
}
|
||||
|
@ -4,11 +4,11 @@ digraph G {
|
||||
edge [fontname="Sans"];
|
||||
|
||||
browser [label="Browser", shape=Mdiamond];
|
||||
rp [label="Reverse Proxy", href="url to configure reverse proxy"];
|
||||
filtron [label="Filtron", href="https://github.com/asciimoo/filtron"];
|
||||
morty [label="Morty", href="https://github.com/asciimoo/morty"];
|
||||
rp [label="Reverse Proxy", href="https://asciimoo.github.io/searx/utils/filtron.sh.html#public-reverse-proxy"];
|
||||
filtron [label="Filtron", href="https://asciimoo.github.io/searx/utils/filtron.sh.html"];
|
||||
morty [label="Morty", href="https://asciimoo.github.io/searx/utils/morty.sh.html"];
|
||||
static [label="Static files", href="url to configure static files"];
|
||||
uwsgi [label="uwsgi", href="url to configure uwsgi"]
|
||||
uwsgi [label="uwsgi", href="https://asciimoo.github.io/searx/utils/searx.sh.html"]
|
||||
searx1 [label="Searx #1"];
|
||||
searx2 [label="Searx #2"];
|
||||
searx3 [label="Searx #3"];
|
||||
|
@ -4,17 +4,21 @@
|
||||
Architecture
|
||||
============
|
||||
|
||||
.. sidebar:: Needs work!
|
||||
.. sidebar:: Further reading
|
||||
|
||||
This article needs some work / Searx is a collaborative effort. If you have
|
||||
any contribution, feel welcome to send us your :pull:`PR <../pulls>`, see
|
||||
:ref:`how to contribute`.
|
||||
- Reverse Proxy: :ref:`Apache <apache searx site>` & :ref:`nginx <nginx searx
|
||||
site>`
|
||||
- Filtron: :ref:`searx filtron`
|
||||
- Morty: :ref:`searx morty`
|
||||
- uWSGI: :ref:`searx uwsgi`
|
||||
- Searx: :ref:`installation basic`
|
||||
|
||||
Herein you will find some hints and suggestions about typical architectures of
|
||||
searx infrastructures.
|
||||
|
||||
We start with a contribution from :pull:`@dalf <1776#issuecomment-567917320>`.
|
||||
It shows a *reference* setup for public searx instances.
|
||||
It shows a *reference* setup for public searx instances which can build up and
|
||||
maintained by the scripts from our :ref:`toolboxing`.
|
||||
|
||||
.. _arch public:
|
||||
|
||||
|
@ -9,8 +9,27 @@ Buildhosts
|
||||
If you have any contribution send us your :pull:`PR <../pulls>`, see
|
||||
:ref:`how to contribute`.
|
||||
|
||||
.. contents:: Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: entry
|
||||
|
||||
To get best results from build, its recommend to install additional packages
|
||||
on build hosts.
|
||||
on build hosts (see :ref:`searx.sh`).::
|
||||
|
||||
sudo -H ./utils/searx.sh install buildhost
|
||||
|
||||
This will install packages needed by searx:
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START distro-packages
|
||||
:end-before: END distro-packages
|
||||
|
||||
and packages needed to build docuemtation and run tests:
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START build-packages
|
||||
:end-before: END build-packages
|
||||
|
||||
.. _docs build:
|
||||
|
||||
@ -35,8 +54,17 @@ processing additional packages are needed. The XeTeX_ needed not only for PDF
|
||||
creation, its also needed for :ref:`math` when HTML output is build.
|
||||
|
||||
To be able to do :ref:`sphinx:math-support` without CDNs, the math are rendered
|
||||
as images (``sphinx.ext.imgmath`` extension). If your docs build (``make
|
||||
docs``) shows warnings like this::
|
||||
as images (``sphinx.ext.imgmath`` extension).
|
||||
|
||||
Here is the extract from the :origin:`docs/conf.py` file, setting math renderer
|
||||
to ``imgmath``:
|
||||
|
||||
.. literalinclude:: ../conf.py
|
||||
:language: python
|
||||
:start-after: # sphinx.ext.imgmath setup
|
||||
:end-before: # sphinx.ext.imgmath setup END
|
||||
|
||||
If your docs build (``make docs``) shows warnings like this::
|
||||
|
||||
WARNING: dot(1) not found, for better output quality install \
|
||||
graphviz from http://www.graphviz.org
|
||||
@ -47,8 +75,6 @@ docs``) shows warnings like this::
|
||||
you need to install additional packages on your build host, to get better HTML
|
||||
output.
|
||||
|
||||
.. _system requirements:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
@ -92,12 +118,38 @@ For PDF output you also need:
|
||||
|
||||
$ sudo dnf install \
|
||||
texlive-collection-fontsrecommended texlive-collection-latex \
|
||||
dejavu-sans-fonts dejavu-serif-fonts dejavu-sans-mono-fonts
|
||||
dejavu-sans-fonts dejavu-serif-fonts dejavu-sans-mono-fonts \
|
||||
ImageMagick
|
||||
|
||||
.. _system requirements END:
|
||||
.. _sh lint:
|
||||
|
||||
.. literalinclude:: ../conf.py
|
||||
:language: python
|
||||
:start-after: # sphinx.ext.imgmath setup
|
||||
:end-before: # sphinx.ext.imgmath setup END
|
||||
Lint shell scripts
|
||||
==================
|
||||
|
||||
.. _ShellCheck: https://github.com/koalaman/shellcheck
|
||||
|
||||
To lint shell scripts, we use ShellCheck_ - A shell script static analysis tool.
|
||||
|
||||
.. SNIP sh lint requirements
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo apt install shellcheck
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo pacman -S shellcheck
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo dnf install ShellCheck
|
||||
|
||||
.. SNAP sh lint requirements
|
||||
|
@ -1,18 +1,51 @@
|
||||
|
||||
.. _searx filtron:
|
||||
|
||||
==========================
|
||||
How to protect an instance
|
||||
==========================
|
||||
|
||||
Searx depens on external search services. To avoid the abuse of these services
|
||||
.. sidebar:: further reading
|
||||
|
||||
- :ref:`filtron.sh`
|
||||
- :ref:`nginx searx site`
|
||||
|
||||
|
||||
.. contents:: Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: entry
|
||||
|
||||
.. _filtron: https://github.com/asciimoo/filtron
|
||||
|
||||
Searx depends on external search services. To avoid the abuse of these services
|
||||
it is advised to limit the number of requests processed by searx.
|
||||
|
||||
An application firewall, ``filtron`` solves exactly this problem. Information
|
||||
on how to install it can be found at the `project page of filtron
|
||||
<https://github.com/asciimoo/filtron>`__.
|
||||
An application firewall, filtron_ solves exactly this problem. Filtron is just
|
||||
a middleware between your web server (nginx, apache, ...) and searx, we describe
|
||||
such infratructures in chapter: :ref:`architecture`.
|
||||
|
||||
|
||||
filtron & go
|
||||
============
|
||||
|
||||
.. _Go: https://golang.org/
|
||||
.. _filtron README: https://github.com/asciimoo/filtron/blob/master/README.md
|
||||
|
||||
Filtron needs Go_ installed. If Go_ is preinstalled, filtron_ is simply
|
||||
installed by ``go get`` package management (see `filtron README`_). If you use
|
||||
filtron as middleware, a more isolated setup is recommended. To simplify such
|
||||
an installation and the maintenance of, use our script :ref:`filtron.sh`.
|
||||
|
||||
.. _Sample configuration of filtron:
|
||||
|
||||
Sample configuration of filtron
|
||||
===============================
|
||||
|
||||
.. sidebar:: Tooling box
|
||||
|
||||
- :origin:`/etc/filtron/rules.json <utils/templates/etc/filtron/rules.json>`
|
||||
|
||||
An example configuration can be find below. This configuration limits the access
|
||||
of:
|
||||
|
||||
@ -24,105 +57,104 @@ of:
|
||||
|
||||
.. code:: json
|
||||
|
||||
[{
|
||||
"name":"search request",
|
||||
"filters":[
|
||||
"Param:q",
|
||||
"Path=^(/|/search)$"
|
||||
],
|
||||
"interval":"<time-interval-in-sec (int)>",
|
||||
"limit":"<max-request-number-in-interval (int)>",
|
||||
"subrules":[
|
||||
{
|
||||
"name":"roboagent limit",
|
||||
"interval":"<time-interval-in-sec (int)>",
|
||||
"limit":"<max-request-number-in-interval (int)>",
|
||||
"filters":[
|
||||
"Header:User-Agent=(curl|cURL|Wget|python-requests|Scrapy|FeedFetcher|Go-http-client)"
|
||||
[
|
||||
{
|
||||
"name": "search request",
|
||||
"filters": [
|
||||
"Param:q",
|
||||
"Path=^(/|/search)$"
|
||||
],
|
||||
"actions":[
|
||||
{
|
||||
"name":"block",
|
||||
"params":{
|
||||
"message":"Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
"interval": "<time-interval-in-sec (int)>"
|
||||
"limit": "<max-request-number-in-interval (int)>",
|
||||
"subrules": [
|
||||
{
|
||||
"name": "missing Accept-Language",
|
||||
"filters": ["!Header:Accept-Language"],
|
||||
"limit": "<max-request-number-in-interval (int)>",
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{"name":"log"},
|
||||
{"name": "block",
|
||||
"params": {"message": "Rate limit exceeded"}}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "suspiciously Connection=close header",
|
||||
"filters": ["Header:Connection=close"],
|
||||
"limit": "<max-request-number-in-interval (int)>",
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{"name":"log"},
|
||||
{"name": "block",
|
||||
"params": {"message": "Rate limit exceeded"}}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "IP limit",
|
||||
"interval": "<time-interval-in-sec (int)>"
|
||||
"limit": "<max-request-number-in-interval (int)>",
|
||||
"stop": true,
|
||||
"aggregations": [
|
||||
"Header:X-Forwarded-For"
|
||||
],
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rss/json limit",
|
||||
"filters": [
|
||||
"Param:format=(csv|json|rss)"
|
||||
],
|
||||
"interval": "<time-interval-in-sec (int)>"
|
||||
"limit": "<max-request-number-in-interval (int)>",
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "useragent limit",
|
||||
"interval": "<time-interval-in-sec (int)>"
|
||||
"limit": "<max-request-number-in-interval (int)>",
|
||||
"aggregations": [
|
||||
"Header:User-Agent"
|
||||
],
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"botlimit",
|
||||
"limit":0,
|
||||
"stop":true,
|
||||
"filters":[
|
||||
"Header:User-Agent=(Googlebot|bingbot|Baiduspider|yacybot|YandexMobileBot|YandexBot|Yahoo! Slurp|MJ12bot|AhrefsBot|archive.org_bot|msnbot|MJ12bot|SeznamBot|linkdexbot|Netvibes|SMTBot|zgrab|James BOT)"
|
||||
],
|
||||
"actions":[
|
||||
{
|
||||
"name":"block",
|
||||
"params":{
|
||||
"message":"Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"IP limit",
|
||||
"interval":"<time-interval-in-sec (int)>",
|
||||
"limit":"<max-request-number-in-interval (int)>",
|
||||
"stop":true,
|
||||
"aggregations":[
|
||||
"Header:X-Forwarded-For"
|
||||
],
|
||||
"actions":[
|
||||
{
|
||||
"name":"block",
|
||||
"params":{
|
||||
"message":"Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"rss/json limit",
|
||||
"interval":"<time-interval-in-sec (int)>",
|
||||
"limit":"<max-request-number-in-interval (int)>",
|
||||
"stop":true,
|
||||
"filters":[
|
||||
"Param:format=(csv|json|rss)"
|
||||
],
|
||||
"actions":[
|
||||
{
|
||||
"name":"block",
|
||||
"params":{
|
||||
"message":"Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name":"useragent limit",
|
||||
"interval":"<time-interval-in-sec (int)>",
|
||||
"limit":"<max-request-number-in-interval (int)>",
|
||||
"aggregations":[
|
||||
"Header:User-Agent"
|
||||
],
|
||||
"actions":[
|
||||
{
|
||||
"name":"block",
|
||||
"params":{
|
||||
"message":"Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}]
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
.. _filtron route request:
|
||||
|
||||
Route request through filtron
|
||||
=============================
|
||||
|
||||
.. sidebar:: further reading
|
||||
|
||||
- :ref:`filtron.sh overview`
|
||||
- :ref:`installation nginx`
|
||||
- :ref:`installation apache`
|
||||
|
||||
Filtron can be started using the following command:
|
||||
|
||||
.. code:: sh
|
||||
@ -136,13 +168,24 @@ Use it along with ``nginx`` with the following example configuration.
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
location / {
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_pass http://127.0.0.1:4004/;
|
||||
# https://example.org/searx
|
||||
|
||||
location /searx {
|
||||
proxy_pass http://127.0.0.1:4004/;
|
||||
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header Connection $http_connection;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Script-Name /searx;
|
||||
}
|
||||
|
||||
location /searx/static {
|
||||
/usr/local/searx/searx-src/searx/static;
|
||||
}
|
||||
|
||||
|
||||
Requests are coming from port 4004 going through filtron and then forwarded to
|
||||
port 8888 where a searx is being run.
|
||||
port 8888 where a searx is being run. For a complete setup see: :ref:`nginx
|
||||
searx site`.
|
||||
|
@ -3,9 +3,16 @@ Administrator documentation
|
||||
===========================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:maxdepth: 2
|
||||
:caption: Contents
|
||||
|
||||
installation
|
||||
installation-searx
|
||||
installation-uwsgi
|
||||
installation-nginx
|
||||
installation-apache
|
||||
installation-docker
|
||||
update-searx
|
||||
settings
|
||||
api
|
||||
architecture
|
||||
|
514
docs/admin/installation-apache.rst
Normal file
514
docs/admin/installation-apache.rst
Normal file
@ -0,0 +1,514 @@
|
||||
.. _installation apache:
|
||||
|
||||
===================
|
||||
Install with apache
|
||||
===================
|
||||
|
||||
.. _Apache: https://httpd.apache.org/
|
||||
.. _Apache Debian:
|
||||
https://cwiki.apache.org/confluence/display/HTTPD/DistrosDefaultLayout#DistrosDefaultLayout-Debian,Ubuntu(Apachehttpd2.x):
|
||||
.. _README.Debian:
|
||||
https://salsa.debian.org/apache-team/apache2/raw/master/debian/apache2.README.Debian
|
||||
.. _Apache Arch Linux:
|
||||
https://wiki.archlinux.org/index.php/Apache_HTTP_Server
|
||||
.. _Apache Fedora:
|
||||
https://docs.fedoraproject.org/en-US/quick-docs/getting-started-with-apache-http-server/index.html
|
||||
.. _Apache directives:
|
||||
https://httpd.apache.org/docs/trunk/mod/directives.html
|
||||
.. _Getting Started:
|
||||
https://httpd.apache.org/docs/current/en/getting-started.html
|
||||
.. _Terms Used to Describe Directives:
|
||||
https://httpd.apache.org/docs/current/en/mod/directive-dict.html
|
||||
.. _Configuration Files:
|
||||
https://httpd.apache.org/docs/current/en/configuring.html
|
||||
.. _ProxyPreserveHost: https://httpd.apache.org/docs/trunk/mod/mod_proxy.html#proxypreservehost
|
||||
.. _LoadModule:
|
||||
https://httpd.apache.org/docs/2.4/mod/mod_so.html#loadmodule
|
||||
.. _DocumentRoot:
|
||||
https://httpd.apache.org/docs/trunk/mod/core.html#documentroot
|
||||
.. _Location:
|
||||
https://httpd.apache.org/docs/trunk/mod/core.html#location
|
||||
.. _uWSGI Apache support:
|
||||
https://uwsgi-docs.readthedocs.io/en/latest/Apache.html
|
||||
.. _mod_proxy_uwsgi:
|
||||
https://uwsgi-docs.readthedocs.io/en/latest/Apache.html#mod-proxy-uwsgi
|
||||
|
||||
.. sidebar:: further read
|
||||
|
||||
- `Apache Arch Linux`_
|
||||
- `Apache Debian`_ and `README.Debian`_
|
||||
- `Apache Fedora`_
|
||||
- `Apache directives`_
|
||||
|
||||
.. contents:: Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: entry
|
||||
|
||||
----
|
||||
|
||||
**Install** :ref:`apache searx site` using :ref:`filtron.sh <filtron.sh overview>`
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ sudo -H ./utils/filtron.sh apache install
|
||||
|
||||
**Install** :ref:`apache searx site` using :ref:`morty.sh <morty.sh overview>`
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ sudo -H ./utils/morty.sh apache install
|
||||
|
||||
----
|
||||
|
||||
The apache HTTP server
|
||||
======================
|
||||
|
||||
If Apache_ is not installed, install it now. If apache_ is new to you, the
|
||||
`Getting Started`_, `Configuration Files`_ and `Terms Used to Describe
|
||||
Directives`_ documentation gives first orientation. There is also a list of
|
||||
`Apache directives`_ *to keep in the pocket*.
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H apt-get install apache2
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H pacman -S apache
|
||||
sudo -H systemctl enable httpd
|
||||
sudo -H systemctl start http
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H dnf install httpd
|
||||
sudo -H systemctl enable httpd
|
||||
sudo -H systemctl start httpd
|
||||
|
||||
Now at http://localhost you should see any kind of *Welcome* or *Test* page.
|
||||
How this default intro site is configured, depends on the linux distribution
|
||||
(compare `Apache directives`_).
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code:: sh
|
||||
|
||||
less /etc/apache2/sites-enabled/000-default.conf
|
||||
|
||||
In this file, there is a line setting the `DocumentRoot`_ directive:
|
||||
|
||||
.. code:: apache
|
||||
|
||||
DocumentRoot /var/www/html
|
||||
|
||||
And the *welcome* page is the HTML file at ``/var/www/html/index.html``.
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. code:: sh
|
||||
|
||||
less /etc/httpd/conf/httpd.conf
|
||||
|
||||
In this file, there is a line setting the `DocumentRoot`_ directive:
|
||||
|
||||
.. code:: apache
|
||||
|
||||
DocumentRoot "/srv/http"
|
||||
<Directory "/srv/http">
|
||||
Options Indexes FollowSymLinks
|
||||
AllowOverride None
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
The *welcome* page of Arch Linux is a page showing directory located at
|
||||
``DocumentRoot``. This is *directory* page is generated by the Module
|
||||
`mod_autoindex <https://httpd.apache.org/docs/2.4/mod/mod_autoindex.html>`_:
|
||||
|
||||
.. code:: apache
|
||||
|
||||
LoadModule autoindex_module modules/mod_autoindex.so
|
||||
...
|
||||
Include conf/extra/httpd-autoindex.conf
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. code:: sh
|
||||
|
||||
less /etc/httpd/conf/httpd.conf
|
||||
|
||||
In this file, there is a line setting the ``DocumentRoot`` directive:
|
||||
|
||||
.. code:: apache
|
||||
|
||||
DocumentRoot "/var/www/html"
|
||||
...
|
||||
<Directory "/var/www">
|
||||
AllowOverride None
|
||||
# Allow open access:
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
On fresh installations, the ``/var/www`` is empty and the *default
|
||||
welcome page* is shown, the configuration is located at::
|
||||
|
||||
less /etc/httpd/conf.d/welcome.conf
|
||||
|
||||
.. _apache searx site:
|
||||
|
||||
Apache Reverse Proxy
|
||||
====================
|
||||
|
||||
.. sidebar:: public to the internet?
|
||||
|
||||
If your searx instance is public, stop here and first install :ref:`filtron
|
||||
reverse proxy <filtron.sh>` and :ref:`result proxy morty <morty.sh>`, see
|
||||
:ref:`installation scripts`. If already done, follow setup: *searx via
|
||||
filtron plus morty*.
|
||||
|
||||
To setup a Apache revers proxy you have to enable the *headers* and *proxy*
|
||||
modules and create a `Location`_ configuration for the searx site. In most
|
||||
distributions you have to un-comment the lines in the main configuration file,
|
||||
except in :ref:`The Debian Layout`.
|
||||
|
||||
To pass the HTTP HOST header
|
||||
With ProxyPreserveHost_ the incoming Host HTTP request header is passed to the
|
||||
proxied host.
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
In the Apache setup, enable headers and proxy modules:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H a2enmod headers
|
||||
sudo -H a2enmod proxy
|
||||
sudo -H a2enmod proxy_http
|
||||
|
||||
In :ref:`The Debian Layout` you create a ``searx.conf`` with the
|
||||
``<Location /searx >`` directive and save this file in the *sites
|
||||
available* folder at ``/etc/apache2/sites-available``. To enable the
|
||||
``searx.conf`` use :man:`a2ensite`:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H a2ensite searx.conf
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
In the ``/etc/httpd/conf/httpd.conf`` file, activate headers and proxy
|
||||
modules (LoadModule_):
|
||||
|
||||
.. code:: apache
|
||||
|
||||
FIXME needs test
|
||||
|
||||
LoadModule headers_module modules/mod_headers.so
|
||||
LoadModule proxy_module modules/mod_proxy.so
|
||||
LoadModule proxy_http_module modules/mod_proxy_http.so
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
In the ``/etc/httpd/conf/httpd.conf`` file, activate headers and proxy
|
||||
modules (LoadModule_):
|
||||
|
||||
.. code:: apache
|
||||
|
||||
FIXME needs test
|
||||
|
||||
LoadModule headers_module modules/mod_headers.so
|
||||
LoadModule proxy_module modules/mod_proxy.so
|
||||
LoadModule proxy_http_module modules/mod_proxy_http.so
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: searx via filtron plus morty
|
||||
|
||||
Use this setup, if your instance is public to the internet, compare
|
||||
figure: :ref:`architecture <arch public>` and :ref:`installation scripts`.
|
||||
|
||||
1. Configure a reverse proxy for :ref:`filtron <filtron.sh>`, listening on
|
||||
*localhost 4004* (:ref:`filtron route request`):
|
||||
|
||||
.. code:: apache
|
||||
|
||||
<Location /searx >
|
||||
|
||||
# SetEnvIf Request_URI "/searx" dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
Require all granted
|
||||
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
#Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyPass http://127.0.0.1:4004
|
||||
RequestHeader set X-Script-Name /searx
|
||||
|
||||
</Location>
|
||||
|
||||
2. Configure reverse proxy for :ref:`morty <searx morty>`, listening on
|
||||
*localhost 3000*
|
||||
|
||||
.. code:: apache
|
||||
|
||||
ProxyPreserveHost On
|
||||
|
||||
<Location /morty >
|
||||
|
||||
# SetEnvIf Request_URI "/morty" dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
Require all granted
|
||||
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
#Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
ProxyPass http://127.0.0.1:3000
|
||||
RequestHeader set X-Script-Name /morty
|
||||
|
||||
</Location>
|
||||
|
||||
Note that reverse proxy advised to be used in case of single-user or
|
||||
low-traffic instances. For a fully result proxification add :ref:`morty's
|
||||
<searx morty>` **public URL** to your :origin:`searx/settings.yml`:
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
result_proxy:
|
||||
# replace example.org with your server's public name
|
||||
url : https://example.org/morty
|
||||
|
||||
server:
|
||||
image_proxy : True
|
||||
|
||||
uWSGI support
|
||||
=============
|
||||
|
||||
Be warned, with this setup, your instance isn't :ref:`protected <searx
|
||||
filtron>`, nevertheless it is good enough for intranet usage. In modern Linux
|
||||
distributions, the `mod_proxy_uwsgi`_ is compiled into the *normal* apache
|
||||
package and you need to install only the :ref:`uWSGI <searx uwsgi>` package:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H apt-get install uwsgi
|
||||
|
||||
# Ubuntu =< 18.04
|
||||
sudo -H apt-get install libapache2-mod-proxy-uwsgi
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H pacman -S uwsgi
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H dnf install uwsgi
|
||||
|
||||
The next example shows a configuration using the `uWSGI Apache support`_ via
|
||||
unix sockets and `mod_proxy_uwsgi`_.
|
||||
|
||||
For socket communication, you have to activate ``socket =
|
||||
/run/uwsgi/app/searx/socket`` and comment out the ``http = 127.0.0.1:8888``
|
||||
configuration in your :ref:`uwsgi ini file <uwsgi configuration>`. If not
|
||||
already exists, create a folder for the unix sockets, which can be used by the
|
||||
searx account (see :ref:`create searx user`):
|
||||
|
||||
.. code:: bash
|
||||
|
||||
sudo -H mkdir -p /run/uwsgi/app/searx/
|
||||
sudo -H chown -R searx:searx /run/uwsgi/app/searx/
|
||||
|
||||
If the server is public; to limit access to your intranet replace ``Allow from
|
||||
all`` directive and replace ``192.168.0.0/16`` with your subnet IP/class.
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code:: apache
|
||||
|
||||
LoadModule headers_module /usr/lib/apache2/mod_headers.so
|
||||
LoadModule proxy_module /usr/lib/apache2/modules/mod_proxy.so
|
||||
LoadModule proxy_uwsgi_module /usr/lib/apache2/modules/mod_proxy_uwsgi.so
|
||||
|
||||
# SetEnvIf Request_URI /searx dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
<Location /searx>
|
||||
|
||||
Require all granted
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
# Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyPass unix:/run/uwsgi/app/searx/socket|uwsgi://uwsgi-uds-searx/
|
||||
|
||||
</Location>
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. code:: apache
|
||||
|
||||
FIXME needs test
|
||||
|
||||
LoadModule proxy_module modules/mod_proxy.so
|
||||
LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so
|
||||
|
||||
# SetEnvIf Request_URI /searx dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
<Location /searx>
|
||||
|
||||
Require all granted
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
# Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyPass unix:/run/uwsgi/app/searx/socket|uwsgi://uwsgi-uds-searx/
|
||||
|
||||
</Location>
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. code:: apache
|
||||
|
||||
FIXME needs test
|
||||
|
||||
LoadModule proxy_module modules/mod_proxy.so
|
||||
LoadModule proxy_uwsgi_module modules/mod_proxy_uwsgi.so
|
||||
<IfModule proxy_uwsgi_module>
|
||||
|
||||
# SetEnvIf Request_URI /searx dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
<Location /searx>
|
||||
|
||||
Require all granted
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
# Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyPass unix:/run/uwsgi/app/searx/socket|uwsgi://uwsgi-uds-searx/
|
||||
|
||||
</Location>
|
||||
|
||||
</IfModule>
|
||||
|
||||
.. group-tab:: old mod_wsgi
|
||||
|
||||
We show this only for historical reasons, DON'T USE `mod_uwsgi
|
||||
<https://uwsgi-docs.readthedocs.io/en/latest/Apache.html#mod-uwsgi>`_.
|
||||
ANYMORE!
|
||||
|
||||
.. code:: apache
|
||||
|
||||
<IfModule mod_uwsgi.c>
|
||||
|
||||
# SetEnvIf Request_URI "/searx" dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
<Location /searx >
|
||||
|
||||
Require all granted
|
||||
|
||||
Options FollowSymLinks Indexes
|
||||
SetHandler uwsgi-handler
|
||||
uWSGISocket /run/uwsgi/app/searx/socket
|
||||
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
# Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
</Location>
|
||||
|
||||
</IfModule>
|
||||
|
||||
.. _restart apache:
|
||||
|
||||
Restart service
|
||||
===============
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H systemctl restart apache2
|
||||
sudo -H service uwsgi restart searx
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H systemctl restart httpd
|
||||
sudo -H systemctl restart uwsgi@searx
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H systemctl restart httpd
|
||||
sudo -H touch /etc/uwsgi.d/searx.ini
|
||||
|
||||
|
||||
disable logs
|
||||
============
|
||||
|
||||
For better privacy you can disable Apache logs. In the examples above activate
|
||||
one of the lines and `restart apache`_::
|
||||
|
||||
|
||||
# SetEnvIf Request_URI "/searx" dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
The ``CustomLog`` directive disable logs for the whole (virtual) server, use it
|
||||
when the URL of the service does not have a path component (``/searx``) / is
|
||||
located at root (``/``).
|
||||
|
||||
.. _The Debian Layout:
|
||||
|
||||
The Debian Layout
|
||||
=================
|
||||
|
||||
Be aware that the Debian layout is quite different from the standard Apache
|
||||
configuration. For details look at the README.Debian_
|
||||
(``/usr/share/doc/apache2/README.Debian.gz``). Some commands you should know on
|
||||
Debian:
|
||||
|
||||
* :man:`apache2ctl`: Apache HTTP server control interface
|
||||
* :man:`a2enmod`, :man:`a2dismod`: switch on/off modules
|
||||
* :man:`a2enconf`, :man:`a2disconf`: switch on/off configurations
|
||||
* :man:`a2ensite`, :man:`a2dissite`: switch on/off sites
|
28
docs/admin/installation-docker.rst
Normal file
28
docs/admin/installation-docker.rst
Normal file
@ -0,0 +1,28 @@
|
||||
.. _installation docker:
|
||||
|
||||
===================
|
||||
Docker installation
|
||||
===================
|
||||
|
||||
.. contents:: Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: entry
|
||||
|
||||
Make sure you have installed Docker. For instance, you can deploy searx like this:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
docker pull wonderfall/searx
|
||||
docker run -d --name searx -p $PORT:8888 wonderfall/searx
|
||||
|
||||
Go to ``http://localhost:$PORT``.
|
||||
|
||||
See https://hub.docker.com/r/wonderfall/searx/ for more informations. It's also
|
||||
possible to build searx from the embedded Dockerfile.
|
||||
|
||||
.. code:: sh
|
||||
|
||||
git clone https://github.com/asciimoo/searx.git
|
||||
cd searx
|
||||
docker build -t whatever/searx .
|
381
docs/admin/installation-nginx.rst
Normal file
381
docs/admin/installation-nginx.rst
Normal file
@ -0,0 +1,381 @@
|
||||
.. _installation nginx:
|
||||
|
||||
==================
|
||||
Install with nginx
|
||||
==================
|
||||
|
||||
.. _nginx:
|
||||
https://docs.nginx.com/nginx/admin-guide/
|
||||
.. _nginx server configuration:
|
||||
https://docs.nginx.com/nginx/admin-guide/web-server/web-server/#setting-up-virtual-servers
|
||||
.. _nginx beginners guide:
|
||||
http://nginx.org/en/docs/beginners_guide.html
|
||||
.. _Getting Started wiki:
|
||||
https://www.nginx.com/resources/wiki/start/
|
||||
.. _uWSGI support from nginx:
|
||||
https://uwsgi-docs.readthedocs.io/en/latest/Nginx.html
|
||||
.. _uwsgi_params:
|
||||
https://uwsgi-docs.readthedocs.io/en/latest/Nginx.html#configuring-nginx
|
||||
.. _SCRIPT_NAME:
|
||||
https://werkzeug.palletsprojects.com/en/1.0.x/wsgi/#werkzeug.wsgi.get_script_name
|
||||
|
||||
.. sidebar:: further reading
|
||||
|
||||
- nginx_
|
||||
- `nginx beginners guide`_
|
||||
- `nginx server configuration`_
|
||||
- `Getting Started wiki`_
|
||||
- `uWSGI support from nginx`_
|
||||
|
||||
.. contents:: Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: entry
|
||||
|
||||
----
|
||||
|
||||
**Install** :ref:`nginx searx site` using :ref:`filtron.sh <filtron.sh overview>`
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ sudo -H ./utils/filtron.sh nginx install
|
||||
|
||||
**Install** :ref:`nginx searx site` using :ref:`morty.sh <morty.sh overview>`
|
||||
|
||||
.. code:: bash
|
||||
|
||||
$ sudo -H ./utils/morty.sh nginx install
|
||||
|
||||
----
|
||||
|
||||
|
||||
The nginx HTTP server
|
||||
=====================
|
||||
|
||||
If nginx_ is not installed (uwsgi will not work with the package nginx-light),
|
||||
install it now.
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H apt-get install nginx
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
sudo -H pacman -S nginx-mainline
|
||||
sudo -H systemctl enable nginx
|
||||
sudo -H systemctl start nginx
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
sudo -H dnf install nginx
|
||||
sudo -H systemctl enable nginx
|
||||
sudo -H systemctl start nginx
|
||||
|
||||
Now at http://localhost you should see a *Welcome to nginx!* page, on Fedora you
|
||||
see a *Fedora Webserver - Test Page*. The test page comes from the default
|
||||
`nginx server configuration`_. How this default intro site is configured,
|
||||
depends on the linux distribution:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code:: sh
|
||||
|
||||
less /etc/nginx/nginx.conf
|
||||
|
||||
there is a line including site configurations from:
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
include /etc/nginx/sites-enabled/*;
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
less /etc/nginx/nginx.conf
|
||||
|
||||
in there is a configuration section named ``server``:
|
||||
|
||||
.. code-block:: nginx
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
# ...
|
||||
}
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
less /etc/nginx/nginx.conf
|
||||
|
||||
there is a line including site configurations from:
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
include /etc/nginx/conf.d/*.conf;
|
||||
|
||||
.. _nginx searx site:
|
||||
|
||||
A nginx searx site
|
||||
==================
|
||||
|
||||
.. sidebar:: public to the internet?
|
||||
|
||||
If your searx instance is public, stop here and first install :ref:`filtron
|
||||
reverse proxy <filtron.sh>` and :ref:`result proxy morty <morty.sh>`, see
|
||||
:ref:`installation scripts`. If already done, follow setup: *searx via
|
||||
filtron plus morty*.
|
||||
|
||||
Now you have to create a configuration for the searx site. If nginx_ is new to
|
||||
you, the `nginx beginners guide`_ is a good starting point and the `Getting
|
||||
Started wiki`_ is always a good resource *to keep in the pocket*.
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
Create configuration at ``/etc/nginx/sites-available/searx`` and place a
|
||||
symlink to sites-enabled:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H ln -s /etc/nginx/sites-available/searx /etc/nginx/sites-enabled/searx
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
In the ``/etc/nginx/nginx.conf`` file, replace the configuration section
|
||||
named ``server``.
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
Create configuration at ``/etc/nginx/conf.d/searx`` and place a
|
||||
symlink to sites-enabled:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: searx via filtron plus morty
|
||||
|
||||
Use this setup, if your instance is public to the internet, compare
|
||||
figure: :ref:`architecture <arch public>` and :ref:`installation scripts`.
|
||||
|
||||
1. Configure a reverse proxy for :ref:`filtron <filtron.sh>`, listening on
|
||||
*localhost 4004* (:ref:`filtron route request`):
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
# https://example.org/searx
|
||||
|
||||
location /searx {
|
||||
proxy_pass http://127.0.0.1:4004/;
|
||||
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header Connection $http_connection;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Script-Name /searx;
|
||||
}
|
||||
|
||||
location /searx/static {
|
||||
/usr/local/searx/searx-src/searx/static;
|
||||
}
|
||||
|
||||
|
||||
2. Configure reverse proxy for :ref:`morty <searx morty>`, listening on
|
||||
*localhost 3000*:
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
# https://example.org/morty
|
||||
|
||||
location /morty {
|
||||
proxy_pass http://127.0.0.1:3000/;
|
||||
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header Connection $http_connection;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
}
|
||||
|
||||
Note that reverse proxy advised to be used in case of single-user or
|
||||
low-traffic instances. For a fully result proxification add :ref:`morty's
|
||||
<searx morty>` **public URL** to your :origin:`searx/settings.yml`:
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
result_proxy:
|
||||
# replace example.org with your server's public name
|
||||
url : https://example.org/morty
|
||||
|
||||
server:
|
||||
image_proxy : True
|
||||
|
||||
|
||||
.. group-tab:: proxy or uWSGI
|
||||
|
||||
Be warned, with this setup, your instance isn't :ref:`protected <searx
|
||||
filtron>`. Nevertheless it is good enough for intranet usage and it is a
|
||||
excellent example of; *how different services can be set up*. The next
|
||||
example shows a reverse proxy configuration wrapping the :ref:`searx-uWSGI
|
||||
application <uwsgi configuration>`, listening on ``http =
|
||||
127.0.0.1:8888``.
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
# https://hostname.local/
|
||||
|
||||
location / {
|
||||
proxy_pass http://127.0.0.1:8888;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Connection $http_connection;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
Alternatively you can use the `uWSGI support from nginx`_ via unix
|
||||
sockets. For socket communication, you have to activate ``socket =
|
||||
/run/uwsgi/app/searx/socket`` and comment out the ``http =
|
||||
127.0.0.1:8888`` configuration in your :ref:`uwsgi ini file <uwsgi
|
||||
configuration>`.
|
||||
|
||||
The example shows a nginx virtual ``server`` configuration, listening on
|
||||
port 80 (IPv4 and IPv6 http://[::]:80). The uWSGI app is configured at
|
||||
location ``/`` by importing the `uwsgi_params`_ and passing requests to
|
||||
the uWSGI socket (``uwsgi_pass``). The ``server``\'s root points to the
|
||||
:ref:`searx-src clone <searx-src>` and wraps directly the
|
||||
:origin:`searx/static/` content at ``location /static``.
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
server {
|
||||
# replace hostname.local with your server's name
|
||||
server_name hostname.local;
|
||||
|
||||
listen 80;
|
||||
listen [::]:80;
|
||||
|
||||
location / {
|
||||
include uwsgi_params;
|
||||
uwsgi_pass unix:/run/uwsgi/app/searx/socket;
|
||||
}
|
||||
|
||||
root /usr/local/searx/searx-src/searx;
|
||||
location /static { }
|
||||
}
|
||||
|
||||
If not already exists, create a folder for the unix sockets, which can be
|
||||
used by the searx account:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
mkdir -p /run/uwsgi/app/searx/
|
||||
sudo -H chown -R searx:searx /run/uwsgi/app/searx/
|
||||
|
||||
.. group-tab:: \.\. at subdir URL
|
||||
|
||||
Be warned, with these setups, your instance isn't :ref:`protected <searx
|
||||
filtron>`. The examples are just here to demonstrate how to export the
|
||||
searx application from a subdirectory URL ``https://example.org/searx/``.
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
# https://hostname.local/searx
|
||||
|
||||
location /searx {
|
||||
proxy_pass http://127.0.0.1:8888;
|
||||
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header Connection $http_connection;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Script-Name /searx;
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
location /searx/static {
|
||||
alias /usr/local/searx/searx-src/searx/static;
|
||||
}
|
||||
|
||||
The ``X-Script-Name /searx`` is needed by the searx implementation to
|
||||
calculate relative URLs correct. The next example shows a uWSGI
|
||||
configuration. Since there are no HTTP headers in a (u)WSGI protocol, the
|
||||
value is shipped via the SCRIPT_NAME_ in the WSGI environment.
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
# https://hostname.local/searx
|
||||
|
||||
location /searx {
|
||||
uwsgi_param SCRIPT_NAME /searx;
|
||||
include uwsgi_params;
|
||||
uwsgi_pass unix:/run/uwsgi/app/searx/socket;
|
||||
}
|
||||
|
||||
location /searx/static {
|
||||
alias /usr/local/searx/searx-src/searx;
|
||||
}
|
||||
|
||||
For searx to work correctly the ``base_url`` must be set in the
|
||||
:origin:`searx/settings.yml`.
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
server:
|
||||
# replace example.org with your server's public name
|
||||
base_url : https://example.org/searx/
|
||||
|
||||
|
||||
Restart service:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H systemctl restart nginx
|
||||
sudo -H service uwsgi restart searx
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H systemctl restart nginx
|
||||
sudo -H systemctl restart uwsgi@searx
|
||||
|
||||
.. group-tab:: Fedora
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H systemctl restart nginx
|
||||
sudo -H touch /etc/uwsgi.d/searx.ini
|
||||
|
||||
|
||||
Disable logs
|
||||
============
|
||||
|
||||
For better privacy you can disable nginx logs in ``/etc/nginx/nginx.conf``.
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
http {
|
||||
# ...
|
||||
access_log /dev/null;
|
||||
error_log /dev/null;
|
||||
# ...
|
||||
}
|
92
docs/admin/installation-searx.rst
Normal file
92
docs/admin/installation-searx.rst
Normal file
@ -0,0 +1,92 @@
|
||||
.. _installation basic:
|
||||
|
||||
=========================
|
||||
Step by step installation
|
||||
=========================
|
||||
|
||||
.. contents:: Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: entry
|
||||
|
||||
Step by step installation with virtualenv. For Ubuntu, be sure to have enable
|
||||
universe repository.
|
||||
|
||||
.. _install packages:
|
||||
|
||||
Install packages
|
||||
================
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START distro-packages
|
||||
:end-before: END distro-packages
|
||||
|
||||
.. hint::
|
||||
|
||||
This installs also the packages needed by :ref:`searx uwsgi`
|
||||
|
||||
.. _create searx user:
|
||||
|
||||
Create user
|
||||
===========
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START create user
|
||||
:end-before: END create user
|
||||
|
||||
.. _searx-src:
|
||||
|
||||
install searx & dependencies
|
||||
============================
|
||||
|
||||
Start a interactive shell from new created user and clone searx:
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START clone searx
|
||||
:end-before: END clone searx
|
||||
|
||||
In the same shell create *virtualenv*:
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START create virtualenv
|
||||
:end-before: END create virtualenv
|
||||
|
||||
To install searx's dependencies, exit the searx *bash* session you opened above
|
||||
and restart a new. Before install, first check if your *virualenv* was sourced
|
||||
from the login (*~/.profile*):
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START manage.sh update_packages
|
||||
:end-before: END manage.sh update_packages
|
||||
|
||||
.. tip::
|
||||
|
||||
Open a second terminal for the configuration tasks and left the ``(searx)$``
|
||||
terminal open for the tasks below.
|
||||
|
||||
Configuration
|
||||
==============
|
||||
|
||||
Create a copy of the :origin:`searx/settings.yml` configuration file in system's
|
||||
*/etc* folder. Configure like shown below -- replace ``searx@\$(uname -n)`` with
|
||||
a name of your choice -- *and/or* edit ``/etc/searx/settings.yml`` if necessary.
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START searx config
|
||||
:end-before: END searx config
|
||||
|
||||
Check
|
||||
=====
|
||||
|
||||
To check your searx setup, optional enable debugging and start the *webapp*.
|
||||
Searx looks at the exported environment ``$SEARX_SETTINGS_PATH`` for a
|
||||
configuration file.
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START check searx installation
|
||||
:end-before: END check searx installation
|
||||
|
||||
If everything works fine, hit ``[CTRL-C]`` to stop the *webapp* and disable the
|
||||
debug option in ``settings.yml``. You can now exit searx user bash (enter exit
|
||||
command twice). At this point searx is not demonized; uwsgi allows this.
|
||||
|
149
docs/admin/installation-uwsgi.rst
Normal file
149
docs/admin/installation-uwsgi.rst
Normal file
@ -0,0 +1,149 @@
|
||||
.. _searx uwsgi:
|
||||
|
||||
=====
|
||||
uwsgi
|
||||
=====
|
||||
|
||||
.. sidebar:: further reading
|
||||
|
||||
- `systemd.unit`_
|
||||
- `uWSGI Emperor`_
|
||||
|
||||
.. contents:: Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: entry
|
||||
|
||||
|
||||
.. _systemd.unit: https://www.freedesktop.org/software/systemd/man/systemd.unit.html
|
||||
.. _One service per app in systemd:
|
||||
https://uwsgi-docs.readthedocs.io/en/latest/Systemd.html#one-service-per-app-in-systemd
|
||||
.. _uWSGI Emperor:
|
||||
https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html
|
||||
.. _uwsgi ini file:
|
||||
https://uwsgi-docs.readthedocs.io/en/latest/Configuration.html#ini-files
|
||||
.. _systemd unit template:
|
||||
http://0pointer.de/blog/projects/instances.html
|
||||
|
||||
|
||||
Origin uWSGI
|
||||
============
|
||||
|
||||
How uWSGI is implemented by distributors is different. uWSGI itself
|
||||
recommend two methods
|
||||
|
||||
`systemd.unit`_ template files as described here `One service per app in systemd`_.
|
||||
|
||||
There is one `systemd unit template`_ and one `uwsgi ini file`_ per uWSGI-app
|
||||
placed at dedicated locations. Take archlinux and a searx.ini as example::
|
||||
|
||||
unit template --> /usr/lib/systemd/system/uwsgi@.service
|
||||
uwsgi ini files --> /etc/uwsgi/searx.ini
|
||||
|
||||
The searx app can be maintained as know from common systemd units::
|
||||
|
||||
systemctl enable uwsgi@searx
|
||||
systemctl start uwsgi@searx
|
||||
systemctl restart uwsgi@searx
|
||||
systemctl stop uwsgi@searx
|
||||
|
||||
The `uWSGI Emperor`_ mode which fits for maintaining a large range of uwsgi apps.
|
||||
|
||||
The Emperor mode is a special uWSGI instance that will monitor specific
|
||||
events. The Emperor mode (service) is started by a (common, not template)
|
||||
systemd unit. The Emperor service will scan specific directories for `uwsgi
|
||||
ini file`_\s (also know as *vassals*). If a *vassal* is added, removed or the
|
||||
timestamp is modified, a corresponding action takes place: a new uWSGI
|
||||
instance is started, reload or stopped. Take Fedora and a searx.ini as
|
||||
example::
|
||||
|
||||
to start a new searx instance create --> /etc/uwsgi.d/searx.ini
|
||||
to reload the instance edit timestamp --> touch /etc/uwsgi.d/searx.ini
|
||||
to stop instance remove ini --> rm /etc/uwsgi.d/searx.ini
|
||||
|
||||
Distributors
|
||||
============
|
||||
|
||||
The `uWSGI Emperor`_ mode and `systemd unit template`_ is what the distributors
|
||||
mostly offer their users, even if they differ in the way they implement both
|
||||
modes and their defaults. Another point they might differ is the packaging of
|
||||
plugins (if so, compare :ref:`install packages`) and what the default python
|
||||
interpreter is (python2 vs. python3).
|
||||
|
||||
Fedora starts a Emperor by default, while archlinux does not start any uwsgi
|
||||
service by default. Worth to know; debian (ubuntu) follow a complete different
|
||||
approach. *debian*: your are familiar with the apache infrastructure? .. they
|
||||
do similar for the uWSGI infrastructure (with less comfort), the folders are::
|
||||
|
||||
/etc/uwsgi/apps-available/
|
||||
/etc/uwsgi/apps-enabled/
|
||||
|
||||
The `uwsgi ini file`_ is enabled by a symbolic link::
|
||||
|
||||
ln -s /etc/uwsgi/apps-available/searx.ini /etc/uwsgi/apps-enabled/
|
||||
|
||||
From debian's documentation (``/usr/share/doc/uwsgi/README.Debian.gz``): You
|
||||
could control specific instance(s) by issuing::
|
||||
|
||||
service uwsgi <command> <confname> <confname> ...
|
||||
|
||||
sudo -H service uwsgi start searx
|
||||
sudo -H service uwsgi stop searx
|
||||
|
||||
My experience is, that this command is a bit buggy.
|
||||
|
||||
.. _uwsgi configuration:
|
||||
|
||||
Alltogether
|
||||
===========
|
||||
|
||||
Create the configuration ini-file according to your distribution (see below) and
|
||||
restart the uwsgi application.
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START searx uwsgi-description ubuntu-20.04
|
||||
:end-before: END searx uwsgi-description ubuntu-20.04
|
||||
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START searx uwsgi-description arch
|
||||
:end-before: END searx uwsgi-description arch
|
||||
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:start-after: START searx uwsgi-description fedora
|
||||
:end-before: END searx uwsgi-description fedora
|
||||
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:code: ini
|
||||
:start-after: START searx uwsgi-appini ubuntu-20.04
|
||||
:end-before: END searx uwsgi-appini ubuntu-20.04
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:code: ini
|
||||
:start-after: START searx uwsgi-appini arch
|
||||
:end-before: END searx uwsgi-appini arch
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
|
||||
:code: ini
|
||||
:start-after: START searx uwsgi-appini fedora
|
||||
:end-before: END searx uwsgi-appini fedora
|
||||
|
||||
|
@ -4,346 +4,63 @@
|
||||
Installation
|
||||
============
|
||||
|
||||
.. contents::
|
||||
:depth: 3
|
||||
*You're spoilt for choice*, choose your preferred method of installation.
|
||||
|
||||
Basic installation
|
||||
==================
|
||||
- :ref:`installation docker`
|
||||
- :ref:`installation scripts`
|
||||
- :ref:`installation basic`
|
||||
|
||||
Step by step installation for Debian/Ubuntu with virtualenv. For Ubuntu, be sure
|
||||
to have enable universe repository.
|
||||
The :ref:`installation basic` is good enough for intranet usage and it is a
|
||||
excellent illustration of *how a searx instance is build up*. If you place your
|
||||
instance public to the internet you should really consider to install a
|
||||
:ref:`filtron reverse proxy <filtron.sh>` and for privacy a :ref:`result proxy
|
||||
<morty.sh>` is mandatory.
|
||||
|
||||
Install packages:
|
||||
Therefore, if you do not have any special preferences, its recommend to use the
|
||||
:ref:`installation docker` or the `Installation scripts`_ from our :ref:`tooling
|
||||
box <toolboxing>` as described below.
|
||||
|
||||
.. code:: sh
|
||||
.. _installation scripts:
|
||||
|
||||
$ sudo -H apt-get install \
|
||||
git build-essential libxslt-dev \
|
||||
python-dev python-virtualenv python-babel \
|
||||
zlib1g-dev libffi-dev libssl-dev
|
||||
Installation scripts
|
||||
====================
|
||||
|
||||
Install searx:
|
||||
.. sidebar:: Update OS first!
|
||||
|
||||
.. code:: sh
|
||||
To avoid unwanted side effects, update your OS before installing searx.
|
||||
|
||||
cd /usr/local
|
||||
sudo -H git clone https://github.com/asciimoo/searx.git
|
||||
sudo -H useradd searx -d /usr/local/searx
|
||||
sudo -H chown searx:searx -R /usr/local/searx
|
||||
The following will install a setup as shown in :ref:`architecture`. First you
|
||||
need to get a clone. The clone is only needed for the installation procedure
|
||||
and some maintenance tasks (alternatively you can create your own fork).
|
||||
|
||||
Install dependencies in a virtualenv:
|
||||
.. code:: bash
|
||||
|
||||
.. code:: sh
|
||||
$ cd ~/Downloads
|
||||
$ git clone https://github.com/asciimoo/searx searx
|
||||
$ cd searx
|
||||
|
||||
cd /usr/local/searx
|
||||
sudo -H -u searx -i
|
||||
**Install** :ref:`searx service <searx.sh>`
|
||||
|
||||
.. code:: sh
|
||||
This installs searx as described in :ref:`installation basic`.
|
||||
|
||||
(searx)$ virtualenv searx-ve
|
||||
(searx)$ . ./searx-ve/bin/activate
|
||||
(searx)$ ./manage.sh update_packages
|
||||
.. code:: bash
|
||||
|
||||
Configuration
|
||||
==============
|
||||
$ sudo -H ./utils/searx.sh install all
|
||||
|
||||
.. code:: sh
|
||||
**Install** :ref:`filtron reverse proxy <filtron.sh>`
|
||||
|
||||
sed -i -e "s/ultrasecretkey/`openssl rand -hex 16`/g" searx/settings.yml
|
||||
.. code:: bash
|
||||
|
||||
Edit searx/settings.yml if necessary.
|
||||
$ sudo -H ./utils/filtron.sh install all
|
||||
|
||||
Check
|
||||
=====
|
||||
**Install** :ref:`result proxy <morty.sh>`
|
||||
|
||||
Start searx:
|
||||
.. code:: bash
|
||||
|
||||
.. code:: sh
|
||||
$ sudo -H ./utils/morty.sh install all
|
||||
|
||||
python searx/webapp.py
|
||||
If all services are running fine, you can add it to your HTTP server:
|
||||
|
||||
Go to http://localhost:8888
|
||||
- :ref:`installation apache`
|
||||
- :ref:`installation nginx`
|
||||
|
||||
If everything works fine, disable the debug option in settings.yml:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sed -i -e "s/debug : True/debug : False/g" searx/settings.yml
|
||||
|
||||
At this point searx is not demonized ; uwsgi allows this.
|
||||
|
||||
You can exit the virtualenv and the searx user bash (enter exit command
|
||||
twice).
|
||||
|
||||
uwsgi
|
||||
=====
|
||||
|
||||
Install packages:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H apt-get install \
|
||||
uwsgi uwsgi-plugin-python
|
||||
|
||||
Create the configuration file ``/etc/uwsgi/apps-available/searx.ini`` with this
|
||||
content:
|
||||
|
||||
.. code:: ini
|
||||
|
||||
[uwsgi]
|
||||
# Who will run the code
|
||||
uid = searx
|
||||
gid = searx
|
||||
|
||||
# disable logging for privacy
|
||||
disable-logging = true
|
||||
|
||||
# Number of workers (usually CPU count)
|
||||
workers = 4
|
||||
|
||||
# The right granted on the created socket
|
||||
chmod-socket = 666
|
||||
|
||||
# Plugin to use and interpretor config
|
||||
single-interpreter = true
|
||||
master = true
|
||||
plugin = python
|
||||
lazy-apps = true
|
||||
enable-threads = true
|
||||
|
||||
# Module to import
|
||||
module = searx.webapp
|
||||
|
||||
# Support running the module from a webserver subdirectory.
|
||||
route-run = fixpathinfo:
|
||||
|
||||
# Virtualenv and python path
|
||||
virtualenv = /usr/local/searx/searx-ve/
|
||||
pythonpath = /usr/local/searx/
|
||||
chdir = /usr/local/searx/searx/
|
||||
|
||||
Activate the uwsgi application and restart:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
cd /etc/uwsgi/apps-enabled
|
||||
ln -s ../apps-available/searx.ini
|
||||
/etc/init.d/uwsgi restart
|
||||
|
||||
Web server
|
||||
==========
|
||||
|
||||
with nginx
|
||||
----------
|
||||
|
||||
If nginx is not installed (uwsgi will not work with the package
|
||||
nginx-light):
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H apt-get install nginx
|
||||
|
||||
Hosted at /
|
||||
~~~~~~~~~~~
|
||||
|
||||
Create the configuration file ``/etc/nginx/sites-available/searx`` with this
|
||||
content:
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name searx.example.com;
|
||||
root /usr/local/searx/searx;
|
||||
|
||||
location /static {
|
||||
}
|
||||
|
||||
location / {
|
||||
include uwsgi_params;
|
||||
uwsgi_pass unix:/run/uwsgi/app/searx/socket;
|
||||
}
|
||||
}
|
||||
|
||||
Create a symlink to sites-enabled:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H ln -s /etc/nginx/sites-available/searx /etc/nginx/sites-enabled/searx
|
||||
|
||||
Restart service:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H service nginx restart
|
||||
sudo -H service uwsgi restart
|
||||
|
||||
from subdirectory URL (/searx)
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Add this configuration in the server config file
|
||||
``/etc/nginx/sites-enabled/default``:
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
location /searx/static {
|
||||
alias /usr/local/searx/searx/static;
|
||||
}
|
||||
|
||||
location /searx {
|
||||
uwsgi_param SCRIPT_NAME /searx;
|
||||
include uwsgi_params;
|
||||
uwsgi_pass unix:/run/uwsgi/app/searx/socket;
|
||||
}
|
||||
|
||||
|
||||
**OR** using reverse proxy (Please, note that reverse proxy advised to be used
|
||||
in case of single-user or low-traffic instances.)
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
location /searx/static {
|
||||
alias /usr/local/searx/searx/static;
|
||||
}
|
||||
|
||||
location /searx {
|
||||
proxy_pass http://127.0.0.1:8888;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme $scheme;
|
||||
proxy_set_header X-Script-Name /searx;
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
|
||||
Enable ``base_url`` in ``searx/settings.yml``
|
||||
|
||||
.. code:: yaml
|
||||
|
||||
base_url : http://your.domain.tld/searx/
|
||||
|
||||
Restart service:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H service nginx restart
|
||||
sudo -H service uwsgi restart
|
||||
|
||||
disable logs
|
||||
^^^^^^^^^^^^
|
||||
|
||||
for better privacy you can disable nginx logs about searx.
|
||||
|
||||
how to proceed: below ``uwsgi_pass`` in ``/etc/nginx/sites-available/default``
|
||||
add:
|
||||
|
||||
.. code:: nginx
|
||||
|
||||
access_log /dev/null;
|
||||
error_log /dev/null;
|
||||
|
||||
Restart service:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H service nginx restart
|
||||
|
||||
with apache
|
||||
-----------
|
||||
|
||||
Add wsgi mod:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H apt-get install libapache2-mod-uwsgi
|
||||
sudo -H a2enmod uwsgi
|
||||
|
||||
Add this configuration in the file ``/etc/apache2/apache2.conf``:
|
||||
|
||||
.. code:: apache
|
||||
|
||||
<Location />
|
||||
Options FollowSymLinks Indexes
|
||||
SetHandler uwsgi-handler
|
||||
uWSGISocket /run/uwsgi/app/searx/socket
|
||||
</Location>
|
||||
|
||||
Note that if your instance of searx is not at the root, you should change
|
||||
``<Location />`` by the location of your instance, like ``<Location /searx>``.
|
||||
|
||||
Restart Apache:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H /etc/init.d/apache2 restart
|
||||
|
||||
disable logs
|
||||
~~~~~~~~~~~~
|
||||
|
||||
For better privacy you can disable Apache logs.
|
||||
|
||||
.. warning::
|
||||
|
||||
You can only disable logs for the whole (virtual) server not for a specific
|
||||
path.
|
||||
|
||||
Go back to ``/etc/apache2/apache2.conf`` and above ``<Location />`` add:
|
||||
|
||||
.. code:: apache
|
||||
|
||||
CustomLog /dev/null combined
|
||||
|
||||
Restart Apache:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H /etc/init.d/apache2 restart
|
||||
|
||||
How to update
|
||||
=============
|
||||
|
||||
.. code:: sh
|
||||
|
||||
cd /usr/local/searx
|
||||
sudo -H -u searx -i
|
||||
|
||||
.. code:: sh
|
||||
|
||||
(searx)$ . ./searx-ve/bin/activate
|
||||
(searx)$ git stash
|
||||
(searx)$ git pull origin master
|
||||
(searx)$ git stash apply
|
||||
(searx)$ ./manage.sh update_packages
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H service uwsgi restart
|
||||
|
||||
Docker
|
||||
======
|
||||
|
||||
Make sure you have installed Docker. For instance, you can deploy searx like this:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
docker pull wonderfall/searx
|
||||
docker run -d --name searx -p $PORT:8888 wonderfall/searx
|
||||
|
||||
Go to ``http://localhost:$PORT``.
|
||||
|
||||
See https://hub.docker.com/r/wonderfall/searx/ for more informations. It's also
|
||||
possible to build searx from the embedded Dockerfile.
|
||||
|
||||
.. code:: sh
|
||||
|
||||
git clone https://github.com/asciimoo/searx.git
|
||||
cd searx
|
||||
docker build -t whatever/searx .
|
||||
|
||||
References
|
||||
==========
|
||||
|
||||
* https://about.okhin.fr/posts/Searx/ with some additions
|
||||
|
||||
* How to: `Setup searx in a couple of hours with a free SSL certificate
|
||||
<https://www.reddit.com/r/privacytoolsIO/comments/366kvn/how_to_setup_your_own_privacy_respecting_search/>`__
|
||||
|
@ -1,7 +1,14 @@
|
||||
|
||||
.. _searx morty:
|
||||
|
||||
=========================
|
||||
How to setup result proxy
|
||||
=========================
|
||||
|
||||
.. sidebar:: further reading
|
||||
|
||||
- :ref:`morty.sh`
|
||||
|
||||
.. _morty: https://github.com/asciimoo/morty
|
||||
.. _morty's README: https://github.com/asciimoo/morty
|
||||
|
||||
|
@ -4,11 +4,17 @@
|
||||
``settings.yml``
|
||||
================
|
||||
|
||||
This page describe the options possibilities of the :origin:`searx/settings.yml`
|
||||
file.
|
||||
|
||||
.. sidebar:: Further reading ..
|
||||
|
||||
- :ref:`search API`
|
||||
|
||||
This page describe the options possibilities of the settings.yml file.
|
||||
.. contents:: Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: entry
|
||||
|
||||
.. _settings global:
|
||||
|
||||
|
23
docs/admin/update-searx.rst
Normal file
23
docs/admin/update-searx.rst
Normal file
@ -0,0 +1,23 @@
|
||||
.. _update searx:
|
||||
|
||||
=============
|
||||
How to update
|
||||
=============
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H -u searx -i
|
||||
(searx)$ git stash
|
||||
(searx)$ git pull origin master
|
||||
(searx)$ git stash apply
|
||||
(searx)$ ./manage.sh update_packages
|
||||
|
||||
Restart uwsgi:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code:: sh
|
||||
|
||||
sudo -H systemctl restart uwsgi
|
@ -3,7 +3,8 @@ Blog
|
||||
====
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:maxdepth: 2
|
||||
:caption: Contents
|
||||
|
||||
python3
|
||||
admin
|
||||
|
@ -13,7 +13,7 @@ Private engines
|
||||
To solve this issue private engines were introduced in :pull:`1823`.
|
||||
A new option was added to engines named `tokens`. It expects a list
|
||||
of strings. If the user making a request presents one of the tokens
|
||||
of an engine, he/she is able to access information about the engine
|
||||
of an engine, they can access information about the engine
|
||||
and make search requests.
|
||||
|
||||
Example configuration to restrict access to the Arch Linux Wiki engine:
|
||||
|
52
docs/build-templates/filtron.rst
Normal file
52
docs/build-templates/filtron.rst
Normal file
@ -0,0 +1,52 @@
|
||||
.. START create user
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H useradd --shell /bin/bash --system \\
|
||||
--home-dir "$SERVICE_HOME" \\
|
||||
--comment "Privacy-respecting metasearch engine" $SERVICE_USER
|
||||
|
||||
$ sudo -H mkdir "$SERVICE_HOME"
|
||||
$ sudo -H chown -R "$SERVICE_GROUP:$SERVICE_GROUP" "$SERVICE_HOME"
|
||||
|
||||
.. END create user
|
||||
|
||||
.. START install go
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cat > "$GO_ENV" <<EOF
|
||||
export GOPATH=${SERVICE_HOME}/go-apps
|
||||
export PATH=\$PATH:${SERVICE_HOME}/local/go/bin:\$GOPATH/bin
|
||||
EOF
|
||||
$ sudo -i -u "${SERVICE_USER}"
|
||||
(${SERVICE_USER}) $ echo 'source $GO_ENV' >> ~/.profile
|
||||
(${SERVICE_USER}) $ mkdir ${SERVICE_HOME}/local
|
||||
(${SERVICE_USER}) $ wget --progress=bar -O "${GO_TAR}" \\
|
||||
"${GO_PKG_URL}"
|
||||
(${SERVICE_USER}) $ tar -C ${SERVICE_HOME}/local/go -xzf "${GO_TAR}"
|
||||
(${SERVICE_USER}) $ which go
|
||||
${SERVICE_HOME}/local/go/bin/go
|
||||
|
||||
.. END install go
|
||||
|
||||
.. START install filtron
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo -i -u "${SERVICE_USER}"
|
||||
(${SERVICE_USER}) $ go get -v -u github.com/asciimoo/filtron
|
||||
|
||||
.. END install filtron
|
52
docs/build-templates/morty.rst
Normal file
52
docs/build-templates/morty.rst
Normal file
@ -0,0 +1,52 @@
|
||||
.. START create user
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H useradd --shell /bin/bash --system \\
|
||||
--home-dir "$SERVICE_HOME" \\
|
||||
--comment "Privacy-respecting metasearch engine" $SERVICE_USER
|
||||
|
||||
$ sudo -H mkdir "$SERVICE_HOME"
|
||||
$ sudo -H chown -R "$SERVICE_GROUP:$SERVICE_GROUP" "$SERVICE_HOME"
|
||||
|
||||
.. END create user
|
||||
|
||||
.. START install go
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ cat > "$GO_ENV" <<EOF
|
||||
export GOPATH=${SERVICE_HOME}/go-apps
|
||||
export PATH=\$PATH:${SERVICE_HOME}/local/go/bin:\$GOPATH/bin
|
||||
EOF
|
||||
$ sudo -i -u "${SERVICE_USER}"
|
||||
(${SERVICE_USER}) $ echo 'source $GO_ENV' >> ~/.profile
|
||||
(${SERVICE_USER}) $ mkdir ${SERVICE_HOME}/local
|
||||
(${SERVICE_USER}) $ wget --progress=bar -O "${GO_TAR}" \\
|
||||
"${GO_PKG_URL}"
|
||||
(${SERVICE_USER}) $ tar -C ${SERVICE_HOME}/local/go -xzf "${GO_TAR}"
|
||||
(${SERVICE_USER}) $ which go
|
||||
${SERVICE_HOME}/local/go/bin/go
|
||||
|
||||
.. END install go
|
||||
|
||||
.. START install morty
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo -i -u "${SERVICE_USER}"
|
||||
(${SERVICE_USER}) $ go get -v -u github.com/asciimoo/morty
|
||||
|
||||
.. END install morty
|
192
docs/build-templates/searx.rst
Normal file
192
docs/build-templates/searx.rst
Normal file
@ -0,0 +1,192 @@
|
||||
.. template evaluated by: ./utils/searx.sh docs
|
||||
.. hint: all dollar-names are variables, dollar sign itself is quoted by: \\$
|
||||
|
||||
.. START distro-packages
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H apt-get install -y \\
|
||||
${debian}
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H pacman -S --noconfirm \\
|
||||
${arch}
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H dnf install -y \\
|
||||
${fedora}
|
||||
|
||||
.. END distro-packages
|
||||
|
||||
.. START build-packages
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: Ubuntu / debian
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H apt-get install -y \\
|
||||
${debian_build}
|
||||
|
||||
.. group-tab:: Arch Linux
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H pacman -S --noconfirm \\
|
||||
${arch_build}
|
||||
|
||||
.. group-tab:: Fedora / RHEL
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H dnf install -y \\
|
||||
${fedora_build}
|
||||
|
||||
.. END build-packages
|
||||
|
||||
.. START create user
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H useradd --shell /bin/bash --system \\
|
||||
--home-dir "$SERVICE_HOME" \\
|
||||
--comment "Privacy-respecting metasearch engine" $SERVICE_USER
|
||||
|
||||
$ sudo -H mkdir "$SERVICE_HOME"
|
||||
$ sudo -H chown -R "$SERVICE_GROUP:$SERVICE_GROUP" "$SERVICE_HOME"
|
||||
|
||||
.. END create user
|
||||
|
||||
.. START clone searx
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H -u ${SERVICE_USER} -i
|
||||
(${SERVICE_USER})$ git clone "https://github.com/asciimoo/searx.git" "$SEARX_SRC"
|
||||
|
||||
.. END clone searx
|
||||
|
||||
.. START create virtualenv
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
(${SERVICE_USER})$ python3 -m venv "${SEARX_PYENV}"
|
||||
(${SERVICE_USER})$ echo ". ${SEARX_PYENV}/bin/activate" >> "$SERVICE_HOME/.profile"
|
||||
|
||||
.. END create virtualenv
|
||||
|
||||
.. START manage.sh update_packages
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H -u ${SERVICE_USER} -i
|
||||
|
||||
(${SERVICE_USER})$ command -v python && python --version
|
||||
$SEARX_PYENV/bin/python
|
||||
Python 3.8.1
|
||||
|
||||
# update pip's boilerplate ..
|
||||
pip install -U pip
|
||||
pip install -U setuptools
|
||||
pip install -U wheel
|
||||
|
||||
# jump to searx's working tree and install searx into virtualenv
|
||||
(${SERVICE_USER})$ cd "$SEARX_SRC"
|
||||
(${SERVICE_USER})$ pip install -e .
|
||||
|
||||
|
||||
.. END manage.sh update_packages
|
||||
|
||||
.. START searx config
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ sudo -H cp "$SEARX_SRC/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
|
||||
$ sudo -H sed -i -e "s/ultrasecretkey/\\$(openssl rand -hex 16)/g" "$SEARX_SETTINGS_PATH"
|
||||
$ sudo -H sed -i -e "s/{instance_name}/searx@\\$(uname -n)/g" "$SEARX_SETTINGS_PATH"
|
||||
|
||||
.. END searx config
|
||||
|
||||
.. START check searx installation
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: bash
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
# enable debug ..
|
||||
$ sudo -H sed -i -e "s/debug : False/debug : True/g" "$SEARX_SETTINGS_PATH"
|
||||
|
||||
# start webapp
|
||||
$ sudo -H -u ${SERVICE_USER} -i
|
||||
(${SERVICE_USER})$ cd ${SEARX_SRC}
|
||||
(${SERVICE_USER})$ export SEARX_SETTINGS_PATH="${SEARX_SETTINGS_PATH}"
|
||||
(${SERVICE_USER})$ python searx/webapp.py
|
||||
|
||||
# disable debug
|
||||
$ sudo -H sed -i -e "s/debug : True/debug : False/g" "$SEARX_SETTINGS_PATH"
|
||||
|
||||
Open WEB browser and visit http://$SEARX_INTERNAL_URL . If you are inside a
|
||||
container or in a script, test with curl:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: WEB browser
|
||||
|
||||
.. code-block:: sh
|
||||
|
||||
$ xgd-open http://$SEARX_INTERNAL_URL
|
||||
|
||||
.. group-tab:: curl
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
$ curl --location --verbose --head --insecure $SEARX_INTERNAL_URL
|
||||
|
||||
* Trying 127.0.0.1:8888...
|
||||
* TCP_NODELAY set
|
||||
* Connected to 127.0.0.1 (127.0.0.1) port 8888 (#0)
|
||||
> HEAD / HTTP/1.1
|
||||
> Host: 127.0.0.1:8888
|
||||
> User-Agent: curl/7.68.0
|
||||
> Accept: */*
|
||||
>
|
||||
* Mark bundle as not supporting multiuse
|
||||
* HTTP 1.0, assume close after body
|
||||
< HTTP/1.0 200 OK
|
||||
HTTP/1.0 200 OK
|
||||
...
|
||||
|
||||
.. END check searx installation
|
14
docs/conf.py
14
docs/conf.py
@ -1,10 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import sys, os
|
||||
from sphinx_build_tools import load_sphinx_config
|
||||
from searx.version import VERSION_STRING
|
||||
from pallets_sphinx_themes import ProjectLink
|
||||
|
||||
from searx.brand import GIT_URL
|
||||
GIT_BRANCH = os.environ.get("GIT_BRANCH", "master")
|
||||
from searx.brand import SEARX_URL
|
||||
from searx.brand import DOCS_URL
|
||||
|
||||
@ -22,6 +24,8 @@ master_doc = "index"
|
||||
source_suffix = '.rst'
|
||||
numfig = True
|
||||
|
||||
exclude_patterns = ['build-templates/*.rst']
|
||||
|
||||
from searx import webapp
|
||||
jinja_contexts = {
|
||||
'webapp': dict(**webapp.__dict__)
|
||||
@ -35,7 +39,7 @@ extlinks['wiki'] = ('https://github.com/asciimoo/searx/wiki/%s', ' ')
|
||||
extlinks['pull'] = ('https://github.com/asciimoo/searx/pull/%s', 'PR ')
|
||||
|
||||
# links to custom brand
|
||||
extlinks['origin'] = (GIT_URL + '/blob/master/%s', 'git://')
|
||||
extlinks['origin'] = (GIT_URL + '/blob/' + GIT_BRANCH + '/%s', 'git://')
|
||||
extlinks['patch'] = (GIT_URL + '/commit/%s', '#')
|
||||
extlinks['search'] = (SEARX_URL + '/%s', '#')
|
||||
extlinks['docs'] = (DOCS_URL + '/%s', 'docs: ')
|
||||
@ -61,6 +65,8 @@ extensions = [
|
||||
"pallets_sphinx_themes",
|
||||
"sphinx_issues", # https://github.com/sloria/sphinx-issues/blob/master/README.rst
|
||||
"sphinxcontrib.jinja", # https://github.com/tardyp/sphinx-jinja
|
||||
"sphinxcontrib.programoutput", # https://github.com/NextThought/sphinxcontrib-programoutput
|
||||
'linuxdoc.kernel_include', # Implementation of the 'kernel-include' reST-directive.
|
||||
'linuxdoc.rstFlatTable', # Implementation of the 'flat-table' reST-directive.
|
||||
'linuxdoc.kfigure', # Sphinx extension which implements scalable image handling.
|
||||
"sphinx_tabs.tabs", # https://github.com/djungelorm/sphinx-tabs
|
||||
@ -112,3 +118,9 @@ html_show_sourcelink = False
|
||||
latex_documents = [
|
||||
(master_doc, "searx-{}.tex".format(VERSION_STRING), html_title, author, "manual")
|
||||
]
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
# Since loadConfig overwrites settings from the global namespace, it has to be
|
||||
# the last statement in the conf.py file
|
||||
# ------------------------------------------------------------------------------
|
||||
load_sphinx_config(globals())
|
||||
|
@ -4,6 +4,11 @@
|
||||
How to contribute
|
||||
=================
|
||||
|
||||
.. contents:: Contents
|
||||
:depth: 2
|
||||
:local:
|
||||
:backlinks: entry
|
||||
|
||||
Prime directives: Privacy, Hackability
|
||||
======================================
|
||||
|
||||
|
@ -3,7 +3,8 @@ Developer documentation
|
||||
=======================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:maxdepth: 2
|
||||
:caption: Contents
|
||||
|
||||
quickstart
|
||||
contribution_guide
|
||||
|
@ -11,23 +11,17 @@ Makefile Targets
|
||||
Before looking deeper at the targets, first read about :ref:`makefile setup`
|
||||
and :ref:`make pyenv`.
|
||||
|
||||
To install system requirements follow :ref:`buildhosts`.
|
||||
|
||||
With the aim to simplify development cycles, started with :pull:`1756` a
|
||||
``Makefile`` based boilerplate was added. If you are not familiar with
|
||||
Makefiles, we recommend to read gnu-make_ introduction.
|
||||
|
||||
The usage is simple, just type ``make {target-name}`` to *build* a target.
|
||||
Calling the ``help`` target gives a first overview::
|
||||
Calling the ``help`` target gives a first overview (``make help``):
|
||||
|
||||
.. program-output:: bash -c "cd ..; make --no-print-directory help"
|
||||
|
||||
$ make help
|
||||
test - run developer tests
|
||||
docs - build documentation
|
||||
docs-live - autobuild HTML documentation while editing
|
||||
run - run developer instance
|
||||
install - developer install (./local)
|
||||
uninstall - uninstall (./local)
|
||||
gh-pages - build docs & deploy on gh-pages branch
|
||||
clean - drop builds and environments
|
||||
...
|
||||
|
||||
.. contents:: Contents
|
||||
:depth: 2
|
||||
@ -37,27 +31,33 @@ Calling the ``help`` target gives a first overview::
|
||||
|
||||
.. _makefile setup:
|
||||
|
||||
Setup
|
||||
=====
|
||||
Makefile setup
|
||||
==============
|
||||
|
||||
.. _git stash: https://git-scm.com/docs/git-stash
|
||||
|
||||
The main setup is done in the :origin:`Makefile`::
|
||||
|
||||
export GIT_URL=https://github.com/asciimoo/searx
|
||||
export SEARX_URL=https://searx.me
|
||||
export DOCS_URL=https://asciimoo.github.io/searx
|
||||
|
||||
.. sidebar:: fork & upstream
|
||||
|
||||
Commit changes in your (local) branch, fork or whatever, but do not push them
|
||||
upstream / `git stash`_ is your friend.
|
||||
|
||||
:GIT_URL: Changes this, to point to your searx fork.
|
||||
The main setup is done in the :origin:`Makefile`.
|
||||
|
||||
:SEARX_URL: Changes this, to point to your searx instance.
|
||||
.. literalinclude:: ../../Makefile
|
||||
:start-after: START Makefile setup
|
||||
:end-before: END Makefile setup
|
||||
|
||||
:DOCS_URL: If you host your own (branded) documentation, change this URL.
|
||||
:GIT_URL: Changes this, to point to your searx fork.
|
||||
:GIT_BRANCH: Changes this, to point to your searx branch.
|
||||
:SEARX_URL: Changes this, to point to your searx instance.
|
||||
:DOCS_URL: If you host your own (*brand*) documentation, change this URL.
|
||||
|
||||
If you change any of this build environment variables, you have to run ``make
|
||||
buildenv``::
|
||||
|
||||
$ make buildenv
|
||||
build searx/brand.py
|
||||
build utils/brand.env
|
||||
|
||||
.. _make pyenv:
|
||||
|
||||
@ -170,7 +170,7 @@ e.g.:
|
||||
|
||||
.. code:: sh
|
||||
|
||||
$ make test.pep8 test.unit
|
||||
$ make test.pep8 test.unit test.sh
|
||||
. ./local/py3/bin/activate; ./manage.sh pep8_check
|
||||
[!] Running pep8 check
|
||||
. ./local/py3/bin/activate; ./manage.sh unit_tests
|
||||
|
@ -27,7 +27,7 @@ searx-ve virtualenv and install the required packages using ``manage.sh``.
|
||||
cd ~/myprojects
|
||||
git clone https://github.com/asciimoo/searx.git
|
||||
cd searx
|
||||
virtualenv searx-ve
|
||||
python3 -m venv searx-ve
|
||||
. ./searx-ve/bin/activate
|
||||
./manage.sh update_dev_packages
|
||||
|
||||
|
@ -325,8 +325,9 @@ Literal blocks
|
||||
|
||||
The simplest form of :duref:`literal-blocks` is a indented block introduced by
|
||||
two colons (``::``). For highlighting use :dudir:`highlight` or :ref:`reST
|
||||
code` directive. To include literals from external files use directive
|
||||
:dudir:`literalinclude`.
|
||||
code` directive. To include literals from external files use
|
||||
:rst:dir:`literalinclude` or :ref:`kernel-include <kernel-include-directive>`
|
||||
directive (latter one expands environment variables in the path name).
|
||||
|
||||
.. _reST literal:
|
||||
|
||||
@ -1312,9 +1313,8 @@ others are basic-tabs_ and code-tabs_. Below a *group-tab* example from
|
||||
|
||||
.. literalinclude:: ../admin/buildhosts.rst
|
||||
:language: reST
|
||||
:start-after: .. _system requirements:
|
||||
:end-before: .. _system requirements END:
|
||||
|
||||
:start-after: .. SNIP sh lint requirements
|
||||
:end-before: .. SNAP sh lint requirements
|
||||
|
||||
.. _math:
|
||||
|
||||
|
@ -81,7 +81,7 @@ Parameters
|
||||
Theme of instance.
|
||||
|
||||
Please note, available themes depend on an instance. It is possible that an
|
||||
instance administrator deleted, created or renamed themes on his/her instance.
|
||||
instance administrator deleted, created or renamed themes on their instance.
|
||||
See the available options in the preferences page of the instance.
|
||||
|
||||
``oscar-style`` : default ``logicodev``
|
||||
@ -91,7 +91,7 @@ Parameters
|
||||
``oscar``.
|
||||
|
||||
Please note, available styles depend on an instance. It is possible that an
|
||||
instance administrator deleted, created or renamed styles on his/her
|
||||
instance administrator deleted, created or renamed styles on their
|
||||
instance. See the available options in the preferences page of the instance.
|
||||
|
||||
``enabled_plugins`` : optional
|
||||
|
@ -2,7 +2,14 @@
|
||||
Welcome to searx
|
||||
================
|
||||
|
||||
Search without being tracked.
|
||||
*Search without being tracked.*
|
||||
|
||||
Searx is a free internet metasearch engine which aggregates results from more
|
||||
than 70 search services. Users are neither tracked nor profiled. Additionally,
|
||||
searx can be used over Tor for online anonymity.
|
||||
|
||||
Get started with searx by using one of the Searx-instances_. If you don't trust
|
||||
anyone, you can set up your own, see :ref:`installation`.
|
||||
|
||||
.. sidebar:: Features
|
||||
|
||||
@ -16,19 +23,14 @@ Search without being tracked.
|
||||
- Hosted by organizations, such as *La Quadrature du Net*, which promote
|
||||
digital rights
|
||||
|
||||
Searx is a free internet metasearch engine which aggregates results from more
|
||||
than 70 search services. Users are neither tracked nor profiled. Additionally,
|
||||
searx can be used over Tor for online anonymity.
|
||||
|
||||
Get started with searx by using one of the Searx-instances_. If you don't trust
|
||||
anyone, you can set up your own, see :ref:`installation`.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents
|
||||
|
||||
user/index
|
||||
admin/index
|
||||
dev/index
|
||||
utils/index
|
||||
blog/index
|
||||
|
||||
.. _Searx-instances: https://searx.space
|
||||
|
19
docs/user/conf.py
Normal file
19
docs/user/conf.py
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8; mode: python -*-
|
||||
"""Configuration for the Searx user handbook
|
||||
"""
|
||||
project = 'Searx User-HB'
|
||||
version = release = VERSION_STRING
|
||||
|
||||
# Grouping the document tree into LaTeX files. List of tuples
|
||||
# (source start file, target name, title,
|
||||
# author, documentclass [howto, manual, or own class]).
|
||||
latex_documents = [
|
||||
('index' # startdocname
|
||||
, 'searx-user-hb.tex' # targetname
|
||||
, '' # take title from .rst
|
||||
, author # author
|
||||
, 'howto' # documentclass
|
||||
, False # toctree_only
|
||||
),
|
||||
]
|
||||
|
@ -3,7 +3,8 @@ User documentation
|
||||
==================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:maxdepth: 2
|
||||
:caption: Contents
|
||||
|
||||
search_syntax
|
||||
own-instance
|
||||
|
@ -2,8 +2,10 @@
|
||||
Why use a private instance?
|
||||
===========================
|
||||
|
||||
"Is it worth to run my own instance?" is a common question among searx users.
|
||||
Before answering this question, see what options a searx user has.
|
||||
*"Is it worth to run my own instance?"*
|
||||
|
||||
\.\. is a common question among searx users. Before answering this question,
|
||||
see what options a searx user has.
|
||||
|
||||
Public instances are open to everyone who has access to its URL. Usually, these
|
||||
are operated by unknown parties (from the users' point of view). Private
|
||||
@ -42,9 +44,9 @@ hidden from visited result pages.
|
||||
What are the consequences of using public instances?
|
||||
----------------------------------------------------
|
||||
|
||||
If someone uses a public instance, he/she has to trust the administrator of that
|
||||
If someone uses a public instance, they have to trust the administrator of that
|
||||
instance. This means that the user of the public instance does not know whether
|
||||
his/her requests are logged, aggregated and sent or sold to a third party.
|
||||
their requests are logged, aggregated and sent or sold to a third party.
|
||||
|
||||
Also, public instances without proper protection are more vulnerable to abusing
|
||||
the search service, In this case the external service in exchange returns
|
||||
|
@ -1,3 +0,0 @@
|
||||
:orphan:
|
||||
|
||||
This page page has been moved to `searx.space <https://searx.space/>`__
|
80
docs/utils/filtron.sh.rst
Normal file
80
docs/utils/filtron.sh.rst
Normal file
@ -0,0 +1,80 @@
|
||||
|
||||
.. _filtron.sh:
|
||||
|
||||
====================
|
||||
``utils/filtron.sh``
|
||||
====================
|
||||
|
||||
.. sidebar:: further reading
|
||||
|
||||
- :ref:`searx filtron`
|
||||
- :ref:`architecture`
|
||||
- :ref:`installation` (:ref:`nginx <installation nginx>` & :ref:`apache
|
||||
<installation apache>`)
|
||||
|
||||
.. _Go: https://golang.org/
|
||||
.. _filtron: https://github.com/asciimoo/filtron
|
||||
.. _filtron README: https://github.com/asciimoo/filtron/blob/master/README.md
|
||||
|
||||
To simplify installation and maintenance of a filtron instance you can use the
|
||||
script :origin:`utils/filtron.sh`. In most cases you will install filtron_
|
||||
simply by running the command:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
sudo -H ./utils/filtron.sh install all
|
||||
|
||||
The script adds a ``${SERVICE_USER}`` (default:``filtron``) and installs filtron_
|
||||
into this user account:
|
||||
|
||||
#. Create a separated user account (``filtron``).
|
||||
#. Download and install Go_ binary in user's $HOME (``~filtron``).
|
||||
#. Install filtron with the package management from Go_ (``go get -v -u
|
||||
github.com/asciimoo/filtron``)
|
||||
#. Setup a proper rule configuration :origin:`[ref]
|
||||
<utils/templates/etc/filtron/rules.json>` (``/etc/filtron/rules.json``).
|
||||
#. Setup a systemd service unit :origin:`[ref]
|
||||
<utils/templates/lib/systemd/system/filtron.service>`
|
||||
(``/lib/systemd/system/filtron.service``).
|
||||
|
||||
|
||||
Create user
|
||||
===========
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/filtron.rst
|
||||
:start-after: START create user
|
||||
:end-before: END create user
|
||||
|
||||
|
||||
Install go
|
||||
==========
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/filtron.rst
|
||||
:start-after: START install go
|
||||
:end-before: END install go
|
||||
|
||||
|
||||
Install filtron
|
||||
===============
|
||||
|
||||
Install :origin:`rules.json <utils/templates/etc/filtron/rules.json>` at
|
||||
``/etc/filtron/rules.json`` (see :ref:`Sample configuration of filtron`) and
|
||||
install filtron software and systemd unit:
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/filtron.rst
|
||||
:start-after: START install filtron
|
||||
:end-before: END install filtron
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/filtron.rst
|
||||
:start-after: START install systemd unit
|
||||
:end-before: END install systemd unit
|
||||
|
||||
.. _filtron.sh overview:
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The ``--help`` output of the script is largely self-explanatory
|
||||
(:ref:`toolboxing common`):
|
||||
|
||||
.. program-output:: ../utils/filtron.sh --help
|
53
docs/utils/index.rst
Normal file
53
docs/utils/index.rst
Normal file
@ -0,0 +1,53 @@
|
||||
.. _searx_utils:
|
||||
.. _toolboxing:
|
||||
|
||||
=======================
|
||||
Tooling box ``utils/*``
|
||||
=======================
|
||||
|
||||
In the folder :origin:`utils/` we maintain some tools useful for admins and
|
||||
developers.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents
|
||||
|
||||
searx.sh
|
||||
filtron.sh
|
||||
morty.sh
|
||||
lxc.sh
|
||||
|
||||
.. _toolboxing common:
|
||||
|
||||
Common commands & environment
|
||||
=============================
|
||||
|
||||
Scripts to maintain services often dispose of common commands and environments.
|
||||
|
||||
``shell`` : command
|
||||
Opens a shell from the service user ``${SERVICE_USSR}``, very helpful for
|
||||
troubleshooting.
|
||||
|
||||
``inspect service`` : command
|
||||
Shows status and log of the service, most often you have a option to enable
|
||||
more verbose debug logs. Very helpful for debugging, but be careful not to
|
||||
enable debugging in a production environment!
|
||||
|
||||
``FORCE_TIMEOUT`` : environment
|
||||
Sets timeout for interactive prompts. If you want to run a script in batch
|
||||
job, with defaults choices, set ``FORCE_TIMEOUT=0``. By example; to install a
|
||||
reverse proxy for filtron on all containers of the :ref:`searx suite
|
||||
<lxc-searx.env>` use ::
|
||||
|
||||
sudo -H ./utils/lxc.sh cmd -- FORCE_TIMEOUT=0 ./utils/filtron.sh apache install
|
||||
|
||||
.. _toolboxing setup:
|
||||
|
||||
Tooling box setup
|
||||
=================
|
||||
|
||||
The main setup is done in the :origin:`.config.sh` (read also :ref:`makefile
|
||||
setup`).
|
||||
|
||||
.. literalinclude:: ../../.config.sh
|
||||
:language: bash
|
148
docs/utils/lxc.sh.rst
Normal file
148
docs/utils/lxc.sh.rst
Normal file
@ -0,0 +1,148 @@
|
||||
|
||||
.. _snap: https://snapcraft.io
|
||||
.. _snapcraft LXD: https://snapcraft.io/lxd
|
||||
.. _LXC/LXD Image Server: https://uk.images.linuxcontainers.org/
|
||||
.. _LXC: https://linuxcontainers.org/lxc/introduction/
|
||||
.. _LXD: https://linuxcontainers.org/lxd/introduction/
|
||||
.. _`LXD@github`: https://github.com/lxc/lxd
|
||||
|
||||
.. _archlinux: https://www.archlinux.org/
|
||||
|
||||
.. _lxc.sh:
|
||||
|
||||
================
|
||||
``utils/lxc.sh``
|
||||
================
|
||||
|
||||
.. sidebar:: further reading
|
||||
|
||||
- snap_, `snapcraft LXD`_
|
||||
- LXC_, LXD_
|
||||
- `LXC/LXD Image Server`_
|
||||
- `LXD@github`_
|
||||
|
||||
With the use of *Linux Containers* (LXC_) we can scale our tasks over a stack of
|
||||
containers, what we call the: *lxc suite*. The *searx suite*
|
||||
(:origin:`lxc-searx.env <utils/lxc-searx.env>`) is loaded by default, every time
|
||||
you start the ``lxc.sh`` script (*you do not need to care about*).
|
||||
|
||||
Before you can start with containers, you need to install and initiate LXD_
|
||||
once::
|
||||
|
||||
$ snap install lxd
|
||||
$ lxd init --auto
|
||||
|
||||
To make use of the containers from the *searx suite*, you have to build the
|
||||
:ref:`LXC suite containers <lxc.sh help>` initial. But be warned, **this might
|
||||
take some time**::
|
||||
|
||||
$ sudo -H ./utils/lxc.sh build
|
||||
|
||||
A cup of coffee later, your LXC suite is build up and you can run whatever task
|
||||
you want / in a selected or even in all :ref:`LXC suite containers <lxc.sh
|
||||
help>`. If you do not want to build all containers, **you can build just
|
||||
one**::
|
||||
|
||||
$ sudo -H ./utils/lxc.sh build searx-ubu1804
|
||||
|
||||
*Good to know ...*
|
||||
|
||||
Eeach container shares the root folder of the repository and the
|
||||
command ``utils/lxc.sh cmd`` **handles relative path names transparent**,
|
||||
compare output of::
|
||||
|
||||
$ sudo -H ./utils/lxc.sh cmd -- ls -la Makefile
|
||||
...
|
||||
|
||||
In the containers, you can run what ever you want, e.g. to start a bash use::
|
||||
|
||||
$ sudo -H ./utils/lxc.sh cmd searx-ubu1804 bash
|
||||
INFO: [searx-ubu1804] bash
|
||||
root@searx-ubu1804:/share/searx#
|
||||
|
||||
If there comes the time you want to **get rid off all** the containers and
|
||||
**clean up local images** just type::
|
||||
|
||||
$ sudo -H ./utils/lxc.sh remove
|
||||
$ sudo -H ./utils/lxc.sh remove images
|
||||
|
||||
|
||||
Install suite
|
||||
=============
|
||||
|
||||
To install the complete :ref:`searx suite (includes searx, morty & filtron)
|
||||
<lxc-searx.env>` into all LXC_ use::
|
||||
|
||||
$ sudo -H ./utils/lxc.sh install suite
|
||||
|
||||
The command above installs a searx suite (see :ref:`installation scripts`). To
|
||||
get the IP (URL) of the filtron service in the containers use ``show suite``
|
||||
command. To test instances from containers just open the URLs in your
|
||||
WEB-Browser::
|
||||
|
||||
$ sudo ./utils/lxc.sh show suite | grep filtron
|
||||
[searx-ubu1604] INFO: (eth0) filtron: http://n.n.n.246:4004/ http://n.n.n.246/searx
|
||||
[searx-ubu1804] INFO: (eth0) filtron: http://n.n.n.147:4004/ http://n.n.n.147/searx
|
||||
[searx-ubu1910] INFO: (eth0) filtron: http://n.n.n.140:4004/ http://n.n.n.140/searx
|
||||
[searx-ubu2004] INFO: (eth0) filtron: http://n.n.n.18:4004/ http://n.n.n.18/searx
|
||||
[searx-fedora31] INFO: (eth0) filtron: http://n.n.n.46:4004/ http://n.n.n.46/searx
|
||||
[searx-archlinux] INFO: (eth0) filtron: http://n.n.n.32:4004/ http://n.n.n.32/searx
|
||||
|
||||
To :ref:`install a nginx <installation nginx>` reverse proxy for filtron and
|
||||
morty use (or alternatively use :ref:`apache <installation apache>`)::
|
||||
|
||||
sudo -H ./utils/lxc.sh cmd -- FORCE_TIMEOUT=0 ./utils/filtron.sh nginx install
|
||||
sudo -H ./utils/lxc.sh cmd -- FORCE_TIMEOUT=0 ./utils/morty.sh nginx install
|
||||
|
||||
|
||||
Running commands
|
||||
================
|
||||
|
||||
**Inside containers, you can use make or run scripts** from the
|
||||
:ref:`toolboxing`. By example: to setup a :ref:`buildhosts` and run the
|
||||
Makefile target ``test`` in the archlinux_ container::
|
||||
|
||||
sudo -H ./utils/lxc.sh cmd searx-archlinux ./utils/searx.sh install buildhost
|
||||
sudo -H ./utils/lxc.sh cmd searx-archlinux make test
|
||||
|
||||
|
||||
Setup searx buildhost
|
||||
=====================
|
||||
|
||||
You can **install the searx buildhost environment** into one or all containers.
|
||||
The installation procedure to set up a :ref:`build host<buildhosts>` takes its
|
||||
time. Installation in all containers will take more time (time for another cup
|
||||
of coffee).::
|
||||
|
||||
sudo -H ./utils/lxc.sh cmd -- ./utils/searx.sh install buildhost
|
||||
|
||||
To build (live) documentation inside a archlinux_ container::
|
||||
|
||||
sudo -H ./utils/lxc.sh cmd searx-archlinux make docs-clean docs-live
|
||||
...
|
||||
[I 200331 15:00:42 server:296] Serving on http://0.0.0.0:8080
|
||||
|
||||
To get IP of the container and the port number *live docs* is listening::
|
||||
|
||||
$ sudo ./utils/lxc.sh show suite | grep docs-live
|
||||
...
|
||||
[searx-archlinux] INFO: (eth0) docs-live: http://n.n.n.12:8080/
|
||||
|
||||
|
||||
.. _lxc.sh help:
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The ``--help`` output of the script is largely self-explanatory:
|
||||
|
||||
.. program-output:: ../utils/lxc.sh --help
|
||||
|
||||
|
||||
.. _lxc-searx.env:
|
||||
|
||||
searx suite
|
||||
===========
|
||||
|
||||
.. literalinclude:: ../../utils/lxc-searx.env
|
||||
:language: bash
|
80
docs/utils/morty.sh.rst
Normal file
80
docs/utils/morty.sh.rst
Normal file
@ -0,0 +1,80 @@
|
||||
|
||||
.. _morty: https://github.com/asciimoo/morty
|
||||
.. _morty's README: https://github.com/asciimoo/morty
|
||||
.. _Go: https://golang.org/
|
||||
|
||||
.. _morty.sh:
|
||||
|
||||
==================
|
||||
``utils/morty.sh``
|
||||
==================
|
||||
|
||||
.. sidebar:: further reading
|
||||
|
||||
- :ref:`architecture`
|
||||
- :ref:`installation` (:ref:`nginx <installation nginx>` & :ref:`apache
|
||||
<installation apache>`)
|
||||
- :ref:`searx morty`
|
||||
|
||||
To simplify installation and maintenance of a morty_ instance you can use the
|
||||
script :origin:`utils/morty.sh`. In most cases you will install morty_ simply by
|
||||
running the command:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
sudo -H ./utils/morty.sh install all
|
||||
|
||||
The script adds a ``${SERVICE_USER}`` (default:``morty``) and installs morty_
|
||||
into this user account:
|
||||
|
||||
#. Create a separated user account (``morty``).
|
||||
#. Download and install Go_ binary in user's $HOME (``~morty``).
|
||||
#. Install morty_ with the package management from Go_ (``go get -v -u
|
||||
github.com/asciimoo/morty``)
|
||||
#. Setup a systemd service unit :origin:`[ref]
|
||||
<utils/templates/lib/systemd/system/morty.service>`
|
||||
(``/lib/systemd/system/morty.service``).
|
||||
|
||||
.. hint::
|
||||
|
||||
To add morty to your searx instance read chapter :ref:`searx morty`.
|
||||
|
||||
Create user
|
||||
===========
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/morty.rst
|
||||
:start-after: START create user
|
||||
:end-before: END create user
|
||||
|
||||
|
||||
Install go
|
||||
==========
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/morty.rst
|
||||
:start-after: START install go
|
||||
:end-before: END install go
|
||||
|
||||
|
||||
Install morty
|
||||
=============
|
||||
|
||||
Install morty software and systemd unit:
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/morty.rst
|
||||
:start-after: START install morty
|
||||
:end-before: END install morty
|
||||
|
||||
.. kernel-include:: $DOCS_BUILD/includes/morty.rst
|
||||
:start-after: START install systemd unit
|
||||
:end-before: END install systemd unit
|
||||
|
||||
.. _morty.sh overview:
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The ``--help`` output of the script is largely self-explanatory
|
||||
(:ref:`toolboxing common`):
|
||||
|
||||
.. program-output:: ../utils/morty.sh --help
|
||||
|
39
docs/utils/searx.sh.rst
Normal file
39
docs/utils/searx.sh.rst
Normal file
@ -0,0 +1,39 @@
|
||||
|
||||
.. _searx.sh:
|
||||
|
||||
==================
|
||||
``utils/searx.sh``
|
||||
==================
|
||||
|
||||
.. sidebar:: further reading
|
||||
|
||||
- :ref:`architecture`
|
||||
- :ref:`installation`
|
||||
- :ref:`installation nginx`
|
||||
- :ref:`installation apache`
|
||||
|
||||
To simplify installation and maintenance of a searx instance you can use the
|
||||
script :origin:`utils/searx.sh`.
|
||||
|
||||
Install
|
||||
=======
|
||||
|
||||
In most cases you will install searx simply by running the command:
|
||||
|
||||
.. code:: bash
|
||||
|
||||
sudo -H ./utils/searx.sh install all
|
||||
|
||||
The script adds a ``${SERVICE_USER}`` (default:``searx``) and installs searx
|
||||
into this user account. The installation is described in chapter
|
||||
:ref:`installation basic`.
|
||||
|
||||
.. _intranet reverse proxy:
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The ``--help`` output of the script is largely self-explanatory
|
||||
(:ref:`toolboxing common`):
|
||||
|
||||
.. program-output:: ../utils/searx.sh --help
|
@ -15,3 +15,5 @@ selenium==3.141.0
|
||||
linuxdoc @ git+http://github.com/return42/linuxdoc.git
|
||||
sphinx-jinja
|
||||
sphinx-tabs
|
||||
sphinxcontrib-programoutput
|
||||
twine
|
||||
|
@ -1,4 +1,5 @@
|
||||
GIT_URL = 'https://github.com/asciimoo/searx'
|
||||
GIT_BRANCH = 'master'
|
||||
ISSUE_URL = 'https://github.com/asciimoo/searx/issues'
|
||||
SEARX_URL = 'https://searx.me'
|
||||
DOCS_URL = 'https://asciimoo.github.io/searx'
|
||||
|
@ -117,14 +117,10 @@ def response(resp):
|
||||
'img_format': img_format,
|
||||
'template': 'images.html'
|
||||
}
|
||||
try:
|
||||
result['author'] = author
|
||||
result['title'] = title
|
||||
result['content'] = content
|
||||
except:
|
||||
result['author'] = ''
|
||||
result['title'] = ''
|
||||
result['content'] = ''
|
||||
result['author'] = author.encode('utf-8', 'ignore').decode('utf-8')
|
||||
result['source'] = source.encode('utf-8', 'ignore').decode('utf-8')
|
||||
result['title'] = title.encode('utf-8', 'ignore').decode('utf-8')
|
||||
result['content'] = content.encode('utf-8', 'ignore').decode('utf-8')
|
||||
results.append(result)
|
||||
|
||||
return results
|
||||
|
@ -33,7 +33,7 @@ supported_languages_url = 'https://search.yahoo.com/web/advanced'
|
||||
results_xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' Sr ')]"
|
||||
url_xpath = './/h3/a/@href'
|
||||
title_xpath = './/h3/a'
|
||||
content_xpath = './/div[@class="compText aAbs"]'
|
||||
content_xpath = './/div[contains(@class, "compText")]'
|
||||
suggestion_xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' AlsoTry ')]//a"
|
||||
|
||||
time_range_dict = {'day': ['1d', 'd'],
|
||||
|
@ -6,19 +6,37 @@ $(document).ready(function() {
|
||||
});
|
||||
$(document.getElementById($(this).attr("for"))).prop('checked', true);
|
||||
if($('#q').val()) {
|
||||
if (getHttpRequest() == "GET") {
|
||||
$('#search_form').attr('action', $('#search_form').serialize());
|
||||
}
|
||||
$('#search_form').submit();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
$('#time-range').change(function(e) {
|
||||
if($('#q').val()) {
|
||||
if (getHttpRequest() == "GET") {
|
||||
$('#search_form').attr('action', $('#search_form').serialize());
|
||||
}
|
||||
$('#search_form').submit();
|
||||
}
|
||||
});
|
||||
$('#language').change(function(e) {
|
||||
if($('#q').val()) {
|
||||
if (getHttpRequest() == "GET") {
|
||||
$('#search_form').attr('action', $('#search_form').serialize());
|
||||
}
|
||||
$('#search_form').submit();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function getHttpRequest() {
|
||||
httpRequest = "POST";
|
||||
urlParams = new URLSearchParams(window.location.search);
|
||||
if (urlParams.has('method')) {
|
||||
httpRequest = urlParams.get('method');
|
||||
}
|
||||
return httpRequest;
|
||||
}
|
||||
|
@ -70,7 +70,21 @@ input[type=checkbox]:not(:checked) + .label_hide_if_checked + .label_hide_if_not
|
||||
-ms-user-select: none;
|
||||
}
|
||||
.onoffswitch-checkbox {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
}
|
||||
.onoffswitch-checkbox:before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 10px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 1px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 0px;
|
||||
}
|
||||
.onoffswitch-label {
|
||||
display: block;
|
||||
@ -104,7 +118,7 @@ input[type=checkbox]:not(:checked) + .label_hide_if_checked + .label_hide_if_not
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0px;
|
||||
border: 2px solid #FFFFFF !important;
|
||||
border: 2px solid #FFFFFF;
|
||||
border-radius: 50px !important;
|
||||
transition: all 0.3s ease-in 0s;
|
||||
}
|
||||
@ -115,6 +129,9 @@ input[type=checkbox]:not(:checked) + .label_hide_if_checked + .label_hide_if_not
|
||||
right: 71px;
|
||||
background-color: #A1A1A1;
|
||||
}
|
||||
.onoffswitch-checkbox:focus + .onoffswitch-label .onoffswitch-switch {
|
||||
border: 3px solid #444444;
|
||||
}
|
||||
.result_header {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 2px;
|
||||
@ -377,6 +394,17 @@ Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb
|
||||
.search-margin {
|
||||
margin-bottom: 0.6em;
|
||||
}
|
||||
.visually-hidden {
|
||||
position: absolute !important;
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(1px 1px 1px 1px);
|
||||
/* IE6, IE7 */
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
white-space: nowrap;
|
||||
/* added line */
|
||||
}
|
||||
#advanced-search-container {
|
||||
display: none;
|
||||
text-align: left;
|
||||
@ -407,8 +435,8 @@ Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb
|
||||
font-weight: bold;
|
||||
border-bottom: #01d7d4 5px solid;
|
||||
}
|
||||
#check-advanced {
|
||||
display: none;
|
||||
#check-advanced:focus + label {
|
||||
text-decoration: underline;
|
||||
}
|
||||
#check-advanced:checked ~ #advanced-search-container {
|
||||
display: block;
|
||||
|
BIN
searx/static/themes/oscar/css/logicodev-dark.min.css
vendored
BIN
searx/static/themes/oscar/css/logicodev-dark.min.css
vendored
Binary file not shown.
@ -43,7 +43,21 @@ input[type=checkbox]:not(:checked) + .label_hide_if_checked + .label_hide_if_not
|
||||
-ms-user-select: none;
|
||||
}
|
||||
.onoffswitch-checkbox {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
}
|
||||
.onoffswitch-checkbox:before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 10px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 1px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 0px;
|
||||
}
|
||||
.onoffswitch-label {
|
||||
display: block;
|
||||
@ -77,7 +91,7 @@ input[type=checkbox]:not(:checked) + .label_hide_if_checked + .label_hide_if_not
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0px;
|
||||
border: 2px solid #FFFFFF !important;
|
||||
border: 2px solid #FFFFFF;
|
||||
border-radius: 50px !important;
|
||||
transition: all 0.3s ease-in 0s;
|
||||
}
|
||||
@ -88,6 +102,9 @@ input[type=checkbox]:not(:checked) + .label_hide_if_checked + .label_hide_if_not
|
||||
right: 71px;
|
||||
background-color: #A1A1A1;
|
||||
}
|
||||
.onoffswitch-checkbox:focus + .onoffswitch-label .onoffswitch-switch {
|
||||
border: 3px solid #444444;
|
||||
}
|
||||
.result_header {
|
||||
margin-top: 0px;
|
||||
margin-bottom: 2px;
|
||||
@ -350,6 +367,17 @@ Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb
|
||||
.search-margin {
|
||||
margin-bottom: 0.6em;
|
||||
}
|
||||
.visually-hidden {
|
||||
position: absolute !important;
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(1px 1px 1px 1px);
|
||||
/* IE6, IE7 */
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
white-space: nowrap;
|
||||
/* added line */
|
||||
}
|
||||
#advanced-search-container {
|
||||
display: none;
|
||||
text-align: left;
|
||||
@ -380,8 +408,8 @@ Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb
|
||||
font-weight: bold;
|
||||
border-bottom: #01d7d4 5px solid;
|
||||
}
|
||||
#check-advanced {
|
||||
display: none;
|
||||
#check-advanced:focus + label {
|
||||
text-decoration: underline;
|
||||
}
|
||||
#check-advanced:checked ~ #advanced-search-container {
|
||||
display: block;
|
||||
|
BIN
searx/static/themes/oscar/css/logicodev.min.css
vendored
BIN
searx/static/themes/oscar/css/logicodev.min.css
vendored
Binary file not shown.
@ -291,7 +291,7 @@ $(document).ready(function(){
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
$(result_table_loadicon).html($(result_table_loadicon).html() + "<p class=\"text-muted\">could not load data!</p>");
|
||||
$(result_table_loadicon).html($(result_table_loadicon).html() + "<p class=\"text-muted\">"+could_not_load+"</p>");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
BIN
searx/static/themes/oscar/js/searx.min.js
vendored
BIN
searx/static/themes/oscar/js/searx.min.js
vendored
Binary file not shown.
@ -90,7 +90,7 @@ $(document).ready(function(){
|
||||
}
|
||||
})
|
||||
.fail(function() {
|
||||
$(result_table_loadicon).html($(result_table_loadicon).html() + "<p class=\"text-muted\">could not load data!</p>");
|
||||
$(result_table_loadicon).html($(result_table_loadicon).html() + "<p class=\"text-muted\">"+could_not_load+"</p>");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -31,8 +31,8 @@
|
||||
}
|
||||
}
|
||||
|
||||
#check-advanced {
|
||||
display: none;
|
||||
#check-advanced:focus + label {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
#check-advanced:checked ~ #advanced-search-container {
|
||||
|
@ -9,7 +9,21 @@
|
||||
-ms-user-select: none;
|
||||
}
|
||||
.onoffswitch-checkbox {
|
||||
display: none;
|
||||
opacity: 0;
|
||||
position: absolute;
|
||||
}
|
||||
.onoffswitch-checkbox:before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
margin-right: 10px;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 1px;
|
||||
background-color: #fff;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 0px;
|
||||
}
|
||||
.onoffswitch-label {
|
||||
display: block;
|
||||
@ -44,7 +58,7 @@
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0px;
|
||||
border: 2px solid #FFFFFF !important;
|
||||
border: 2px solid #FFFFFF;
|
||||
border-radius: 50px !important;
|
||||
transition: all 0.3s ease-in 0s;
|
||||
}
|
||||
@ -55,3 +69,6 @@
|
||||
right: 71px;
|
||||
background-color: #A1A1A1;
|
||||
}
|
||||
.onoffswitch-checkbox:focus + .onoffswitch-label .onoffswitch-switch {
|
||||
border: 3px solid #444444;
|
||||
}
|
||||
|
@ -77,4 +77,14 @@ Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb
|
||||
|
||||
.search-margin {
|
||||
margin-bottom: 0.6em;
|
||||
}
|
||||
}
|
||||
|
||||
.visually-hidden {
|
||||
position: absolute !important;
|
||||
height: 1px;
|
||||
width: 1px;
|
||||
overflow: hidden;
|
||||
clip: rect(1px 1px 1px 1px); /* IE6, IE7 */
|
||||
clip: rect(1px, 1px, 1px, 1px);
|
||||
white-space: nowrap; /* added line */
|
||||
}
|
||||
|
BIN
searx/static/themes/simple/js/searx.head.min.js
vendored
BIN
searx/static/themes/simple/js/searx.head.min.js
vendored
Binary file not shown.
@ -1314,7 +1314,7 @@ module.exports = AutoComplete;
|
||||
})
|
||||
.catch(function() {
|
||||
result_table_loadicon.classList.remove('invisible');
|
||||
result_table_loadicon.innerHTML = "could not load data!";
|
||||
result_table_loadicon.innerHTML = could_not_load;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
BIN
searx/static/themes/simple/js/searx.min.js
vendored
BIN
searx/static/themes/simple/js/searx.min.js
vendored
Binary file not shown.
Binary file not shown.
@ -97,7 +97,7 @@
|
||||
})
|
||||
.catch(function() {
|
||||
result_table_loadicon.classList.remove('invisible');
|
||||
result_table_loadicon.innerHTML = "could not load data!";
|
||||
result_table_loadicon.innerHTML = could_not_load;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -59,12 +59,16 @@
|
||||
|
||||
<h2 id='add to browser'>How to set as the default search engine?</h2>
|
||||
|
||||
<dt>Firefox</dt>
|
||||
<p>
|
||||
Searx supports <a href="https://github.com/dewitt/opensearch/blob/master/opensearch-1-1-draft-6.md">OpenSearch</a>.
|
||||
For more information on changing your default search engine, see your browser's documentation:
|
||||
</p>
|
||||
|
||||
<dd>
|
||||
<a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a>
|
||||
searx as a search engine on any version of Firefox! (javascript required)
|
||||
</dd>
|
||||
<ul>
|
||||
<li><a href="https://support.mozilla.org/en-US/kb/add-or-remove-search-engine-firefox">Firefox</a></li>
|
||||
<li><a href="https://support.microsoft.com/en-us/help/4028574/microsoft-edge-change-the-default-search-engine" >Microsoft Egde</a></li>
|
||||
<li>Chrome based browsers <a href="https://www.chromium.org/tab-to-search">only add websites that the user navigates to without a path.</a>
|
||||
</ul>
|
||||
|
||||
<h2>Where to find anonymous usage statistics of this instance ?</h2>
|
||||
|
||||
|
@ -6,23 +6,13 @@
|
||||
<Image>{{ urljoin(host, url_for('static', filename='img/favicon.png')) }}</Image>
|
||||
<LongName>searx metasearch</LongName>
|
||||
{% if opensearch_method == 'get' %}
|
||||
<Url type="text/html" method="get" template="{{ host }}search?q={searchTerms}"/>
|
||||
{% if autocomplete %}
|
||||
<Url type="application/x-suggestions+json" method="get" template="{{ host }}autocompleter">
|
||||
<Param name="format" value="x-suggestions" />
|
||||
<Param name="q" value="{searchTerms}" />
|
||||
</Url>
|
||||
{% endif %}
|
||||
<Url rel="results" type="text/html" method="get" template="{{ host }}search?q={searchTerms}"/>
|
||||
{% else %}
|
||||
<Url type="text/html" method="post" template="{{ host }}">
|
||||
<Url rel="results" type="text/html" method="post" template="{{ host }}">
|
||||
<Param name="q" value="{searchTerms}" />
|
||||
</Url>
|
||||
{% if autocomplete %}
|
||||
<!-- TODO, POST REQUEST doesn't work -->
|
||||
<Url type="application/x-suggestions+json" method="get" template="{{ host }}autocompleter">
|
||||
<Param name="format" value="x-suggestions" />
|
||||
<Param name="q" value="{searchTerms}" />
|
||||
</Url>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if autocomplete %}
|
||||
<Url rel="suggestions" type="application/json" template="{{ host }}autocompleter"/>
|
||||
{% endif %}
|
||||
</OpenSearchDescription>
|
||||
|
1
searx/templates/__common__/translations.js.tpl
Normal file
1
searx/templates/__common__/translations.js.tpl
Normal file
@ -0,0 +1 @@
|
||||
var could_not_load = '{{ _('could not load data') }}!';
|
@ -1,4 +1,4 @@
|
||||
<input type="checkbox" name="advanced_search" id="check-advanced" {% if advanced_search %} checked="checked"{% endif %}>
|
||||
<input type="checkbox" name="advanced_search" class="visually-hidden" id="check-advanced" {% if advanced_search %} checked="checked"{% endif %}>
|
||||
<label for="check-advanced">{{- "" -}}
|
||||
<span class="glyphicon glyphicon-cog"></span>
|
||||
{{- _('Advanced settings') -}}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{% from 'oscar/macros.html' import icon %}
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"{% if rtl %} dir="rtl"{% endif %}>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="{{ preferences.get_value('locale') }}" xml:lang="{{ preferences.get_value('locale') }}"{% if rtl %} dir="rtl"{% endif %}>
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="description" content="searx - a privacy-respecting, hackable metasearch engine" />
|
||||
@ -8,9 +8,9 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="generator" content="searx/{{ searx_version }}">
|
||||
<meta name="referrer" content="no-referrer">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1 , maximum-scale=1.0, user-scalable=1" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1 , maximum-scale=2.0, user-scalable=1" />
|
||||
{% block meta %}{% endblock %}
|
||||
|
||||
<script src="{{ url_for('js_translations') }}"></script>
|
||||
<title>{% block title %}{% endblock %}{{ instance_name }}</title>
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}" type="text/css" />
|
||||
{% if preferences.get_value('oscar-style') -%}
|
||||
|
@ -6,10 +6,10 @@
|
||||
{% if cookies['oscar-style'] == 'pointhi' %}
|
||||
<h1 class="text-hide center-block"><img class="center-block img-responsive" src="{{ url_for('static', filename='img/searx_logo.png') }}" alt="searx logo"/>searx</h1>
|
||||
{% else %}
|
||||
<h1 class="text-hide center-block" id="main-logo">
|
||||
<div class="text-hide center-block" id="main-logo">
|
||||
<img class="center-block img-responsive" src="{{ url_for('static', filename='img/logo_searx_a.png') }}" alt="searx logo" />
|
||||
searx
|
||||
</h1>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
{% for u in infobox.urls %}{% if u.official %} <a href="{{ u.url }}">{{ u.domain }}</a>{% endif %}{% endfor %}
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
{% if infobox.img_src %}<img class="img-responsive center-block infobox_part" src="{{ image_proxify(infobox.img_src) }}" alt="{{ infobox.infobox }}" />{% endif %}
|
||||
{% if infobox.img_src %}<img class="img-responsive center-block infobox_part" src="{{ image_proxify(infobox.img_src) }}" />{% endif %}
|
||||
|
||||
{% if infobox.content %}<bdi><p class="infobox_part">{{ infobox.content | safe }}</p></bdi>{% endif %}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
<label class="visually-hidden" for="language">{{ _('Language') }}</label>
|
||||
<select class="language custom-select form-control" id="language" name="language" accesskey="l">
|
||||
<option value="all" {% if current_language == 'all' %}selected="selected"{% endif %}>{{ _('Default language') }}</option>
|
||||
{%- for lang_id,lang_name,country_name,english_name in language_codes | sort(attribute=1) -%}
|
||||
|
@ -60,15 +60,15 @@
|
||||
{%- endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro preferences_item_header(info, label, rtl) -%}
|
||||
{% macro preferences_item_header(info, label, rtl, id) -%}
|
||||
{% if rtl %}
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-3 col-md-2 pull-right">{{ label }}</label>
|
||||
<label class="col-sm-3 col-md-2 pull-right"{% if id %} for="{{id}}"{% endif %}>{{ label }}</label>
|
||||
<span class="col-sm-5 col-md-6 help-block pull-left">{{ info }}</span>
|
||||
<div class="col-sm-4 col-md-4">
|
||||
{% else %}
|
||||
<div class="row form-group">
|
||||
<label class="col-sm-3 col-md-2">{{ label }}</label>
|
||||
<label class="col-sm-3 col-md-2"{% if id %} for="{{id}}"{% endif %}>{{ label }}</label>
|
||||
<div class="col-sm-4 col-md-4">
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
@ -91,6 +91,7 @@
|
||||
<span class="onoffswitch-inner"></span>
|
||||
<span class="onoffswitch-switch"></span>
|
||||
</label>
|
||||
<label class="visually-hidden" for="{{ id }}">{{ _('Allow') }}</label>
|
||||
</div>
|
||||
{%- endmacro %}
|
||||
|
||||
|
@ -30,9 +30,9 @@
|
||||
<div class="col-sm-11 col-md-10">
|
||||
{% include 'oscar/categories.html' %}
|
||||
</div>
|
||||
<label class="col-sm-3 col-md-2">{{ _('Default categories') }}</label>
|
||||
<label class="col-sm-3 col-md-2" for="categories">{{ _('Default categories') }}</label>
|
||||
{% else %}
|
||||
<label class="col-sm-3 col-md-2">{{ _('Default categories') }}</label>
|
||||
<label class="col-sm-3 col-md-2" for="categories">{{ _('Default categories') }}</label>
|
||||
<div class="col-sm-11 col-md-10 search-categories">
|
||||
{% include 'oscar/categories.html' %}
|
||||
</div>
|
||||
@ -40,14 +40,14 @@
|
||||
</div>
|
||||
{% set language_label = _('Search language') %}
|
||||
{% set language_info = _('What language do you prefer for search?') %}
|
||||
{{ preferences_item_header(language_info, language_label, rtl) }}
|
||||
{{ preferences_item_header(language_info, language_label, rtl, 'language') }}
|
||||
{% include 'oscar/languages.html' %}
|
||||
{{ preferences_item_footer(language_info, language_label, rtl) }}
|
||||
|
||||
{% set locale_label = _('Interface language') %}
|
||||
{% set locale_info = _('Change the language of the layout') %}
|
||||
{{ preferences_item_header(locale_info, locale_label, rtl) }}
|
||||
<select class="form-control" name='locale'>
|
||||
{{ preferences_item_header(locale_info, locale_label, rtl, 'locale') }}
|
||||
<select class="form-control" name="locale" id="locale">
|
||||
{% for locale_id,locale_name in locales.items() | sort %}
|
||||
<option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option>
|
||||
{% endfor %}
|
||||
@ -56,8 +56,8 @@
|
||||
|
||||
{% set autocomplete_label = _('Autocomplete') %}
|
||||
{% set autocomplete_info = _('Find stuff as you type') %}
|
||||
{{ preferences_item_header(autocomplete_info, autocomplete_label, rtl) }}
|
||||
<select class="form-control" name="autocomplete">
|
||||
{{ preferences_item_header(autocomplete_info, autocomplete_label, rtl, 'autocomplete') }}
|
||||
<select class="form-control" name="autocomplete" id="autocomplete">
|
||||
<option value=""> - </option>
|
||||
{% for backend in autocomplete_backends %}
|
||||
<option value="{{ backend }}" {% if backend == autocomplete %}selected="selected"{% endif %}>{{ backend }}</option>
|
||||
@ -67,8 +67,8 @@
|
||||
|
||||
{% set image_proxy_label = _('Image proxy') %}
|
||||
{% set image_proxy_info = _('Proxying image results through searx') %}
|
||||
{{ preferences_item_header(image_proxy_info, image_proxy_label, rtl) }}
|
||||
<select class="form-control" name='image_proxy'>
|
||||
{{ preferences_item_header(image_proxy_info, image_proxy_label, rtl, 'image_proxy') }}
|
||||
<select class="form-control" name="image_proxy" id="image_proxy">
|
||||
<option value="1" {% if image_proxy %}selected="selected"{% endif %}>{{ _('Enabled') }}</option>
|
||||
<option value="" {% if not image_proxy %}selected="selected"{% endif %}>{{ _('Disabled')}}</option>
|
||||
</select>
|
||||
@ -76,8 +76,8 @@
|
||||
|
||||
{% set method_label = _('Method') %}
|
||||
{% set method_info = _('Change how forms are submited, <a href="http://en.wikipedia.org/wiki/Hypertext_Transfer_Protocol#Request_methods" rel="external">learn more about request methods</a>') %}
|
||||
{{ preferences_item_header(method_info, method_label, rtl) }}
|
||||
<select class="form-control" name='method'>
|
||||
{{ preferences_item_header(method_info, method_label, rtl, 'method') }}
|
||||
<select class="form-control" name="method" id="method">
|
||||
<option value="POST" {% if method == 'POST' %}selected="selected"{% endif %}>POST</option>
|
||||
<option value="GET" {% if method == 'GET' %}selected="selected"{% endif %}>GET</option>
|
||||
</select>
|
||||
@ -85,8 +85,8 @@
|
||||
|
||||
{% set safesearch_label = _('SafeSearch') %}
|
||||
{% set safesearch_info = _('Filter content') %}
|
||||
{{ preferences_item_header(safesearch_info, safesearch_label, rtl) }}
|
||||
<select class="form-control" name='safesearch'>
|
||||
{{ preferences_item_header(safesearch_info, safesearch_label, rtl, 'safesearch') }}
|
||||
<select class="form-control" name="safesearch" id="safesearch">
|
||||
<option value="2" {% if safesearch == '2' %}selected="selected"{% endif %}>{{ _('Strict') }}</option>
|
||||
<option value="1" {% if safesearch == '1' %}selected="selected"{% endif %}>{{ _('Moderate') }}</option>
|
||||
<option value="0" {% if safesearch == '0' %}selected="selected"{% endif %}>{{ _('None') }}</option>
|
||||
@ -95,16 +95,16 @@
|
||||
|
||||
{% set theme_label = _('Themes') %}
|
||||
{% set theme_info = _('Change searx layout') %}
|
||||
{{ preferences_item_header(theme_info, theme_label, rtl) }}
|
||||
<select class="form-control" name="theme">
|
||||
{{ preferences_item_header(theme_info, theme_label, rtl, 'theme') }}
|
||||
<select class="form-control" name="theme" id="theme">
|
||||
{% for name in themes %}
|
||||
<option value="{{ name }}" {% if name == theme %}selected="selected"{% endif %}>{{ name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{{ preferences_item_footer(theme_info, theme_label, rtl) }}
|
||||
|
||||
{{ preferences_item_header(_('Choose style for this theme'), _('Style'), rtl) }}
|
||||
<select class="form-control" name='oscar-style'>
|
||||
{{ preferences_item_header(_('Choose style for this theme'), _('Style'), rtl, 'oscar_style') }}
|
||||
<select class="form-control" name="oscar-style" id="oscar_style">
|
||||
<option value="logicodev" >Logicodev</option>
|
||||
<option value="pointhi" {% if preferences.get_value('oscar-style') == 'pointhi' %}selected="selected"{% endif %}>Pointhi</option>
|
||||
<option value="logicodev-dark" {% if preferences.get_value('oscar-style') == 'logicodev-dark' %}selected="selected"{% endif %}>Logicodev dark</option>
|
||||
@ -113,8 +113,8 @@
|
||||
|
||||
{% set label = _('Results on new tabs') %}
|
||||
{% set info = _('Open result links on new browser tabs') %}
|
||||
{{ preferences_item_header(info, label, rtl) }}
|
||||
<select class="form-control" name='results_on_new_tab'>
|
||||
{{ preferences_item_header(info, label, rtl, 'results_on_new_tab') }}
|
||||
<select class="form-control" name="results_on_new_tab" id="results_on_new_tab">
|
||||
<option value="1" {% if results_on_new_tab %}selected="selected"{% endif %}>{{ _('On') }}</option>
|
||||
<option value="0" {% if not results_on_new_tab %}selected="selected"{% endif %}>{{ _('Off')}}</option>
|
||||
</select>
|
||||
@ -122,8 +122,8 @@
|
||||
|
||||
{% set label = _('Open Access DOI resolver') %}
|
||||
{% set info = _('Redirect to open-access versions of publications when available (plugin required)') %}
|
||||
{{ preferences_item_header(info, label, rtl) }}
|
||||
<select class="form-control" id='doi_resolver' name='doi_resolver'>
|
||||
{{ preferences_item_header(info, label, rtl, 'doi_resolver') }}
|
||||
<select class="form-control" name="doi_resolver" id="doi_resolver">
|
||||
{% for doi_resolver_name,doi_resolver_url in doi_resolvers.items() %}
|
||||
<option value="{{ doi_resolver_name }}" {% if doi_resolver_name == current_doi_resolver %}selected="selected"{% endif %}>
|
||||
{{ doi_resolver_name }} - {{ doi_resolver_url }}
|
||||
@ -134,8 +134,8 @@
|
||||
|
||||
{% set label = _('Engine tokens') %}
|
||||
{% set info = _('Access tokens for private engines') %}
|
||||
{{ preferences_item_header(info, label, rtl) }}
|
||||
<input class="form-control" id='tokens' name='tokens' value='{{ preferences.tokens.get_value() }}'/>
|
||||
{{ preferences_item_header(info, label, rtl, 'tokens') }}
|
||||
<input class="form-control" id="tokens" name="tokens" value='{{ preferences.tokens.get_value() }}'/>
|
||||
{{ preferences_item_footer(info, label, rtl) }}
|
||||
</div>
|
||||
</fieldset>
|
||||
@ -173,23 +173,23 @@
|
||||
<table class="table table-hover table-condensed table-striped">
|
||||
<tr>
|
||||
{% if not rtl %}
|
||||
<th>{{ _("Allow") }}</th>
|
||||
<th>{{ _("Engine name") }}</th>
|
||||
<th>{{ _("Shortcut") }}</th>
|
||||
<th>{{ _("Selected language") }}</th>
|
||||
<th>{{ _("SafeSearch") }}</th>
|
||||
<th>{{ _("Time range") }}</th>
|
||||
<th>{{ _("Avg. time") }}</th>
|
||||
<th>{{ _("Max time") }}</th>
|
||||
<th scope="col">{{ _("Allow") }}</th>
|
||||
<th scope="col">{{ _("Engine name") }}</th>
|
||||
<th scope="col">{{ _("Shortcut") }}</th>
|
||||
<th scope="col">{{ _("Selected language") }}</th>
|
||||
<th scope="col">{{ _("SafeSearch") }}</th>
|
||||
<th scope="col">{{ _("Time range") }}</th>
|
||||
<th scope="col">{{ _("Avg. time") }}</th>
|
||||
<th scope="col">{{ _("Max time") }}</th>
|
||||
{% else %}
|
||||
<th class="text-right">{{ _("Max time") }}</th>
|
||||
<th class="text-right">{{ _("Avg. time") }}</th>
|
||||
<th class="text-right">{{ _("Time range") }}</th>
|
||||
<th class="text-right">{{ _("SafeSearch") }}</th>
|
||||
<th class="text-right">{{ _("Selected language") }}</th>
|
||||
<th class="text-right">{{ _("Shortcut") }}</th>
|
||||
<th class="text-right">{{ _("Engine name") }}</th>
|
||||
<th class="text-right">{{ _("Allow") }}</th>
|
||||
<th scope="col" class="text-right">{{ _("Max time") }}</th>
|
||||
<th scope="col" class="text-right">{{ _("Avg. time") }}</th>
|
||||
<th scope="col" class="text-right">{{ _("Time range") }}</th>
|
||||
<th scope="col" class="text-right">{{ _("SafeSearch") }}</th>
|
||||
<th scope="col" class="text-right">{{ _("Selected language") }}</th>
|
||||
<th scope="col" class="text-right">{{ _("Shortcut") }}</th>
|
||||
<th scope="col" class="text-right">{{ _("Engine name") }}</th>
|
||||
<th scope="col" class="text-right">{{ _("Allow") }}</th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% for search_engine in engines_by_category[categ] %}
|
||||
@ -199,21 +199,21 @@
|
||||
<td class="onoff-checkbox">
|
||||
{{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
|
||||
</td>
|
||||
<th>{{ search_engine.name }}</th>
|
||||
<th scope="row">{{ search_engine.name }}</th>
|
||||
<td class="name">{{ shortcuts[search_engine.name] }}</td>
|
||||
<td>{{ support_toggle(stats[search_engine.name].supports_selected_language) }}</td>
|
||||
<td>{{ support_toggle(search_engine.safesearch==True) }}</td>
|
||||
<td>{{ support_toggle(search_engine.time_range_support==True) }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>
|
||||
{% else %}
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{% if stats[search_engine.name]['warn_time'] %}{{ icon('exclamation-sign')}} {% endif %}{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{% if stats[search_engine.name]['warn_timeout'] %}{{ icon('exclamation-sign') }} {% endif %}{{ search_engine.timeout }}</td>
|
||||
{% else %}
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_timeout'] else '' }}">{{ search_engine.timeout }}{% if stats[search_engine.name]['warn_time'] %} {{ icon('exclamation-sign')}}{% endif %}</td>
|
||||
<td class="{{ 'danger' if stats[search_engine.name]['warn_time'] else '' }}">{{ 'N/A' if stats[search_engine.name].time==None else stats[search_engine.name].time }}{% if stats[search_engine.name]['warn_time'] %} {{ icon('exclamation-sign')}}{% endif %}</td>
|
||||
<td>{{ support_toggle(search_engine.time_range_support==True) }}</td>
|
||||
<td>{{ support_toggle(search_engine.safesearch==True) }}</td>
|
||||
<td>{{ support_toggle(stats[search_engine.name].supports_selected_language) }}</td>
|
||||
<td>{{ shortcuts[search_engine.name] }}</td>
|
||||
<th>{{ search_engine.name }}</th>
|
||||
<th scope="row">{{ search_engine.name }}</th>
|
||||
<td class="onoff-checkbox">
|
||||
{{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
|
||||
</td>
|
||||
@ -241,7 +241,7 @@
|
||||
<h3 class="panel-title">{{ _(plugin.name) }}</h3>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<div class="col-xs-6 col-sm-4 col-md-6">{{ _(plugin.description) }}</div>
|
||||
<div class="col-xs-6 col-sm-4 col-md-6"><label for="{{'plugin_' + plugin.id}}">{{ _(plugin.description) }}</label></div>
|
||||
<div class="col-xs-6 col-sm-4 col-md-6">
|
||||
<div class="onoff-checkbox">
|
||||
{{ checkbox_toggle('plugin_' + plugin.id, plugin.id not in allowed_plugins) }}
|
||||
|
@ -16,7 +16,7 @@
|
||||
{%- if result.img_src -%}
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<img src="{{ image_proxify(result.img_src) }}" alt="{{ result.title|striptags }}" title="{{ result.title|striptags }}" style="width: auto; max-height: 60px; min-height: 60px;" class="col-xs-2 col-sm-4 col-md-4 result-content">
|
||||
<img src="{{ image_proxify(result.img_src) }}" title="{{ result.title|striptags }}" style="width: auto; max-height: 60px; min-height: 60px;" class="col-xs-2 col-sm-4 col-md-4 result-content">
|
||||
{% if result.content %}<p class="result-content col-xs-8 col-sm-8 col-md-8">{{ result.content|safe }}</p>{% endif -%}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -15,7 +15,7 @@
|
||||
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}><img class="thumbnail col-xs-6 col-sm-4 col-md-4 result-content" src="{{ image_proxify(result.thumbnail) }}" alt="{{ result.title|striptags }} {{ result.engine }}" /></a>
|
||||
<a href="{{ result.url }}" {% if results_on_new_tab %}target="_blank" rel="noopener noreferrer"{% else %}rel="noreferrer"{% endif %}><img class="thumbnail col-xs-6 col-sm-4 col-md-4 result-content" src="{{ image_proxify(result.thumbnail) }}" /></a>
|
||||
{% if result.author %}<p class="col-xs-12 col-sm-8 col-md-8 result-content"><b>{{ _('Author') }}</b>: {{ result.author }}</p>{% endif %}
|
||||
{% if result.length %}<p class="col-xs-12 col-sm-8 col-md-8 result-content"><b>{{ _('Length') }}</b>: {{ result.length }}</p>{% endif %}
|
||||
{% if result.content %}<p class="col-xs-12 col-sm-8 col-md-8 result-content">{{ result.content|safe }}</p>{% endif %}
|
||||
|
@ -1,3 +1,4 @@
|
||||
<label class="visually-hidden" for="time-range">{{ _('Time range') }}</label>
|
||||
<select name="time_range" id="time-range" class="custom-select form-control" accesskey="t">{{- "" -}}
|
||||
<option id="time-range-anytime" value="" {{ "selected" if time_range=="" or not time_range else ""}}>
|
||||
{{- _('Anytime') -}}
|
||||
|
@ -12,6 +12,7 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
|
||||
<title>{% block title %}{% endblock %}{{ instance_name }}</title>
|
||||
{% block meta %}{% endblock %}
|
||||
<script src="{{ url_for('js_translations') }}"></script>
|
||||
{% if rtl %}
|
||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/searx-rtl.min.css') }}" type="text/css" media="screen" />
|
||||
{% else %}
|
||||
|
@ -335,8 +335,15 @@ def image_proxify(url):
|
||||
if not request.preferences.get_value('image_proxy'):
|
||||
return url
|
||||
|
||||
if url.startswith('data:image/jpeg;base64,'):
|
||||
return url
|
||||
if url.startswith('data:image/'):
|
||||
# 50 is an arbitrary number to get only the beginning of the image.
|
||||
partial_base64 = url[len('data:image/'):50].split(';')
|
||||
if len(partial_base64) == 2 \
|
||||
and partial_base64[0] in ['gif', 'png', 'jpeg', 'pjpeg', 'webp', 'tiff', 'bmp']\
|
||||
and partial_base64[1].startswith('base64,'):
|
||||
return url
|
||||
else:
|
||||
return None
|
||||
|
||||
if settings.get('result_proxy'):
|
||||
return proxify(url)
|
||||
@ -949,7 +956,7 @@ def opensearch():
|
||||
|
||||
resp = Response(response=ret,
|
||||
status=200,
|
||||
mimetype="text/xml")
|
||||
mimetype="application/opensearchdescription+xml")
|
||||
return resp
|
||||
|
||||
|
||||
@ -1021,6 +1028,14 @@ def config():
|
||||
})
|
||||
|
||||
|
||||
@app.route('/translations.js')
|
||||
def js_translations():
|
||||
return render(
|
||||
'translations.js.tpl',
|
||||
override_theme='__common__',
|
||||
), {'Content-Type': 'text/javascript; charset=UTF-8'}
|
||||
|
||||
|
||||
@app.errorhandler(404)
|
||||
def page_not_found(e):
|
||||
return render('404.html'), 404
|
||||
|
@ -1,4 +1,5 @@
|
||||
export GIT_URL='https://github.com/asciimoo/searx'
|
||||
export GIT_BRANCH='master'
|
||||
export ISSUE_URL='https://github.com/asciimoo/searx/issues'
|
||||
export SEARX_URL='https://searx.me'
|
||||
export DOCS_URL='https://asciimoo.github.io/searx'
|
||||
|
561
utils/filtron.sh
Executable file
561
utils/filtron.sh
Executable file
@ -0,0 +1,561 @@
|
||||
#!/usr/bin/env bash
|
||||
# -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# shellcheck disable=SC2119,SC2001
|
||||
|
||||
# shellcheck source=utils/lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
||||
# shellcheck source=utils/brand.env
|
||||
source "${REPO_ROOT}/utils/brand.env"
|
||||
source_dot_config
|
||||
source "${REPO_ROOT}/utils/lxc-searx.env"
|
||||
in_container && lxc_set_suite_env
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# config
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
PUBLIC_URL="${PUBLIC_URL:-http://$(uname -n)/searx}"
|
||||
PUBLIC_HOST="${PUBLIC_HOST:-$(echo "$PUBLIC_URL" | sed -e 's/[^/]*\/\/\([^@]*@\)\?\([^:/]*\).*/\2/')}"
|
||||
|
||||
FILTRON_URL_PATH="${FILTRON_URL_PATH:-$(echo "${PUBLIC_URL}" \
|
||||
| sed -e 's,^.*://[^/]*\(/.*\),\1,g')}"
|
||||
[[ "${FILTRON_URL_PATH}" == "${PUBLIC_URL}" ]] && FILTRON_URL_PATH=/
|
||||
|
||||
FILTRON_ETC="/etc/filtron"
|
||||
FILTRON_RULES="$FILTRON_ETC/rules.json"
|
||||
|
||||
FILTRON_API="${FILTRON_API:-127.0.0.1:4005}"
|
||||
FILTRON_LISTEN="${FILTRON_LISTEN:-127.0.0.1:4004}"
|
||||
FILTRON_TARGET="${FILTRON_TARGET:-127.0.0.1:8888}"
|
||||
|
||||
SERVICE_NAME="filtron"
|
||||
SERVICE_USER="${SERVICE_USER:-${SERVICE_NAME}}"
|
||||
SERVICE_HOME_BASE="${SERVICE_HOME_BASE:-/usr/local}"
|
||||
SERVICE_HOME="${SERVICE_HOME_BASE}/${SERVICE_USER}"
|
||||
SERVICE_SYSTEMD_UNIT="${SYSTEMD_UNITS}/${SERVICE_NAME}.service"
|
||||
# shellcheck disable=SC2034
|
||||
SERVICE_GROUP="${SERVICE_USER}"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
SERVICE_GROUP="${SERVICE_USER}"
|
||||
|
||||
GO_ENV="${SERVICE_HOME}/.go_env"
|
||||
GO_PKG_URL="https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz"
|
||||
GO_TAR=$(basename "$GO_PKG_URL")
|
||||
|
||||
APACHE_FILTRON_SITE="searx.conf"
|
||||
NGINX_FILTRON_SITE="searx.conf"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_FILES=(
|
||||
"${FILTRON_RULES}"
|
||||
"${SERVICE_SYSTEMD_UNIT}"
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
usage() {
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# shellcheck disable=SC1117
|
||||
cat <<EOF
|
||||
usage::
|
||||
$(basename "$0") shell
|
||||
$(basename "$0") install [all|user|rules]
|
||||
$(basename "$0") update [filtron]
|
||||
$(basename "$0") remove [all]
|
||||
$(basename "$0") activate [service]
|
||||
$(basename "$0") deactivate [service]
|
||||
$(basename "$0") inspect [service]
|
||||
$(basename "$0") option [debug-on|debug-off]
|
||||
$(basename "$0") apache [install|remove]
|
||||
$(basename "$0") nginx [install|remove]
|
||||
|
||||
shell
|
||||
start interactive shell from user ${SERVICE_USER}
|
||||
install / remove
|
||||
:all: complete setup of filtron service
|
||||
:user: add/remove service user '$SERVICE_USER' ($SERVICE_HOME)
|
||||
:rules: reinstall filtron rules $FILTRON_RULES
|
||||
update filtron
|
||||
Update filtron installation ($SERVICE_HOME)
|
||||
activate service
|
||||
activate and start service daemon (systemd unit)
|
||||
deactivate service
|
||||
stop and deactivate service daemon (systemd unit)
|
||||
inspect service
|
||||
show service status and log
|
||||
option
|
||||
set one of the available options
|
||||
apache (${PUBLIC_URL})
|
||||
:install: apache site with a reverse proxy (ProxyPass)
|
||||
:remove: apache site ${APACHE_FILTRON_SITE}
|
||||
nginx (${PUBLIC_URL})
|
||||
:install: nginx site with a reverse proxy (ProxyPass)
|
||||
:remove: nginx site ${NGINX_FILTRON_SITE}
|
||||
|
||||
filtron rules: ${FILTRON_RULES}
|
||||
|
||||
If needed, set PUBLIC_URL of your WEB service in the '${DOT_CONFIG#"$REPO_ROOT/"}' file::
|
||||
PUBLIC_URL : ${PUBLIC_URL}
|
||||
PUBLIC_HOST : ${PUBLIC_HOST}
|
||||
SERVICE_USER : ${SERVICE_USER}
|
||||
FILTRON_TARGET : ${FILTRON_TARGET}
|
||||
FILTRON_API : ${FILTRON_API}
|
||||
FILTRON_LISTEN : ${FILTRON_LISTEN}
|
||||
EOF
|
||||
if in_container; then
|
||||
# in containers the service is listening on 0.0.0.0 (see lxc-searx.env)
|
||||
for ip in $(global_IPs) ; do
|
||||
if [[ $ip =~ .*:.* ]]; then
|
||||
echo " container URL (IPv6): http://[${ip#*|}]:4005/"
|
||||
else
|
||||
# IPv4:
|
||||
echo " container URL (IPv4): http://${ip#*|}:4005/"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
[[ -n ${1} ]] && err_msg "$1"
|
||||
}
|
||||
|
||||
main() {
|
||||
required_commands \
|
||||
sudo install git wget curl \
|
||||
|| exit
|
||||
|
||||
local _usage="unknown or missing $1 command $2"
|
||||
|
||||
case $1 in
|
||||
--getenv) var="$2"; echo "${!var}"; exit 0;;
|
||||
-h|--help) usage; exit 0;;
|
||||
|
||||
shell)
|
||||
sudo_or_exit
|
||||
interactive_shell "${SERVICE_USER}"
|
||||
;;
|
||||
inspect)
|
||||
case $2 in
|
||||
service)
|
||||
sudo_or_exit
|
||||
inspect_service
|
||||
;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
install)
|
||||
rst_title "$SERVICE_NAME" part
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
all) install_all ;;
|
||||
user) assert_user ;;
|
||||
rules)
|
||||
rst_title "Re-Install filtron rules"
|
||||
echo
|
||||
install_template --no-eval "$FILTRON_RULES" root root 644
|
||||
systemd_restart_service "${SERVICE_NAME}"
|
||||
;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
update)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
filtron) update_filtron ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
remove)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
all) remove_all;;
|
||||
user) drop_service_account "${SERVICE_USER}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
activate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service) systemd_activate_service "${SERVICE_NAME}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
deactivate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service) systemd_deactivate_service "${SERVICE_NAME}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
apache)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
install) install_apache_site ;;
|
||||
remove) remove_apache_site ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
nginx)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
install) install_nginx_site ;;
|
||||
remove) remove_nginx_site ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
option)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
debug-on) echo; enable_debug ;;
|
||||
debug-off) echo; disable_debug ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
doc) rst-doc ;;
|
||||
*) usage "unknown or missing command $1"; exit 42;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_all() {
|
||||
rst_title "Install $SERVICE_NAME (service)"
|
||||
assert_user
|
||||
wait_key
|
||||
install_go "${GO_PKG_URL}" "${GO_TAR}" "${SERVICE_USER}"
|
||||
wait_key
|
||||
install_filtron
|
||||
wait_key
|
||||
systemd_install_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"
|
||||
wait_key
|
||||
echo
|
||||
if ! service_is_available "http://${FILTRON_LISTEN}" ; then
|
||||
err_msg "Filtron does not listening on: http://${FILTRON_LISTEN}"
|
||||
fi
|
||||
if apache_is_installed; then
|
||||
info_msg "Apache is installed on this host."
|
||||
if ask_yn "Do you want to install a reverse proxy (ProxyPass)" Yn; then
|
||||
install_apache_site
|
||||
fi
|
||||
elif nginx_is_installed; then
|
||||
info_msg "nginx is installed on this host."
|
||||
if ask_yn "Do you want to install a reverse proxy (ProxyPass)" Yn; then
|
||||
install_nginx_site
|
||||
fi
|
||||
fi
|
||||
if ask_yn "Do you want to inspect the installation?" Ny; then
|
||||
inspect_service
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
remove_all() {
|
||||
rst_title "De-Install $SERVICE_NAME (service)"
|
||||
|
||||
rst_para "\
|
||||
It goes without saying that this script can only be used to remove
|
||||
installations that were installed with this script."
|
||||
|
||||
if ! systemd_remove_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"; then
|
||||
return 42
|
||||
fi
|
||||
drop_service_account "${SERVICE_USER}"
|
||||
rm -r "$FILTRON_ETC" 2>&1 | prefix_stdout
|
||||
if service_is_available "${PUBLIC_URL}"; then
|
||||
MSG="** Don't forget to remove your public site! (${PUBLIC_URL}) **" wait_key 10
|
||||
fi
|
||||
}
|
||||
|
||||
assert_user() {
|
||||
rst_title "user $SERVICE_USER" section
|
||||
echo
|
||||
tee_stderr 1 <<EOF | bash | prefix_stdout
|
||||
useradd --shell /bin/bash --system \
|
||||
--home-dir "$SERVICE_HOME" \
|
||||
--comment 'Reverse HTTP proxy to filter requests' $SERVICE_USER
|
||||
mkdir "$SERVICE_HOME"
|
||||
chown -R "$SERVICE_GROUP:$SERVICE_GROUP" "$SERVICE_HOME"
|
||||
groups $SERVICE_USER
|
||||
EOF
|
||||
SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
|
||||
export SERVICE_HOME
|
||||
echo "export SERVICE_HOME=$SERVICE_HOME"
|
||||
|
||||
cat > "$GO_ENV" <<EOF
|
||||
export GOPATH=\$HOME/go-apps
|
||||
export PATH=\$PATH:\$HOME/local/go/bin:\$GOPATH/bin
|
||||
EOF
|
||||
echo "Environment $GO_ENV has been setup."
|
||||
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER"
|
||||
grep -qFs -- 'source $GO_ENV' ~/.profile || echo 'source $GO_ENV' >> ~/.profile
|
||||
EOF
|
||||
}
|
||||
|
||||
filtron_is_installed() {
|
||||
[[ -f $SERVICE_HOME/go-apps/bin/filtron ]]
|
||||
}
|
||||
|
||||
_svcpr=" ${_Yellow}|${SERVICE_USER}|${_creset} "
|
||||
|
||||
install_filtron() {
|
||||
rst_title "Install filtron in user's ~/go-apps" section
|
||||
echo
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
go get -v -u github.com/asciimoo/filtron
|
||||
EOF
|
||||
install_template --no-eval "$FILTRON_RULES" root root 644
|
||||
}
|
||||
|
||||
update_filtron() {
|
||||
rst_title "Update filtron" section
|
||||
echo
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
go get -v -u github.com/asciimoo/filtron
|
||||
EOF
|
||||
}
|
||||
|
||||
inspect_service() {
|
||||
|
||||
rst_title "service status & log"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
sourced ${DOT_CONFIG#"$REPO_ROOT/"} :
|
||||
|
||||
PUBLIC_URL : ${PUBLIC_URL}
|
||||
PUBLIC_HOST : ${PUBLIC_HOST}
|
||||
FILTRON_URL_PATH : ${FILTRON_URL_PATH}
|
||||
FILTRON_API : ${FILTRON_API}
|
||||
FILTRON_LISTEN : ${FILTRON_LISTEN}
|
||||
FILTRON_TARGET : ${FILTRON_TARGET}
|
||||
|
||||
EOF
|
||||
|
||||
if service_account_is_available "$SERVICE_USER"; then
|
||||
info_msg "service account $SERVICE_USER available."
|
||||
else
|
||||
err_msg "service account $SERVICE_USER not available!"
|
||||
fi
|
||||
if go_is_available "$SERVICE_USER"; then
|
||||
info_msg "~$SERVICE_USER: go is installed"
|
||||
else
|
||||
err_msg "~$SERVICE_USER: go is not installed"
|
||||
fi
|
||||
if filtron_is_installed; then
|
||||
info_msg "~$SERVICE_USER: filtron app is installed"
|
||||
else
|
||||
err_msg "~$SERVICE_USER: filtron app is not installed!"
|
||||
fi
|
||||
|
||||
if ! service_is_available "http://${FILTRON_API}"; then
|
||||
err_msg "API not available at: http://${FILTRON_API}"
|
||||
fi
|
||||
|
||||
if ! service_is_available "http://${FILTRON_LISTEN}" ; then
|
||||
err_msg "Filtron does not listening on: http://${FILTRON_LISTEN}"
|
||||
fi
|
||||
|
||||
if service_is_available "http://${FILTRON_TARGET}" ; then
|
||||
info_msg "Filtron's target is available at: http://${FILTRON_TARGET}"
|
||||
fi
|
||||
|
||||
if ! service_is_available "${PUBLIC_URL}"; then
|
||||
warn_msg "Public service at ${PUBLIC_URL} is not available!"
|
||||
if ! in_container; then
|
||||
warn_msg "Check if public name is correct and routed or use the public IP from above."
|
||||
fi
|
||||
fi
|
||||
|
||||
if in_container; then
|
||||
lxc_suite_info
|
||||
else
|
||||
info_msg "public URL --> ${PUBLIC_URL}"
|
||||
info_msg "internal URL --> http://${FILTRON_LISTEN}"
|
||||
fi
|
||||
|
||||
|
||||
local _debug_on
|
||||
if ask_yn "Enable filtron debug mode?"; then
|
||||
enable_debug
|
||||
_debug_on=1
|
||||
fi
|
||||
echo
|
||||
systemctl --no-pager -l status "${SERVICE_NAME}"
|
||||
echo
|
||||
|
||||
info_msg "public URL --> ${PUBLIC_URL}"
|
||||
# shellcheck disable=SC2059
|
||||
printf "// use ${_BCyan}CTRL-C${_creset} to stop monitoring the log"
|
||||
read -r -s -n1 -t 5
|
||||
echo
|
||||
while true; do
|
||||
trap break 2
|
||||
journalctl -f -u "${SERVICE_NAME}"
|
||||
done
|
||||
|
||||
if [[ $_debug_on == 1 ]]; then
|
||||
disable_debug
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
|
||||
enable_debug() {
|
||||
info_msg "try to enable debug mode ..."
|
||||
python <<EOF
|
||||
import sys, json
|
||||
|
||||
debug = {
|
||||
u'name': u'debug request'
|
||||
, u'filters': []
|
||||
, u'interval': 0
|
||||
, u'limit': 0
|
||||
, u'actions': [{u'name': u'log'}]
|
||||
}
|
||||
|
||||
with open('$FILTRON_RULES') as rules:
|
||||
j = json.load(rules)
|
||||
|
||||
pos = None
|
||||
for i in range(len(j)):
|
||||
if j[i].get('name') == 'debug request':
|
||||
pos = i
|
||||
break
|
||||
if pos is not None:
|
||||
j[pos] = debug
|
||||
else:
|
||||
j.append(debug)
|
||||
with open('$FILTRON_RULES', 'w') as rules:
|
||||
json.dump(j, rules, indent=2, sort_keys=True)
|
||||
|
||||
EOF
|
||||
systemctl restart "${SERVICE_NAME}.service"
|
||||
}
|
||||
|
||||
disable_debug() {
|
||||
info_msg "try to disable debug mode ..."
|
||||
python <<EOF
|
||||
import sys, json
|
||||
with open('$FILTRON_RULES') as rules:
|
||||
j = json.load(rules)
|
||||
|
||||
pos = None
|
||||
for i in range(len(j)):
|
||||
if j[i].get('name') == 'debug request':
|
||||
pos = i
|
||||
break
|
||||
if pos is not None:
|
||||
del j[pos]
|
||||
with open('$FILTRON_RULES', 'w') as rules:
|
||||
json.dump(j, rules, indent=2, sort_keys=True)
|
||||
EOF
|
||||
systemctl restart "${SERVICE_NAME}.service"
|
||||
}
|
||||
|
||||
install_apache_site() {
|
||||
|
||||
rst_title "Install Apache site $APACHE_FILTRON_SITE"
|
||||
|
||||
rst_para "\
|
||||
This installs a reverse proxy (ProxyPass) into apache site (${APACHE_FILTRON_SITE})"
|
||||
|
||||
! apache_is_installed && info_msg "Apache is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
else
|
||||
install_apache
|
||||
fi
|
||||
|
||||
"${REPO_ROOT}/utils/searx.sh" install uwsgi
|
||||
|
||||
apache_install_site --variant=filtron "${APACHE_FILTRON_SITE}"
|
||||
|
||||
info_msg "testing public url .."
|
||||
if ! service_is_available "${PUBLIC_URL}"; then
|
||||
err_msg "Public service at ${PUBLIC_URL} is not available!"
|
||||
fi
|
||||
}
|
||||
|
||||
remove_apache_site() {
|
||||
|
||||
rst_title "Remove Apache site $APACHE_FILTRON_SITE"
|
||||
|
||||
rst_para "\
|
||||
This removes apache site ${APACHE_FILTRON_SITE}."
|
||||
|
||||
! apache_is_installed && err_msg "Apache is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
fi
|
||||
|
||||
apache_remove_site "$APACHE_FILTRON_SITE"
|
||||
|
||||
}
|
||||
|
||||
install_nginx_site() {
|
||||
|
||||
rst_title "Install nginx site $NGINX_FILTRON_SITE"
|
||||
|
||||
rst_para "\
|
||||
This installs a reverse proxy (ProxyPass) into nginx site (${NGINX_FILTRON_SITE})"
|
||||
|
||||
! nginx_is_installed && info_msg "nginx is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
else
|
||||
install_nginx
|
||||
fi
|
||||
|
||||
"${REPO_ROOT}/utils/searx.sh" install uwsgi
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
SEARX_SRC=$("${REPO_ROOT}/utils/searx.sh" --getenv SEARX_SRC)
|
||||
# shellcheck disable=SC2034
|
||||
SEARX_URL_PATH=$("${REPO_ROOT}/utils/searx.sh" --getenv SEARX_URL_PATH)
|
||||
nginx_install_app --variant=filtron "${NGINX_FILTRON_SITE}"
|
||||
|
||||
info_msg "testing public url .."
|
||||
if ! service_is_available "${PUBLIC_URL}"; then
|
||||
err_msg "Public service at ${PUBLIC_URL} is not available!"
|
||||
fi
|
||||
}
|
||||
|
||||
remove_nginx_site() {
|
||||
|
||||
rst_title "Remove nginx site $NGINX_FILTRON_SITE"
|
||||
|
||||
rst_para "\
|
||||
This removes nginx site ${NGINX_FILTRON_SITE}."
|
||||
|
||||
! nginx_is_installed && err_msg "nginx is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
fi
|
||||
|
||||
nginx_remove_site "$FILTRON_FILTRON_SITE"
|
||||
|
||||
}
|
||||
|
||||
|
||||
rst-doc() {
|
||||
|
||||
eval "echo \"$(< "${REPO_ROOT}/docs/build-templates/filtron.rst")\""
|
||||
|
||||
echo -e "\n.. START install systemd unit"
|
||||
cat <<EOF
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: systemd
|
||||
|
||||
.. code:: bash
|
||||
|
||||
EOF
|
||||
eval "echo \"$(< "${TEMPLATES}/${SERVICE_SYSTEMD_UNIT}")\"" | prefix_stdout " "
|
||||
echo -e "\n.. END install systemd unit"
|
||||
|
||||
# for DIST_NAME in ubuntu-20.04 arch fedora; do
|
||||
# (
|
||||
# DIST_ID=${DIST_NAME%-*}
|
||||
# DIST_VERS=${DIST_NAME#*-}
|
||||
# [[ $DIST_VERS =~ $DIST_ID ]] && DIST_VERS=
|
||||
# # ...
|
||||
# )
|
||||
# done
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
main "$@"
|
||||
# ----------------------------------------------------------------------------
|
1519
utils/lib.sh
Executable file
1519
utils/lib.sh
Executable file
File diff suppressed because it is too large
Load Diff
95
utils/lxc-searx.env
Normal file
95
utils/lxc-searx.env
Normal file
@ -0,0 +1,95 @@
|
||||
# -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# shellcheck shell=bash
|
||||
|
||||
# This file is a setup of a LXC suite. It is sourced from different context, do
|
||||
# not manipulate the environment directly, implement functions and manipulate
|
||||
# environment only is subshells!
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# config
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
LXC_SUITE_NAME="searx"
|
||||
lxc_set_suite_env() {
|
||||
# name of https://images.linuxcontainers.org
|
||||
export LINUXCONTAINERS_ORG_NAME="${LINUXCONTAINERS_ORG_NAME:-images}"
|
||||
export LXC_HOST_PREFIX="${LXC_SUITE_NAME:-searx}"
|
||||
export LXC_SUITE=(
|
||||
|
||||
# to disable containers, comment out lines ..
|
||||
|
||||
# end of standard support see https://wiki.ubuntu.com/Releases
|
||||
"$LINUXCONTAINERS_ORG_NAME:ubuntu/16.04" "ubu1604" # April 2021
|
||||
"$LINUXCONTAINERS_ORG_NAME:ubuntu/18.04" "ubu1804" # April 2023
|
||||
"$LINUXCONTAINERS_ORG_NAME:ubuntu/19.10" "ubu1910" # July 2020
|
||||
"$LINUXCONTAINERS_ORG_NAME:ubuntu/20.04" "ubu2004" # future (EOL 2030)
|
||||
|
||||
# EOL see https://fedoraproject.org/wiki/Releases
|
||||
"$LINUXCONTAINERS_ORG_NAME:fedora/31" "fedora31"
|
||||
|
||||
# rolling releases see https://www.archlinux.org/releng/releases/
|
||||
"$LINUXCONTAINERS_ORG_NAME:archlinux" "archlinux"
|
||||
)
|
||||
|
||||
PUBLIC_URL="${PUBLIC_URL:-http://$(uname -n)/searx}"
|
||||
if in_container; then
|
||||
# container hostnames do not have a DNS entry: use primary IP!
|
||||
PUBLIC_URL="http://$(primary_ip)/searx"
|
||||
|
||||
# make GUEST's services public to the HOST
|
||||
FILTRON_API="0.0.0.0:4005"
|
||||
FILTRON_LISTEN="0.0.0.0:4004"
|
||||
MORTY_LISTEN="0.0.0.0:3000"
|
||||
|
||||
# export LXC specific environment
|
||||
export PUBLIC_URL FILTRON_API FILTRON_LISTEN MORTY_LISTEN
|
||||
fi
|
||||
}
|
||||
|
||||
lxc_suite_install_info() {
|
||||
(
|
||||
lxc_set_suite_env
|
||||
cat <<EOF
|
||||
LXC suite: ${LXC_SUITE_NAME} --> ${PUBLIC_URL}
|
||||
suite includes searx, morty & filtron
|
||||
suite images:
|
||||
$(echo " ${LOCAL_IMAGES[*]}" | $FMT)
|
||||
suite containers:
|
||||
$(echo " ${CONTAINERS[*]}" | $FMT)
|
||||
EOF
|
||||
)
|
||||
}
|
||||
|
||||
lxc_suite_install() {
|
||||
(
|
||||
lxc_set_suite_env
|
||||
FORCE_TIMEOUT=0
|
||||
export FORCE_TIMEOUT
|
||||
"${LXC_REPO_ROOT}/utils/searx.sh" install all
|
||||
"${LXC_REPO_ROOT}/utils/morty.sh" install all
|
||||
"${LXC_REPO_ROOT}/utils/filtron.sh" install all
|
||||
|
||||
rst_title "suite installation finished ($(hostname))" part
|
||||
lxc_suite_info
|
||||
echo
|
||||
)
|
||||
}
|
||||
|
||||
lxc_suite_info() {
|
||||
(
|
||||
lxc_set_suite_env
|
||||
for ip in $(global_IPs) ; do
|
||||
if [[ $ip =~ .*:.* ]]; then
|
||||
info_msg "(${ip%|*}) IPv6: http://[${ip#*|}]"
|
||||
else
|
||||
# IPv4:
|
||||
# shellcheck disable=SC2034,SC2031
|
||||
info_msg "(${ip%|*}) filtron: http://${ip#*|}:4004/ $PUBLIC_URL"
|
||||
info_msg "(${ip%|*}) morty: http://${ip#*|}:3000/ $PUBLIC_URL_MORTY"
|
||||
info_msg "(${ip%|*}) docs-live: http://${ip#*|}:8080/"
|
||||
fi
|
||||
done
|
||||
)
|
||||
}
|
552
utils/lxc.sh
Executable file
552
utils/lxc.sh
Executable file
@ -0,0 +1,552 @@
|
||||
#!/usr/bin/env bash
|
||||
# -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# shellcheck source=utils/lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
||||
source_dot_config
|
||||
|
||||
# load environment of the LXC suite
|
||||
LXC_ENV="${LXC_ENV:-${REPO_ROOT}/utils/lxc-searx.env}"
|
||||
source "$LXC_ENV"
|
||||
lxc_set_suite_env
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# config
|
||||
# ----------------------------------------------------------------------------
|
||||
#
|
||||
# read also:
|
||||
# - https://lxd.readthedocs.io/en/latest/
|
||||
|
||||
LXC_HOST_PREFIX="${LXC_HOST_PREFIX:-test}"
|
||||
|
||||
# where all folders from HOST are mounted
|
||||
LXC_SHARE_FOLDER="/share"
|
||||
LXC_REPO_ROOT="${LXC_SHARE_FOLDER}/$(basename "${REPO_ROOT}")"
|
||||
|
||||
ubu1604_boilerplate="
|
||||
export DEBIAN_FRONTEND=noninteractive
|
||||
apt-get update -y
|
||||
apt-get upgrade -y
|
||||
apt-get install -y git curl wget
|
||||
"
|
||||
ubu1804_boilerplate="$ubu1604_boilerplate"
|
||||
ubu1904_boilerplate="$ubu1804_boilerplate"
|
||||
ubu1910_boilerplate="$ubu1904_boilerplate"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
ubu2004_boilerplate="
|
||||
$ubu1910_boilerplate
|
||||
echo 'Set disable_coredump false' >> /etc/sudo.conf
|
||||
"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
archlinux_boilerplate="
|
||||
pacman -Syu --noconfirm
|
||||
pacman -S --noconfirm inetutils git curl wget sudo
|
||||
echo 'Set disable_coredump false' >> /etc/sudo.conf
|
||||
"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
fedora31_boilerplate="
|
||||
dnf update -y
|
||||
dnf install -y git curl wget hostname
|
||||
echo 'Set disable_coredump false' >> /etc/sudo.conf
|
||||
"
|
||||
|
||||
REMOTE_IMAGES=()
|
||||
CONTAINERS=()
|
||||
LOCAL_IMAGES=()
|
||||
|
||||
for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
|
||||
REMOTE_IMAGES=("${REMOTE_IMAGES[@]}" "${LXC_SUITE[i]}")
|
||||
CONTAINERS=("${CONTAINERS[@]}" "${LXC_HOST_PREFIX}-${LXC_SUITE[i+1]}")
|
||||
LOCAL_IMAGES=("${LOCAL_IMAGES[@]}" "${LXC_SUITE[i+1]}")
|
||||
done
|
||||
|
||||
HOST_USER="${SUDO_USER:-$USER}"
|
||||
HOST_USER_ID=$(id -u "${HOST_USER}")
|
||||
HOST_GROUP_ID=$(id -g "${HOST_USER}")
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
usage() {
|
||||
# ----------------------------------------------------------------------------
|
||||
_cmd="$(basename "$0")"
|
||||
cat <<EOF
|
||||
usage::
|
||||
$_cmd build [containers|<name>]
|
||||
$_cmd copy [images]
|
||||
$_cmd remove [containers|<name>|images]
|
||||
$_cmd [start|stop] [containers|<name>]
|
||||
$_cmd show [images|suite|info|config [<name>]]
|
||||
$_cmd cmd [--|<name>] '...'
|
||||
$_cmd install [suite|base [<name>]]
|
||||
|
||||
build
|
||||
:containers: build, launch all containers and 'install base' packages
|
||||
:<name>: build, launch container <name> and 'install base' packages
|
||||
copy:
|
||||
:images: copy remote images of the suite into local storage
|
||||
remove
|
||||
:containers: delete all 'containers' or only <container-name>
|
||||
:images: delete local images of the suite
|
||||
start/stop
|
||||
:containers: start/stop all 'containers' from the suite
|
||||
:<name>: start/stop container <name> from suite
|
||||
show
|
||||
:info: show info of all (or <name>) containers from LXC suite
|
||||
:config: show config of all (or <name>) containers from the LXC suite
|
||||
:suite: show services of all (or <name>) containers from the LXC suite
|
||||
:images: show information of local images
|
||||
cmd
|
||||
use single qoutes to evaluate in container's bash, e.g.: 'echo \$(hostname)'
|
||||
-- run command '...' in all containers of the LXC suite
|
||||
:<name>: run command '...' in container <name>
|
||||
install
|
||||
:base: prepare LXC; install basic packages
|
||||
:suite: install LXC ${LXC_SUITE_NAME} suite into all (or <name>) containers
|
||||
|
||||
EOF
|
||||
usage_containers
|
||||
[ -n "${1+x}" ] && err_msg "$1"
|
||||
}
|
||||
|
||||
usage_containers() {
|
||||
lxc_suite_install_info
|
||||
[ -n "${1+x}" ] && err_msg "$1"
|
||||
}
|
||||
|
||||
lxd_info() {
|
||||
|
||||
cat <<EOF
|
||||
|
||||
LXD is needed, to install run::
|
||||
|
||||
snap install lxd
|
||||
lxd init --auto
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
|
||||
local exit_val
|
||||
local _usage="unknown or missing $1 command $2"
|
||||
|
||||
# don't check prerequisite when in recursion
|
||||
if [[ ! $1 == __* ]]; then
|
||||
if ! in_container; then
|
||||
! required_commands lxc && lxd_info && exit 42
|
||||
fi
|
||||
[[ -z $LXC_SUITE ]] && err_msg "missing LXC_SUITE" && exit 42
|
||||
fi
|
||||
|
||||
case $1 in
|
||||
--getenv) var="$2"; echo "${!var}"; exit 0;;
|
||||
-h|--help) usage; exit 0;;
|
||||
|
||||
build)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
${LXC_HOST_PREFIX}-*) build_container "$2" ;;
|
||||
''|--|containers) build_all_containers ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac
|
||||
;;
|
||||
copy)
|
||||
case $2 in
|
||||
''|images) lxc_copy_images_localy;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac
|
||||
;;
|
||||
remove)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
''|--|containers) remove_containers ;;
|
||||
images) lxc_delete_images_localy ;;
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$2" && warn_msg "container not yet exists: $2" && exit 0
|
||||
if ask_yn "Do you really want to delete container $2"; then
|
||||
lxc_delete_container "$2"
|
||||
fi
|
||||
;;
|
||||
*) usage "uknown or missing container <name> $2"; exit 42;;
|
||||
esac
|
||||
;;
|
||||
start|stop)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
''|--|containers) lxc_cmd "$1" ;;
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$2" && usage_containers "unknown container: $2" && exit 42
|
||||
info_msg "lxc $1 $2"
|
||||
lxc "$1" "$2" | prefix_stdout "[${_BBlue}${i}${_creset}] "
|
||||
;;
|
||||
*) usage "uknown or missing container <name> $2"; exit 42;;
|
||||
esac
|
||||
;;
|
||||
show)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
suite)
|
||||
case $3 in
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
lxc exec -t "$3" -- "${LXC_REPO_ROOT}/utils/lxc.sh" __show suite \
|
||||
| prefix_stdout "[${_BBlue}$3${_creset}] "
|
||||
;;
|
||||
*) show_suite;;
|
||||
esac
|
||||
;;
|
||||
images) show_images ;;
|
||||
config)
|
||||
case $3 in
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$3" && usage_containers "unknown container: $3" && exit 42
|
||||
lxc config show "$3" | prefix_stdout "[${_BBlue}${3}${_creset}] "
|
||||
;;
|
||||
*)
|
||||
rst_title "container configurations"
|
||||
echo
|
||||
lxc list "$LXC_HOST_PREFIX-"
|
||||
echo
|
||||
lxc_cmd config show
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
info)
|
||||
case $3 in
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$3" && usage_containers "unknown container: $3" && exit 42
|
||||
lxc info "$3" | prefix_stdout "[${_BBlue}${3}${_creset}] "
|
||||
;;
|
||||
*)
|
||||
rst_title "container info"
|
||||
echo
|
||||
lxc_cmd info
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac
|
||||
;;
|
||||
__show)
|
||||
# wrapped show commands, called once in each container
|
||||
case $2 in
|
||||
suite) lxc_suite_info ;;
|
||||
esac
|
||||
;;
|
||||
cmd)
|
||||
sudo_or_exit
|
||||
shift
|
||||
case $1 in
|
||||
--) shift; lxc_exec "$@" ;;
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$1" && usage_containers "unknown container: $1" && exit 42
|
||||
local name=$1
|
||||
shift
|
||||
lxc_exec_cmd "${name}" "$@"
|
||||
;;
|
||||
*) usage_containers "unknown container: $1" && exit 42
|
||||
esac
|
||||
;;
|
||||
install)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
suite|base)
|
||||
case $3 in
|
||||
${LXC_HOST_PREFIX}-*)
|
||||
! lxc_exists "$3" && usage_containers "unknown container: $3" && exit 42
|
||||
lxc_exec_cmd "$3" "${LXC_REPO_ROOT}/utils/lxc.sh" __install "$2"
|
||||
;;
|
||||
''|--) lxc_exec "${LXC_REPO_ROOT}/utils/lxc.sh" __install "$2" ;;
|
||||
*) usage_containers "unknown container: $3" && exit 42
|
||||
esac
|
||||
;;
|
||||
*) usage "$_usage"; exit 42 ;;
|
||||
esac
|
||||
;;
|
||||
__install)
|
||||
# wrapped install commands, called once in each container
|
||||
# shellcheck disable=SC2119
|
||||
case $2 in
|
||||
suite) lxc_suite_install ;;
|
||||
base) FORCE_TIMEOUT=0 lxc_install_base_packages ;;
|
||||
esac
|
||||
;;
|
||||
doc)
|
||||
echo
|
||||
echo ".. generic utils/lxc.sh documentation"
|
||||
;;
|
||||
-*) usage "unknown option $1"; exit 42;;
|
||||
*) usage "unknown or missing command $1"; exit 42;;
|
||||
esac
|
||||
}
|
||||
|
||||
|
||||
build_all_containers() {
|
||||
rst_title "Build all LXC containers of suite"
|
||||
echo
|
||||
usage_containers
|
||||
lxc_copy_images_localy
|
||||
lxc_init_all_containers
|
||||
lxc_config_all_containers
|
||||
lxc_boilerplate_all_containers
|
||||
rst_title "install LXC base packages" section
|
||||
echo
|
||||
lxc_exec "${LXC_REPO_ROOT}/utils/lxc.sh" __install base
|
||||
echo
|
||||
lxc list "$LXC_HOST_PREFIX"
|
||||
}
|
||||
|
||||
build_container() {
|
||||
rst_title "Build container $1"
|
||||
|
||||
local remote_image
|
||||
local container
|
||||
local image
|
||||
local boilerplate_script
|
||||
|
||||
for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
|
||||
if [ "${LXC_HOST_PREFIX}-${LXC_SUITE[i+1]}" = "$1" ]; then
|
||||
remote_image="${LXC_SUITE[i]}"
|
||||
container="${LXC_HOST_PREFIX}-${LXC_SUITE[i+1]}"
|
||||
image="${LXC_SUITE[i+1]}"
|
||||
boilerplate_script="${image}_boilerplate"
|
||||
boilerplate_script="${!boilerplate_script}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
echo
|
||||
if [ -z "$container" ]; then
|
||||
err_msg "container $1 unknown"
|
||||
usage_containers
|
||||
return 42
|
||||
fi
|
||||
lxc_image_copy "${remote_image}" "${image}"
|
||||
rst_title "init container" section
|
||||
lxc_init_container "${image}" "${container}"
|
||||
rst_title "configure container" section
|
||||
lxc_config_container "${container}"
|
||||
rst_title "run LXC boilerplate scripts" section
|
||||
lxc_install_boilerplate "${container}" "$boilerplate_script"
|
||||
echo
|
||||
rst_title "install LXC base packages" section
|
||||
lxc_exec_cmd "${container}" "${LXC_REPO_ROOT}/utils/lxc.sh" __install base \
|
||||
| prefix_stdout "[${_BBlue}${container}${_creset}] "
|
||||
echo
|
||||
lxc list "$container"
|
||||
}
|
||||
|
||||
remove_containers() {
|
||||
rst_title "Remove all LXC containers of suite"
|
||||
rst_para "existing containers matching ${_BGreen}$LXC_HOST_PREFIX-*${_creset}"
|
||||
echo
|
||||
lxc list "$LXC_HOST_PREFIX-"
|
||||
echo -en "\\n${_BRed}LXC containers to delete::${_creset}\\n\\n ${CONTAINERS[*]}\\n" | $FMT
|
||||
local default=Ny
|
||||
[[ $FORCE_TIMEOUT = 0 ]] && default=Yn
|
||||
if ask_yn "Do you really want to delete these containers" $default; then
|
||||
for i in "${CONTAINERS[@]}"; do
|
||||
lxc_delete_container "$i"
|
||||
done
|
||||
fi
|
||||
echo
|
||||
lxc list "$LXC_HOST_PREFIX-"
|
||||
}
|
||||
|
||||
# images
|
||||
# ------
|
||||
|
||||
lxc_copy_images_localy() {
|
||||
rst_title "copy images" section
|
||||
for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
|
||||
lxc_image_copy "${LXC_SUITE[i]}" "${LXC_SUITE[i+1]}"
|
||||
done
|
||||
# lxc image list local: && wait_key
|
||||
}
|
||||
|
||||
lxc_delete_images_localy() {
|
||||
rst_title "Delete LXC images"
|
||||
rst_para "local existing images"
|
||||
echo
|
||||
lxc image list local:
|
||||
echo -en "\\n${_BRed}LXC images to delete::${_creset}\\n\\n ${LOCAL_IMAGES[*]}\\n"
|
||||
if ask_yn "Do you really want to delete these images"; then
|
||||
for i in "${LOCAL_IMAGES[@]}"; do
|
||||
lxc_delete_local_image "$i"
|
||||
done
|
||||
fi
|
||||
|
||||
for i in $(lxc image list --format csv | grep '^,' | sed 's/,\([^,]*\).*$/\1/'); do
|
||||
if ask_yn "Image $i has no alias, do you want to delete the image?" Yn; then
|
||||
lxc_delete_local_image "$i"
|
||||
fi
|
||||
done
|
||||
|
||||
echo
|
||||
lxc image list local:
|
||||
}
|
||||
|
||||
show_images(){
|
||||
rst_title "local images"
|
||||
echo
|
||||
lxc image list local:
|
||||
echo -en "\\n${_Green}LXC suite images::${_creset}\\n\\n ${LOCAL_IMAGES[*]}\\n"
|
||||
wait_key
|
||||
for i in "${LOCAL_IMAGES[@]}"; do
|
||||
if lxc_image_exists "$i"; then
|
||||
info_msg "lxc image info ${_BBlue}${i}${_creset}"
|
||||
lxc image info "$i" | prefix_stdout "[${_BBlue}${i}${_creset}] "
|
||||
else
|
||||
warn_msg "image ${_BBlue}$i${_creset} does not yet exists"
|
||||
fi
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
|
||||
# container
|
||||
# ---------
|
||||
|
||||
show_suite(){
|
||||
rst_title "LXC suite ($LXC_HOST_PREFIX-*)"
|
||||
echo
|
||||
lxc list "$LXC_HOST_PREFIX-"
|
||||
echo
|
||||
for i in "${CONTAINERS[@]}"; do
|
||||
if ! lxc_exists "$i"; then
|
||||
warn_msg "container ${_BBlue}$i${_creset} does not yet exists"
|
||||
else
|
||||
lxc exec -t "${i}" -- "${LXC_REPO_ROOT}/utils/lxc.sh" __show suite \
|
||||
| prefix_stdout "[${_BBlue}${i}${_creset}] "
|
||||
echo
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
lxc_cmd() {
|
||||
for i in "${CONTAINERS[@]}"; do
|
||||
if ! lxc_exists "$i"; then
|
||||
warn_msg "container ${_BBlue}$i${_creset} does not yet exists"
|
||||
else
|
||||
info_msg "lxc $* $i"
|
||||
lxc "$@" "$i" | prefix_stdout "[${_BBlue}${i}${_creset}] "
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
lxc_exec_cmd() {
|
||||
local name="$1"
|
||||
shift
|
||||
exit_val=
|
||||
info_msg "[${_BBlue}${name}${_creset}] ${_BGreen}${*}${_creset}"
|
||||
lxc exec -t --cwd "${LXC_REPO_ROOT}" "${name}" -- bash -c "$*"
|
||||
exit_val=$?
|
||||
if [[ $exit_val -ne 0 ]]; then
|
||||
warn_msg "[${_BBlue}${name}${_creset}] exit code (${_BRed}${exit_val}${_creset}) from ${_BGreen}${*}${_creset}"
|
||||
else
|
||||
info_msg "[${_BBlue}${name}${_creset}] exit code (${exit_val}) from ${_BGreen}${*}${_creset}"
|
||||
fi
|
||||
}
|
||||
|
||||
lxc_exec() {
|
||||
for i in "${CONTAINERS[@]}"; do
|
||||
if ! lxc_exists "$i"; then
|
||||
warn_msg "container ${_BBlue}$i${_creset} does not yet exists"
|
||||
else
|
||||
lxc_exec_cmd "${i}" "$@" | prefix_stdout "[${_BBlue}${i}${_creset}] "
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
lxc_init_all_containers() {
|
||||
rst_title "init all containers" section
|
||||
|
||||
local image_name
|
||||
local container_name
|
||||
|
||||
for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
|
||||
lxc_init_container "${LXC_SUITE[i+1]}" "${LXC_HOST_PREFIX}-${LXC_SUITE[i+1]}"
|
||||
done
|
||||
}
|
||||
|
||||
lxc_config_all_containers() {
|
||||
rst_title "configure all containers" section
|
||||
|
||||
for i in "${CONTAINERS[@]}"; do
|
||||
lxc_config_container "${i}"
|
||||
done
|
||||
}
|
||||
|
||||
lxc_config_container() {
|
||||
info_msg "[${_BBlue}$1${_creset}] configure container ..."
|
||||
|
||||
info_msg "[${_BBlue}$1${_creset}] map uid/gid from host to container"
|
||||
# https://lxd.readthedocs.io/en/latest/userns-idmap/#custom-idmaps
|
||||
echo -e -n "uid $HOST_USER_ID 0\\ngid $HOST_GROUP_ID 0"\
|
||||
| lxc config set "$1" raw.idmap -
|
||||
|
||||
info_msg "[${_BBlue}$1${_creset}] share ${REPO_ROOT} (repo_share) from HOST into container"
|
||||
# https://lxd.readthedocs.io/en/latest/instances/#type-disk
|
||||
lxc config device add "$1" repo_share disk \
|
||||
source="${REPO_ROOT}" \
|
||||
path="${LXC_REPO_ROOT}" &>/dev/null
|
||||
# lxc config show "$1" && wait_key
|
||||
}
|
||||
|
||||
lxc_boilerplate_all_containers() {
|
||||
rst_title "run LXC boilerplate scripts" section
|
||||
|
||||
local boilerplate_script
|
||||
local image_name
|
||||
|
||||
for ((i=0; i<${#LXC_SUITE[@]}; i+=2)); do
|
||||
|
||||
image_name="${LXC_SUITE[i+1]}"
|
||||
boilerplate_script="${image_name}_boilerplate"
|
||||
boilerplate_script="${!boilerplate_script}"
|
||||
|
||||
lxc_install_boilerplate "${LXC_HOST_PREFIX}-${image_name}" "$boilerplate_script"
|
||||
|
||||
if [[ -z "${boilerplate_script}" ]]; then
|
||||
err_msg "[${_BBlue}${container_name}${_creset}] no boilerplate for image '${image_name}'"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
lxc_install_boilerplate() {
|
||||
|
||||
# usage: lxc_install_boilerplate <container-name> <string: shell commands ..>
|
||||
#
|
||||
# usage: lxc_install_boilerplate searx-archlinux "${archlinux_boilerplate}"
|
||||
|
||||
local container_name="$1"
|
||||
local boilerplate_script="$2"
|
||||
|
||||
info_msg "[${_BBlue}${container_name}${_creset}] init .."
|
||||
if lxc start -q "${container_name}" &>/dev/null; then
|
||||
sleep 5 # guest needs some time to come up and get an IP
|
||||
fi
|
||||
lxc_init_container_env "${container_name}"
|
||||
info_msg "[${_BBlue}${container_name}${_creset}] install /.lxcenv.mk .."
|
||||
cat <<EOF | lxc exec "${container_name}" -- bash | prefix_stdout "[${_BBlue}${container_name}${_creset}] "
|
||||
rm -f "/.lxcenv.mk"
|
||||
ln -s "${LXC_REPO_ROOT}/utils/makefile.lxc" "/.lxcenv.mk"
|
||||
ls -l "/.lxcenv.mk"
|
||||
EOF
|
||||
|
||||
info_msg "[${_BBlue}${container_name}${_creset}] run LXC boilerplate scripts .."
|
||||
if lxc start -q "${container_name}" &>/dev/null; then
|
||||
sleep 5 # guest needs some time to come up and get an IP
|
||||
fi
|
||||
if [[ -n "${boilerplate_script}" ]]; then
|
||||
echo "${boilerplate_script}" \
|
||||
| lxc exec "${container_name}" -- bash \
|
||||
| prefix_stdout "[${_BBlue}${container_name}${_creset}] "
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
main "$@"
|
||||
# ----------------------------------------------------------------------------
|
@ -1,12 +1,25 @@
|
||||
# -*- coding: utf-8; mode: makefile-gmake -*-
|
||||
|
||||
ifeq (,$(wildcard /.lxcenv.mk))
|
||||
PHONY += lxc-activate lxc-purge
|
||||
lxc-activate:
|
||||
@$(MAKE) -s -f /share/searx/utils/makefile.lxc lxc-activate
|
||||
lxc-purge:
|
||||
$(Q)rm -rf ./lxc
|
||||
else
|
||||
include /.lxcenv.mk
|
||||
endif
|
||||
|
||||
ifeq (,$(wildcard /.lxcenv.mk))
|
||||
make-help:
|
||||
else
|
||||
make-help: lxc-help
|
||||
endif
|
||||
@echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
|
||||
@echo ' make V=2 [targets] 2 => give reason for rebuild of target'
|
||||
|
||||
quiet_cmd_common_clean = CLEAN $@
|
||||
cmd_common_clean = \
|
||||
rm -rf tests/build ;\
|
||||
find . -name '*.orig' -exec rm -f {} + ;\
|
||||
find . -name '*.rej' -exec rm -f {} + ;\
|
||||
find . -name '*~' -exec rm -f {} + ;\
|
||||
@ -126,3 +139,4 @@ echo-cmd = $(if $($(quiet)cmd_$(1)),echo '$(call escsq,$($(quiet)cmd_$(1)))$(ech
|
||||
# printing commands
|
||||
cmd = @$(echo-cmd) $(cmd_$(1))
|
||||
|
||||
.PHONY: $(PHONY)
|
||||
|
29
utils/makefile.lxc
Normal file
29
utils/makefile.lxc
Normal file
@ -0,0 +1,29 @@
|
||||
# -*- coding: utf-8; mode: makefile-gmake -*-
|
||||
#
|
||||
# LXC environment
|
||||
# ===============
|
||||
#
|
||||
# To activate/deactivate LXC makefile environment in a container, set/unset link
|
||||
# from root '/.lxcenv.mk' to *this* file::
|
||||
#
|
||||
# sudo make ./utils/makefile.lxc lxc-activate
|
||||
# sudo make ./utils/makefile.lxc lxc-deactivate
|
||||
|
||||
LXC_ENV_FOLDER=lxc/$(shell hostname)/
|
||||
|
||||
lxc-help::
|
||||
@echo 'LXC: running in container LXC_ENV_FOLDER=$(LXC_ENV_FOLDER)'
|
||||
|
||||
# If not activated, serve target 'lxc-activate' ..
|
||||
ifeq (,$(wildcard /.lxcenv.mk))
|
||||
PHONY += lxc-activate
|
||||
lxc-activate:
|
||||
ln -s "$(abspath $(lastword $(MAKEFILE_LIST)))" "/.lxcenv.mk"
|
||||
else
|
||||
# .. and if activated, serve target 'lxc-deactivate'.
|
||||
PHONY += lxc-deactivate
|
||||
lxc-deactivate:
|
||||
rm /.lxcenv.mk
|
||||
endif
|
||||
|
||||
.PHONY: $(PHONY)
|
@ -8,9 +8,9 @@ export PYTHONPATH := $(SITE_PYTHON):$$PYTHONPATH
|
||||
export PY_ENV PYDIST PYBUILD
|
||||
|
||||
# folder where the python distribution takes place
|
||||
PYDIST ?= ./py_dist
|
||||
PYDIST = ./$(LXC_ENV_FOLDER)dist
|
||||
# folder where the python intermediate build files take place
|
||||
PYBUILD ?= ./py_build
|
||||
PYBUILD = ./$(LXC_ENV_FOLDER)build
|
||||
# python version to use
|
||||
PY ?=3
|
||||
# $(PYTHON) points to the python interpreter from the OS! The python from the
|
||||
@ -30,8 +30,7 @@ PYLINT_RC ?= .pylintrc
|
||||
TEST_FOLDER ?= ./tests
|
||||
TEST ?= .
|
||||
|
||||
VTENV_OPTS = "--no-site-packages"
|
||||
PY_ENV = ./local/py$(PY)
|
||||
PY_ENV = ./$(LXC_ENV_FOLDER)local/py$(PY)
|
||||
PY_ENV_BIN = $(PY_ENV)/bin
|
||||
PY_ENV_ACT = . $(PY_ENV_BIN)/activate
|
||||
|
||||
@ -41,6 +40,7 @@ ifeq ($(OS),Windows_NT)
|
||||
PY_ENV_ACT = $(PY_ENV_BIN)/activate
|
||||
endif
|
||||
|
||||
VTENV_OPTS ?=
|
||||
ifeq ($(PYTHON),python)
|
||||
VIRTUALENV = virtualenv
|
||||
else
|
||||
|
@ -1,17 +1,19 @@
|
||||
# -*- coding: utf-8; mode: makefile-gmake -*-
|
||||
|
||||
export DOCS_FOLDER DOCS_BUILD DOCS_DIST BOOKS_FOLDER BOOKS_DIST
|
||||
|
||||
# You can set these variables from the command line.
|
||||
SPHINXOPTS ?=
|
||||
SPHINXBUILD ?= $(PY_ENV_BIN)/sphinx-build
|
||||
SPHINX_CONF ?= conf.py
|
||||
|
||||
DOCS_FOLDER ?= docs
|
||||
DOCS_BUILD ?= build/docs
|
||||
DOCS_DIST ?= dist/docs
|
||||
DOCS_FOLDER = ./docs
|
||||
DOCS_BUILD = ./$(LXC_ENV_FOLDER)build/docs
|
||||
DOCS_DIST = ./$(LXC_ENV_FOLDER)dist/docs
|
||||
GH_PAGES ?= gh-pages
|
||||
|
||||
BOOKS_FOLDER ?= docs
|
||||
BOOKS_DIST ?= dist/books
|
||||
BOOKS_FOLDER = ./docs
|
||||
BOOKS_DIST = ./$(LXC_ENV_FOLDER)dist/books
|
||||
|
||||
ifeq ($(KBUILD_VERBOSE),1)
|
||||
SPHINX_VERBOSE = "-v"
|
||||
@ -54,11 +56,13 @@ docs-help:
|
||||
# requirements
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
sphinx-doc: $(PY_ENV)
|
||||
sphinx-doc-prebuilds:: $(PY_ENV)
|
||||
|
||||
sphinx-doc: sphinx-doc-prebuilds
|
||||
@echo "PYENV installing Sphinx$(SPHINXVERS)"
|
||||
$(Q)$(PY_ENV_BIN)/pip install $(PIP_VERBOSE) 'Sphinx$(SPHINXVERS)'
|
||||
|
||||
sphinx-live: $(PY_ENV)
|
||||
sphinx-live: sphinx-doc-prebuilds
|
||||
@echo "PYENV installing Sphinx$(SPHINXVERS)"
|
||||
$(Q)$(PY_ENV_BIN)/pip install $(PIP_VERBOSE) 'Sphinx$(SPHINXVERS)' sphinx-autobuild
|
||||
|
||||
@ -113,7 +117,7 @@ quiet_cmd_sphinx_clean = CLEAN $@
|
||||
# targets
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
# build PDF of whole documentation in: $(DOCS_DIST)/pdf
|
||||
# build PDF of whole documentation in: $(DOCS_DIST)/pdf
|
||||
|
||||
PHONY += sphinx-pdf
|
||||
sphinx-pdf: sphinx-latex
|
||||
@ -154,7 +158,7 @@ $(BOOKS_HTML): sphinx-doc | $(BOOKS_DIST)
|
||||
-b html \
|
||||
-c $(DOCS_FOLDER) \
|
||||
-d $(DOCS_BUILD)/books/$(patsubst books/%.html,%,$@)/.doctrees \
|
||||
$(patsubst books/%.html,%,$@) \
|
||||
$(BOOKS_FOLDER)/$(patsubst books/%.html,%,$@) \
|
||||
$(BOOKS_DIST)/$(patsubst books/%.html,%,$@)
|
||||
@echo "SPHINX $@ --> file://$(abspath $(BOOKS_DIST)/$(patsubst books/%.html,%,$@))"
|
||||
|
||||
@ -166,7 +170,7 @@ $(BOOKS_LIVE): sphinx-live | $(BOOKS_DIST)
|
||||
-b html \
|
||||
-c $(DOCS_FOLDER) \
|
||||
-d $(DOCS_BUILD)/books/$(patsubst books/%.live,%,$@)/.doctrees \
|
||||
$(patsubst books/%.live,%,$@) \
|
||||
$(BOOKS_FOLDER)/$(patsubst books/%.live,%,$@) \
|
||||
$(BOOKS_DIST)/$(patsubst books/%.live,%,$@)
|
||||
|
||||
$(BOOKS_PDF): %.pdf : %.latex
|
||||
@ -182,7 +186,7 @@ $(BOOKS_LATEX): sphinx-doc | $(BOOKS_DIST)
|
||||
-b latex \
|
||||
-c $(DOCS_FOLDER) \
|
||||
-d $(DOCS_BUILD)/books/$(patsubst books/%.latex,%,$@)/.doctrees \
|
||||
$(patsubst books/%.latex,%,$@) \
|
||||
$(BOOKS_FOLDER)/$(patsubst books/%.latex,%,$@) \
|
||||
$(DOCS_BUILD)/latex/$(patsubst books/%.latex,%,$@)
|
||||
@echo "SPHINX $@ --> file://$(abspath $(DOCS_BUILD)/latex/$(patsubst books/%.latex,%,$@))"
|
||||
|
||||
|
546
utils/morty.sh
Executable file
546
utils/morty.sh
Executable file
@ -0,0 +1,546 @@
|
||||
#!/usr/bin/env bash
|
||||
# -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
|
||||
# shellcheck source=utils/lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
||||
# shellcheck source=utils/brand.env
|
||||
source "${REPO_ROOT}/utils/brand.env"
|
||||
source_dot_config
|
||||
SEARX_URL="${PUBLIC_URL:-http://$(uname -n)/searx}"
|
||||
source "${REPO_ROOT}/utils/lxc-searx.env"
|
||||
in_container && lxc_set_suite_env
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# config
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
MORTY_LISTEN="${MORTY_LISTEN:-127.0.0.1:3000}"
|
||||
PUBLIC_URL_PATH_MORTY="${PUBLIC_URL_PATH_MORTY:-/morty/}"
|
||||
|
||||
PUBLIC_URL_MORTY="${PUBLIC_URL_MORTY:-$(echo "$SEARX_URL" | sed -e's,^\(.*://[^/]*\).*,\1,g')${PUBLIC_URL_PATH_MORTY}}"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
MORTY_TIMEOUT=5
|
||||
|
||||
SERVICE_NAME="morty"
|
||||
SERVICE_USER="${SERVICE_USER:-${SERVICE_NAME}}"
|
||||
SERVICE_HOME_BASE="${SERVICE_HOME_BASE:-/usr/local}"
|
||||
SERVICE_HOME="${SERVICE_HOME_BASE}/${SERVICE_USER}"
|
||||
SERVICE_SYSTEMD_UNIT="${SYSTEMD_UNITS}/${SERVICE_NAME}.service"
|
||||
# shellcheck disable=SC2034
|
||||
SERVICE_GROUP="${SERVICE_USER}"
|
||||
# shellcheck disable=SC2034
|
||||
SERVICE_ENV_DEBUG=false
|
||||
|
||||
GO_ENV="${SERVICE_HOME}/.go_env"
|
||||
GO_PKG_URL="https://dl.google.com/go/go1.13.5.linux-amd64.tar.gz"
|
||||
GO_TAR=$(basename "$GO_PKG_URL")
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_FILES=()
|
||||
|
||||
# Apache Settings
|
||||
|
||||
APACHE_MORTY_SITE="morty.conf"
|
||||
NGINX_MORTY_SITE="morty.conf"
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
usage() {
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# shellcheck disable=SC1117
|
||||
cat <<EOF
|
||||
usage::
|
||||
$(basename "$0") shell
|
||||
$(basename "$0") install [all|user]
|
||||
$(basename "$0") update [morty]
|
||||
$(basename "$0") remove [all]
|
||||
$(basename "$0") activate [service]
|
||||
$(basename "$0") deactivate [service]
|
||||
$(basename "$0") inspect [service]
|
||||
$(basename "$0") option [debug-on|debug-off|new-key]
|
||||
$(basename "$0") apache [install|remove]
|
||||
$(basename "$0") nginx [install|remove]
|
||||
$(basename "$0") info [searx]
|
||||
|
||||
shell
|
||||
start interactive shell from user ${SERVICE_USER}
|
||||
install / remove
|
||||
all: complete setup of morty service
|
||||
user: add/remove service user '$SERVICE_USER' ($SERVICE_HOME)
|
||||
update morty
|
||||
Update morty installation ($SERVICE_HOME)
|
||||
activate service
|
||||
activate and start service daemon (systemd unit)
|
||||
deactivate service
|
||||
stop and deactivate service daemon (systemd unit)
|
||||
inspect service
|
||||
show service status and log
|
||||
option
|
||||
set one of the available options
|
||||
:new-key: set new morty key
|
||||
apache : ${PUBLIC_URL_MORTY}
|
||||
:install: apache site with a reverse proxy (ProxyPass)
|
||||
:remove: apache site ${APACHE_MORTY_SITE}
|
||||
nginx (${PUBLIC_URL_MORTY})
|
||||
:install: nginx site with a reverse proxy (ProxyPass)
|
||||
:remove: nginx site ${NGINX_MORTY_SITE}
|
||||
|
||||
If needed, set the environment variables in the '${DOT_CONFIG#"$REPO_ROOT/"}' file::
|
||||
PUBLIC_URL_MORTY: ${PUBLIC_URL_MORTY}
|
||||
MORTY_LISTEN: ${MORTY_LISTEN}
|
||||
SERVICE_USER: ${SERVICE_USER}
|
||||
EOF
|
||||
if in_container; then
|
||||
# in containers the service is listening on 0.0.0.0 (see lxc-searx.env)
|
||||
for ip in $(global_IPs) ; do
|
||||
if [[ $ip =~ .*:.* ]]; then
|
||||
echo " container URL (IPv6): http://[${ip#*|}]:3000/"
|
||||
else
|
||||
# IPv4:
|
||||
echo " container URL (IPv4): http://${ip#*|}:3000/"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
echo
|
||||
info_searx
|
||||
|
||||
[[ -n ${1} ]] && err_msg "$1"
|
||||
}
|
||||
|
||||
info_searx() {
|
||||
# shellcheck disable=SC1117
|
||||
cat <<EOF
|
||||
To activate result and image proxy in searx, edit settings.yml (read:
|
||||
${DOCS_URL}/admin/morty.html)::
|
||||
result_proxy:
|
||||
url : ${PUBLIC_URL_MORTY}
|
||||
server:
|
||||
image_proxy : True
|
||||
EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
required_commands \
|
||||
sudo install git wget curl \
|
||||
|| exit
|
||||
|
||||
local _usage="ERROR: unknown or missing $1 command $2"
|
||||
|
||||
case $1 in
|
||||
--getenv) var="$2"; echo "${!var}"; exit 0;;
|
||||
-h|--help) usage; exit 0;;
|
||||
|
||||
shell)
|
||||
sudo_or_exit
|
||||
interactive_shell "${SERVICE_USER}"
|
||||
;;
|
||||
inspect)
|
||||
case $2 in
|
||||
service)
|
||||
sudo_or_exit
|
||||
inspect_service
|
||||
;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
install)
|
||||
rst_title "$SERVICE_NAME" part
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
all) install_all ;;
|
||||
user) assert_user ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
update)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
morty) update_morty ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
remove)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
all) remove_all;;
|
||||
user) drop_service_account "${SERVICE_USER}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
activate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service) systemd_activate_service "${SERVICE_NAME}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
deactivate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service) systemd_deactivate_service "${SERVICE_NAME}" ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
apache)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
install) install_apache_site ;;
|
||||
remove) remove_apache_site ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
nginx)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
install) install_nginx_site ;;
|
||||
remove) remove_nginx_site ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
info)
|
||||
case $2 in
|
||||
searx) info_searx ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
option)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
new-key) set_new_key ;;
|
||||
debug-on) enable_debug ;;
|
||||
debug-off) disable_debug ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
doc) rst-doc ;;
|
||||
*) usage "ERROR: unknown or missing command $1"; exit 42;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_all() {
|
||||
|
||||
MORTY_KEY="$(head -c 32 /dev/urandom | base64)"
|
||||
|
||||
rst_title "Install $SERVICE_NAME (service)"
|
||||
assert_user
|
||||
wait_key
|
||||
install_go "${GO_PKG_URL}" "${GO_TAR}" "${SERVICE_USER}"
|
||||
wait_key
|
||||
install_morty
|
||||
wait_key
|
||||
systemd_install_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"
|
||||
wait_key
|
||||
if ! service_is_available "http://${MORTY_LISTEN}" ; then
|
||||
err_msg "Morty does not listening on: http://${MORTY_LISTEN}"
|
||||
fi
|
||||
if apache_is_installed; then
|
||||
info_msg "Apache is installed on this host."
|
||||
if ask_yn "Do you want to install a reverse proxy (ProxyPass)" Yn; then
|
||||
install_apache_site
|
||||
fi
|
||||
elif nginx_is_installed; then
|
||||
info_msg "nginx is installed on this host."
|
||||
if ask_yn "Do you want to install a reverse proxy (ProxyPass)" Yn; then
|
||||
install_nginx_site
|
||||
fi
|
||||
fi
|
||||
info_searx
|
||||
if ask_yn "Add image and result proxy to searx settings.yml?" Yn; then
|
||||
"${REPO_ROOT}/utils/searx.sh" option result-proxy "${PUBLIC_URL_MORTY}" "${MORTY_KEY}"
|
||||
"${REPO_ROOT}/utils/searx.sh" option image-proxy-on
|
||||
fi
|
||||
|
||||
if ask_yn "Do you want to inspect the installation?" Ny; then
|
||||
inspect_service
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
remove_all() {
|
||||
rst_title "De-Install $SERVICE_NAME (service)"
|
||||
|
||||
rst_para "\
|
||||
It goes without saying that this script can only be used to remove
|
||||
installations that were installed with this script."
|
||||
|
||||
if systemd_remove_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"; then
|
||||
drop_service_account "${SERVICE_USER}"
|
||||
fi
|
||||
}
|
||||
|
||||
assert_user() {
|
||||
rst_title "user $SERVICE_USER" section
|
||||
echo
|
||||
tee_stderr 1 <<EOF | bash | prefix_stdout
|
||||
useradd --shell /bin/bash --system \
|
||||
--home-dir "$SERVICE_HOME" \
|
||||
--comment 'Web content sanitizer proxy' $SERVICE_USER
|
||||
mkdir "$SERVICE_HOME"
|
||||
chown -R "$SERVICE_GROUP:$SERVICE_GROUP" "$SERVICE_HOME"
|
||||
groups $SERVICE_USER
|
||||
EOF
|
||||
SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
|
||||
export SERVICE_HOME
|
||||
echo "export SERVICE_HOME=$SERVICE_HOME"
|
||||
|
||||
cat > "$GO_ENV" <<EOF
|
||||
export GOPATH=\$HOME/go-apps
|
||||
export PATH=\$PATH:\$HOME/local/go/bin:\$GOPATH/bin
|
||||
EOF
|
||||
echo "Environment $GO_ENV has been setup."
|
||||
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER"
|
||||
grep -qFs -- 'source $GO_ENV' ~/.profile || echo 'source $GO_ENV' >> ~/.profile
|
||||
EOF
|
||||
}
|
||||
|
||||
morty_is_installed() {
|
||||
[[ -f $SERVICE_HOME/go-apps/bin/morty ]]
|
||||
}
|
||||
|
||||
_svcpr=" ${_Yellow}|${SERVICE_USER}|${_creset} "
|
||||
|
||||
install_morty() {
|
||||
rst_title "Install morty in user's ~/go-apps" section
|
||||
echo
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
go get -v -u github.com/asciimoo/morty
|
||||
EOF
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
cd \$GOPATH/src/github.com/asciimoo/morty
|
||||
go test
|
||||
go test -benchmem -bench .
|
||||
EOF
|
||||
}
|
||||
|
||||
update_morty() {
|
||||
rst_title "Update morty" section
|
||||
echo
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
go get -v -u github.com/asciimoo/morty
|
||||
EOF
|
||||
tee_stderr <<EOF | sudo -i -u "$SERVICE_USER" 2>&1 | prefix_stdout "$_svcpr"
|
||||
cd \$GOPATH/src/github.com/asciimoo/morty
|
||||
go test
|
||||
go test -benchmem -bench .
|
||||
EOF
|
||||
}
|
||||
|
||||
set_service_env_debug() {
|
||||
|
||||
# usage: set_service_env_debug [false|true]
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
local SERVICE_ENV_DEBUG="${1:-false}"
|
||||
if systemd_remove_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"; then
|
||||
systemd_install_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"
|
||||
fi
|
||||
}
|
||||
|
||||
inspect_service() {
|
||||
|
||||
rst_title "service status & log"
|
||||
|
||||
cat <<EOF
|
||||
|
||||
sourced ${DOT_CONFIG#"$REPO_ROOT/"} :
|
||||
|
||||
MORTY_LISTEN : ${MORTY_LISTEN}
|
||||
|
||||
EOF
|
||||
|
||||
if service_account_is_available "$SERVICE_USER"; then
|
||||
info_msg "service account $SERVICE_USER available."
|
||||
else
|
||||
err_msg "service account $SERVICE_USER not available!"
|
||||
fi
|
||||
if go_is_available "$SERVICE_USER"; then
|
||||
info_msg "~$SERVICE_USER: go is installed"
|
||||
else
|
||||
err_msg "~$SERVICE_USER: go is not installed"
|
||||
fi
|
||||
if morty_is_installed; then
|
||||
info_msg "~$SERVICE_USER: morty app is installed"
|
||||
else
|
||||
err_msg "~$SERVICE_USER: morty app is not installed!"
|
||||
fi
|
||||
|
||||
if ! service_is_available "http://${MORTY_LISTEN}" ; then
|
||||
err_msg "Morty does not listening on: http://${MORTY_LISTEN}"
|
||||
echo -e "${_Green}stop with [${_BCyan}CTRL-C${_Green}] or .."
|
||||
wait_key
|
||||
fi
|
||||
|
||||
if ! service_is_available "${PUBLIC_URL_MORTY}"; then
|
||||
warn_msg "Public service at ${PUBLIC_URL_MORTY} is not available!"
|
||||
if ! in_container; then
|
||||
warn_msg "Check if public name is correct and routed or use the public IP from above."
|
||||
fi
|
||||
fi
|
||||
|
||||
if in_container; then
|
||||
lxc_suite_info
|
||||
else
|
||||
info_msg "public URL --> ${PUBLIC_URL_MORTY}"
|
||||
info_msg "morty URL --> http://${MORTY_LISTEN}"
|
||||
fi
|
||||
|
||||
local _debug_on
|
||||
if ask_yn "Enable morty debug mode (needs reinstall of systemd service)?"; then
|
||||
enable_debug
|
||||
_debug_on=1
|
||||
else
|
||||
systemctl --no-pager -l status "${SERVICE_NAME}"
|
||||
fi
|
||||
echo
|
||||
|
||||
# shellcheck disable=SC2059
|
||||
printf "// use ${_BCyan}CTRL-C${_creset} to stop monitoring the log"
|
||||
read -r -s -n1 -t 5
|
||||
echo
|
||||
while true; do
|
||||
trap break 2
|
||||
journalctl -f -u "${SERVICE_NAME}"
|
||||
done
|
||||
|
||||
if [[ $_debug_on == 1 ]]; then
|
||||
FORCE_SELECTION=Y disable_debug
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
enable_debug() {
|
||||
warn_msg "Do not enable debug in production enviroments!!"
|
||||
info_msg "Enabling debug option needs to reinstall systemd service!"
|
||||
set_service_env_debug true
|
||||
}
|
||||
|
||||
disable_debug() {
|
||||
info_msg "Disabling debug option needs to reinstall systemd service!"
|
||||
set_service_env_debug false
|
||||
}
|
||||
|
||||
|
||||
set_new_key() {
|
||||
rst_title "Set morty key"
|
||||
echo
|
||||
|
||||
MORTY_KEY="$(head -c 32 /dev/urandom | base64)"
|
||||
info_msg "morty key: '${MORTY_KEY}'"
|
||||
|
||||
warn_msg "this will need to reinstall services .."
|
||||
MSG="${_Green}press any [${_BCyan}KEY${_Green}] to continue // stop with [${_BCyan}CTRL-C${_creset}]" wait_key
|
||||
|
||||
systemd_install_service "${SERVICE_NAME}" "${SERVICE_SYSTEMD_UNIT}"
|
||||
"${REPO_ROOT}/utils/searx.sh" option result-proxy "${PUBLIC_URL_MORTY}" "${MORTY_KEY}"
|
||||
"${REPO_ROOT}/utils/searx.sh" option image-proxy-on
|
||||
}
|
||||
|
||||
|
||||
install_apache_site() {
|
||||
|
||||
rst_title "Install Apache site $APACHE_MORTY_SITE"
|
||||
|
||||
rst_para "\
|
||||
This installs a reverse proxy (ProxyPass) into apache site (${APACHE_MORTY_SITE})"
|
||||
|
||||
! apache_is_installed && err_msg "Apache is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
else
|
||||
install_apache
|
||||
fi
|
||||
|
||||
apache_install_site "${APACHE_MORTY_SITE}"
|
||||
|
||||
info_msg "testing public url .."
|
||||
if ! service_is_available "${PUBLIC_URL_MORTY}"; then
|
||||
err_msg "Public service at ${PUBLIC_URL_MORTY} is not available!"
|
||||
fi
|
||||
}
|
||||
|
||||
remove_apache_site() {
|
||||
|
||||
rst_title "Remove Apache site $APACHE_MORTY_SITE"
|
||||
|
||||
rst_para "\
|
||||
This removes apache site ${APACHE_MORTY_SITE}."
|
||||
|
||||
! apache_is_installed && err_msg "Apache is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
fi
|
||||
|
||||
apache_remove_site "$APACHE_MORTY_SITE"
|
||||
}
|
||||
|
||||
install_nginx_site() {
|
||||
|
||||
rst_title "Install nginx site $NGINX_MORTY_SITE"
|
||||
|
||||
rst_para "\
|
||||
This installs a reverse proxy (ProxyPass) into nginx site (${NGINX_MORTY_SITE})"
|
||||
|
||||
! nginx_is_installed && err_msg "nginx is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
else
|
||||
install_nginx
|
||||
fi
|
||||
|
||||
"${REPO_ROOT}/utils/searx.sh" install uwsgi
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
SEARX_SRC=$("${REPO_ROOT}/utils/searx.sh" --getenv SEARX_SRC)
|
||||
# shellcheck disable=SC2034
|
||||
SEARX_URL_PATH=$("${REPO_ROOT}/utils/searx.sh" --getenv SEARX_URL_PATH)
|
||||
nginx_install_app "${NGINX_MORTY_SITE}"
|
||||
|
||||
info_msg "testing public url .."
|
||||
if ! service_is_available "${PUBLIC_URL_MORTY}"; then
|
||||
err_msg "Public service at ${PUBLIC_URL_MORTY} is not available!"
|
||||
fi
|
||||
}
|
||||
|
||||
remove_nginx_site() {
|
||||
|
||||
rst_title "Remove nginx site $NGINX_MORTY_SITE"
|
||||
|
||||
rst_para "\
|
||||
This removes nginx site ${NGINX_MORTY_SITE}."
|
||||
|
||||
! nginx_is_installed && err_msg "nginx is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
fi
|
||||
|
||||
nginx_remove_site "$NGINX_MORTY_SITE"
|
||||
|
||||
}
|
||||
|
||||
rst-doc() {
|
||||
|
||||
eval "echo \"$(< "${REPO_ROOT}/docs/build-templates/morty.rst")\""
|
||||
|
||||
echo -e "\n.. START install systemd unit"
|
||||
cat <<EOF
|
||||
.. tabs::
|
||||
|
||||
.. group-tab:: systemd
|
||||
|
||||
.. code:: bash
|
||||
|
||||
EOF
|
||||
eval "echo \"$(< "${TEMPLATES}/${SERVICE_SYSTEMD_UNIT}")\"" | prefix_stdout " "
|
||||
echo -e "\n.. END install systemd unit"
|
||||
|
||||
# for DIST_NAME in ubuntu-20.04 arch fedora; do
|
||||
# (
|
||||
# DIST_ID=${DIST_NAME%-*}
|
||||
# DIST_VERS=${DIST_NAME#*-}
|
||||
# [[ $DIST_VERS =~ $DIST_ID ]] && DIST_VERS=
|
||||
# # ...
|
||||
# )
|
||||
# done
|
||||
}
|
||||
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
main "$@"
|
||||
# ----------------------------------------------------------------------------
|
869
utils/searx.sh
Executable file
869
utils/searx.sh
Executable file
@ -0,0 +1,869 @@
|
||||
#!/usr/bin/env bash
|
||||
# -*- coding: utf-8; mode: sh indent-tabs-mode: nil -*-
|
||||
# SPDX-License-Identifier: AGPL-3.0-or-later
|
||||
# shellcheck disable=SC2001
|
||||
|
||||
# shellcheck source=utils/lib.sh
|
||||
source "$(dirname "${BASH_SOURCE[0]}")/lib.sh"
|
||||
# shellcheck source=utils/brand.env
|
||||
source "${REPO_ROOT}/utils/brand.env"
|
||||
source_dot_config
|
||||
source "${REPO_ROOT}/utils/lxc-searx.env"
|
||||
in_container && lxc_set_suite_env
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# config
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
PUBLIC_URL="${PUBLIC_URL:-http://$(uname -n)/searx}"
|
||||
|
||||
SEARX_INTERNAL_HTTP="${SEARX_INTERNAL_HTTP:-127.0.0.1:8888}"
|
||||
|
||||
SEARX_URL_PATH="${SEARX_URL_PATH:-$(echo "${PUBLIC_URL}" \
|
||||
| sed -e 's,^.*://[^/]*\(/.*\),\1,g')}"
|
||||
[[ "${SEARX_URL_PATH}" == "${PUBLIC_URL}" ]] && SEARX_URL_PATH=/
|
||||
SEARX_INSTANCE_NAME="${SEARX_INSTANCE_NAME:-searx@$(echo "$PUBLIC_URL" \
|
||||
| sed -e 's,^.*://\([^\:/]*\).*,\1,g') }"
|
||||
|
||||
SERVICE_NAME="searx"
|
||||
SERVICE_USER="${SERVICE_USER:-${SERVICE_NAME}}"
|
||||
SERVICE_HOME_BASE="${SERVICE_HOME_BASE:-/usr/local}"
|
||||
SERVICE_HOME="${SERVICE_HOME_BASE}/${SERVICE_USER}"
|
||||
# shellcheck disable=SC2034
|
||||
SERVICE_GROUP="${SERVICE_USER}"
|
||||
|
||||
GIT_BRANCH="${GIT_BRANCH:-master}"
|
||||
SEARX_PYENV="${SERVICE_HOME}/searx-pyenv"
|
||||
SEARX_SRC="${SERVICE_HOME}/searx-src"
|
||||
SEARX_SETTINGS_PATH="/etc/searx/settings.yml"
|
||||
SEARX_UWSGI_APP="searx.ini"
|
||||
# shellcheck disable=SC2034
|
||||
SEARX_UWSGI_SOCKET="/run/uwsgi/app/searx/socket"
|
||||
|
||||
# apt packages
|
||||
SEARX_PACKAGES_debian="\
|
||||
virtualenv python3-dev python3-babel python3-venv
|
||||
uwsgi uwsgi-plugin-python3
|
||||
git build-essential libxslt-dev zlib1g-dev libffi-dev libssl-dev
|
||||
shellcheck"
|
||||
|
||||
BUILD_PACKAGES_debian="\
|
||||
firefox graphviz imagemagick texlive-xetex librsvg2-bin
|
||||
texlive-latex-recommended texlive-extra-utils ttf-dejavu
|
||||
latexmk"
|
||||
|
||||
# pacman packages
|
||||
SEARX_PACKAGES_arch="\
|
||||
python-virtualenv python python-pip python-lxml python-babel
|
||||
uwsgi uwsgi-plugin-python
|
||||
git base-devel libxml2
|
||||
shellcheck"
|
||||
|
||||
BUILD_PACKAGES_arch="\
|
||||
firefox graphviz imagemagick texlive-bin extra/librsvg
|
||||
texlive-core texlive-latexextra ttf-dejavu"
|
||||
|
||||
# dnf packages
|
||||
SEARX_PACKAGES_fedora="\
|
||||
virtualenv python python-pip python-lxml python-babel
|
||||
uwsgi uwsgi-plugin-python3
|
||||
git @development-tools libxml2
|
||||
ShellCheck"
|
||||
|
||||
BUILD_PACKAGES_fedora="\
|
||||
firefox graphviz graphviz-gd ImageMagick librsvg2-tools
|
||||
texlive-xetex-bin texlive-collection-fontsrecommended
|
||||
texlive-collection-latex dejavu-sans-fonts dejavu-serif-fonts
|
||||
dejavu-sans-mono-fonts"
|
||||
|
||||
case $DIST_ID-$DIST_VERS in
|
||||
ubuntu-16.04|ubuntu-18.04)
|
||||
SEARX_PACKAGES="${SEARX_PACKAGES_debian}"
|
||||
BUILD_PACKAGES="${BUILD_PACKAGES_debian}"
|
||||
APACHE_PACKAGES="$APACHE_PACKAGES libapache2-mod-proxy-uwsgi"
|
||||
;;
|
||||
ubuntu-20.04)
|
||||
# https://askubuntu.com/a/1224710
|
||||
SEARX_PACKAGES="${SEARX_PACKAGES_debian} python-is-python3"
|
||||
BUILD_PACKAGES="${BUILD_PACKAGES_debian}"
|
||||
;;
|
||||
ubuntu-*|debian-*)
|
||||
SEARX_PACKAGES="${SEARX_PACKAGES_debian}"
|
||||
BUILD_PACKAGES="${BUILD_PACKAGES_debian}"
|
||||
;;
|
||||
arch-*)
|
||||
SEARX_PACKAGES="${SEARX_PACKAGES_arch}"
|
||||
BUILD_PACKAGES="${BUILD_PACKAGES_arch}"
|
||||
;;
|
||||
fedora-*)
|
||||
SEARX_PACKAGES="${SEARX_PACKAGES_fedora}"
|
||||
BUILD_PACKAGES="${BUILD_PACKAGES_fedora}"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Apache Settings
|
||||
APACHE_SEARX_SITE="searx.conf"
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_FILES=(
|
||||
"${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}"
|
||||
)
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
CONFIG_BACKUP_ENCRYPTED=(
|
||||
"${SEARX_SETTINGS_PATH}"
|
||||
)
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
usage() {
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# shellcheck disable=SC1117
|
||||
cat <<EOF
|
||||
usage::
|
||||
$(basename "$0") shell
|
||||
$(basename "$0") install [all|user|searx-src|pyenv|uwsgi|packages|buildhost]
|
||||
$(basename "$0") update [searx]
|
||||
$(basename "$0") remove [all|user|pyenv|searx-src]
|
||||
$(basename "$0") activate [service]
|
||||
$(basename "$0") deactivate [service]
|
||||
$(basename "$0") inspect [service]
|
||||
$(basename "$0") option [debug-[on|off]|image-proxy-[on|off]|result-proxy <url> <key>]
|
||||
$(basename "$0") apache [install|remove]
|
||||
|
||||
shell
|
||||
start interactive shell from user ${SERVICE_USER}
|
||||
install / remove
|
||||
:all: complete (de-) installation of searx service
|
||||
:user: add/remove service user '$SERVICE_USER' ($SERVICE_HOME)
|
||||
:searx-src: clone $GIT_URL
|
||||
:pyenv: create/remove virtualenv (python) in $SEARX_PYENV
|
||||
:uwsgi: install searx uWSGI application
|
||||
:settings: reinstall settings from ${REPO_ROOT}/searx/settings.yml
|
||||
:packages: install needed packages from OS package manager
|
||||
:buildhost: install packages from OS package manager needed by buildhosts
|
||||
update searx
|
||||
Update searx installation ($SERVICE_HOME)
|
||||
activate service
|
||||
activate and start service daemon (systemd unit)
|
||||
deactivate service
|
||||
stop and deactivate service daemon (systemd unit)
|
||||
inspect service
|
||||
run some small tests and inspect service's status and log
|
||||
option
|
||||
set one of the available options
|
||||
apache
|
||||
:install: apache site with the searx uwsgi app
|
||||
:remove: apache site ${APACHE_FILTRON_SITE}
|
||||
|
||||
searx settings: ${SEARX_SETTINGS_PATH}
|
||||
|
||||
If needed, set PUBLIC_URL of your WEB service in the '${DOT_CONFIG#"$REPO_ROOT/"}' file::
|
||||
PUBLIC_URL : ${PUBLIC_URL}
|
||||
SEARX_INSTANCE_NAME : ${SEARX_INSTANCE_NAME}
|
||||
SERVICE_USER : ${SERVICE_USER}
|
||||
SEARX_INTERNAL_HTTP : http://${SEARX_INTERNAL_HTTP}
|
||||
EOF
|
||||
if in_container; then
|
||||
# searx is listening on 127.0.0.1 and not available from outside container
|
||||
# in containers the service is listening on 0.0.0.0 (see lxc-searx.env)
|
||||
echo -e "${_BBlack}HINT:${_creset} searx only listen on loopback device" \
|
||||
"${_BBlack}inside${_creset} the container."
|
||||
for ip in $(global_IPs) ; do
|
||||
if [[ $ip =~ .*:.* ]]; then
|
||||
echo " container (IPv6): [${ip#*|}]"
|
||||
else
|
||||
# IPv4:
|
||||
echo " container (IPv4): ${ip#*|}"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
[[ -n ${1} ]] && err_msg "$1"
|
||||
}
|
||||
|
||||
main() {
|
||||
required_commands \
|
||||
sudo systemctl install git wget curl \
|
||||
|| exit
|
||||
|
||||
local _usage="unknown or missing $1 command $2"
|
||||
|
||||
case $1 in
|
||||
--getenv) var="$2"; echo "${!var}"; exit 0;;
|
||||
-h|--help) usage; exit 0;;
|
||||
shell)
|
||||
sudo_or_exit
|
||||
interactive_shell "${SERVICE_USER}"
|
||||
;;
|
||||
inspect)
|
||||
case $2 in
|
||||
service)
|
||||
sudo_or_exit
|
||||
inspect_service
|
||||
;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
install)
|
||||
rst_title "$SEARX_INSTANCE_NAME" part
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
all) install_all ;;
|
||||
user) assert_user ;;
|
||||
pyenv) create_pyenv ;;
|
||||
searx-src) clone_searx ;;
|
||||
settings) install_settings ;;
|
||||
uwsgi)
|
||||
install_searx_uwsgi
|
||||
if ! service_is_available "http://${SEARX_INTERNAL_HTTP}"; then
|
||||
err_msg "URL http://${SEARX_INTERNAL_HTTP} not available, check searx & uwsgi setup!"
|
||||
fi
|
||||
;;
|
||||
packages)
|
||||
pkg_install "$SEARX_PACKAGES"
|
||||
;;
|
||||
buildhost)
|
||||
pkg_install "$SEARX_PACKAGES"
|
||||
pkg_install "$BUILD_PACKAGES"
|
||||
;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
update)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
searx) update_searx;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
remove)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
all) remove_all;;
|
||||
user) drop_service_account "${SERVICE_USER}";;
|
||||
pyenv) remove_pyenv ;;
|
||||
searx-src) remove_searx ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
activate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service)
|
||||
activate_service ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
deactivate)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
service) deactivate_service ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
option)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
debug-on) echo; enable_debug ;;
|
||||
debug-off) echo; disable_debug ;;
|
||||
result-proxy) set_result_proxy "$3" "$4" ;;
|
||||
image-proxy-on) enable_image_proxy ;;
|
||||
image-proxy-off) disable_image_proxy ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
apache)
|
||||
sudo_or_exit
|
||||
case $2 in
|
||||
install) install_apache_site ;;
|
||||
remove) remove_apache_site ;;
|
||||
*) usage "$_usage"; exit 42;;
|
||||
esac ;;
|
||||
doc) rst-doc;;
|
||||
*) usage "unknown or missing command $1"; exit 42;;
|
||||
esac
|
||||
}
|
||||
|
||||
_service_prefix=" ${_Yellow}|$SERVICE_USER|${_creset} "
|
||||
|
||||
install_all() {
|
||||
rst_title "Install $SEARX_INSTANCE_NAME (service)"
|
||||
pkg_install "$SEARX_PACKAGES"
|
||||
wait_key
|
||||
assert_user
|
||||
wait_key
|
||||
clone_searx
|
||||
wait_key
|
||||
create_pyenv
|
||||
wait_key
|
||||
install_settings
|
||||
wait_key
|
||||
test_local_searx
|
||||
wait_key
|
||||
install_searx_uwsgi
|
||||
if ! service_is_available "http://${SEARX_INTERNAL_HTTP}"; then
|
||||
err_msg "URL http://${SEARX_INTERNAL_HTTP} not available, check searx & uwsgi setup!"
|
||||
fi
|
||||
if ask_yn "Do you want to inspect the installation?" Ny; then
|
||||
inspect_service
|
||||
fi
|
||||
}
|
||||
|
||||
update_searx() {
|
||||
rst_title "Update searx instance"
|
||||
|
||||
echo
|
||||
tee_stderr 0.3 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
git checkout -B "$GIT_BRANCH"
|
||||
git pull
|
||||
pip install -U pip
|
||||
pip install -U setuptools
|
||||
pip install -U wheel
|
||||
pip install -U -e .
|
||||
EOF
|
||||
install_settings
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
remove_all() {
|
||||
rst_title "De-Install $SEARX_INSTANCE_NAME (service)"
|
||||
|
||||
rst_para "\
|
||||
It goes without saying that this script can only be used to remove
|
||||
installations that were installed with this script."
|
||||
|
||||
if ! ask_yn "Do you really want to deinstall $SEARX_INSTANCE_NAME?"; then
|
||||
return
|
||||
fi
|
||||
remove_searx_uwsgi
|
||||
drop_service_account "${SERVICE_USER}"
|
||||
remove_settings
|
||||
wait_key
|
||||
if service_is_available "${PUBLIC_URL}"; then
|
||||
MSG="** Don't forgett to remove your public site! (${PUBLIC_URL}) **" wait_key 10
|
||||
fi
|
||||
}
|
||||
|
||||
assert_user() {
|
||||
rst_title "user $SERVICE_USER" section
|
||||
echo
|
||||
tee_stderr 1 <<EOF | bash | prefix_stdout
|
||||
useradd --shell /bin/bash --system \
|
||||
--home-dir "$SERVICE_HOME" \
|
||||
--comment 'Privacy-respecting metasearch engine' $SERVICE_USER
|
||||
mkdir "$SERVICE_HOME"
|
||||
chown -R "$SERVICE_GROUP:$SERVICE_GROUP" "$SERVICE_HOME"
|
||||
groups $SERVICE_USER
|
||||
EOF
|
||||
#SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME)"
|
||||
#export SERVICE_HOME
|
||||
#echo "export SERVICE_HOME=$SERVICE_HOME"
|
||||
}
|
||||
|
||||
clone_is_available() {
|
||||
[[ -f "$SEARX_SRC/.git/config" ]]
|
||||
}
|
||||
|
||||
# shellcheck disable=SC2164
|
||||
clone_searx() {
|
||||
rst_title "Clone searx sources" section
|
||||
echo
|
||||
if ! sudo -i -u "$SERVICE_USER" ls -d "$REPO_ROOT" > /dev/null; then
|
||||
die 42 "user '$SERVICE_USER' missed read permission: $REPO_ROOT"
|
||||
fi
|
||||
SERVICE_HOME="$(sudo -i -u "$SERVICE_USER" echo \$HOME 2>/dev/null)"
|
||||
if [[ ! "${SERVICE_HOME}" ]]; then
|
||||
err_msg "to clone searx sources, user $SERVICE_USER hast to be created first"
|
||||
return 42
|
||||
fi
|
||||
export SERVICE_HOME
|
||||
git_clone "$REPO_ROOT" "$SEARX_SRC" \
|
||||
"$GIT_BRANCH" "$SERVICE_USER"
|
||||
|
||||
pushd "${SEARX_SRC}" > /dev/null
|
||||
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd "${SEARX_SRC}"
|
||||
git remote set-url origin ${GIT_URL}
|
||||
git config user.email "$ADMIN_EMAIL"
|
||||
git config user.name "$ADMIN_NAME"
|
||||
git config --list
|
||||
EOF
|
||||
popd > /dev/null
|
||||
}
|
||||
|
||||
install_settings() {
|
||||
rst_title "${SEARX_SETTINGS_PATH}" section
|
||||
if ! clone_is_available; then
|
||||
err_msg "you have to install searx first"
|
||||
exit 42
|
||||
fi
|
||||
mkdir -p "$(dirname ${SEARX_SETTINGS_PATH})"
|
||||
|
||||
if [[ ! -f ${SEARX_SETTINGS_PATH} ]]; then
|
||||
info_msg "install settings ${REPO_ROOT}/searx/settings.yml"
|
||||
info_msg " --> ${SEARX_SETTINGS_PATH}"
|
||||
cp "${REPO_ROOT}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
|
||||
configure_searx
|
||||
return
|
||||
fi
|
||||
|
||||
rst_para "Diff between origin's setting file (+) and current (-):"
|
||||
echo
|
||||
$DIFF_CMD "${SEARX_SETTINGS_PATH}" "${SEARX_SRC}/searx/settings.yml"
|
||||
|
||||
local action
|
||||
choose_one action "What should happen to the settings file? " \
|
||||
"keep configuration unchanged" \
|
||||
"use origin settings" \
|
||||
"start interactiv shell"
|
||||
case $action in
|
||||
"keep configuration unchanged")
|
||||
info_msg "leave settings file unchanged"
|
||||
;;
|
||||
"use origin settings")
|
||||
backup_file "${SEARX_SETTINGS_PATH}"
|
||||
info_msg "install origin settings"
|
||||
cp "${SEARX_SRC}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
|
||||
;;
|
||||
"start interactiv shell")
|
||||
backup_file "${SEARX_SETTINGS_PATH}"
|
||||
echo -e "// exit with [${_BCyan}CTRL-D${_creset}]"
|
||||
sudo -H -i
|
||||
rst_para 'Diff between new setting file (-) and current (+):'
|
||||
echo
|
||||
$DIFF_CMD "${SEARX_SRC}/searx/settings.yml" "${SEARX_SETTINGS_PATH}"
|
||||
wait_key
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
remove_settings() {
|
||||
rst_title "remove searx settings" section
|
||||
echo
|
||||
info_msg "delete ${SEARX_SETTINGS_PATH}"
|
||||
rm -f "${SEARX_SETTINGS_PATH}"
|
||||
}
|
||||
|
||||
remove_searx() {
|
||||
rst_title "Drop searx sources" section
|
||||
if ask_yn "Do you really want to drop searx sources ($SEARX_SRC)?"; then
|
||||
rm -rf "$SEARX_SRC"
|
||||
else
|
||||
rst_para "Leave searx sources unchanged."
|
||||
fi
|
||||
}
|
||||
|
||||
pyenv_is_available() {
|
||||
[[ -f "${SEARX_PYENV}/bin/activate" ]]
|
||||
}
|
||||
|
||||
create_pyenv() {
|
||||
rst_title "Create virtualenv (python)" section
|
||||
echo
|
||||
if [[ ! -f "${SEARX_SRC}/manage.sh" ]]; then
|
||||
err_msg "to create pyenv for searx, searx has to be cloned first"
|
||||
return 42
|
||||
fi
|
||||
info_msg "create pyenv in ${SEARX_PYENV}"
|
||||
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
rm -rf "${SEARX_PYENV}"
|
||||
python3 -m venv "${SEARX_PYENV}"
|
||||
grep -qFs -- 'source ${SEARX_PYENV}/bin/activate' ~/.profile \
|
||||
|| echo 'source ${SEARX_PYENV}/bin/activate' >> ~/.profile
|
||||
EOF
|
||||
info_msg "inspect python's virtual environment"
|
||||
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
command -v python && python --version
|
||||
EOF
|
||||
wait_key
|
||||
info_msg "install needed python packages"
|
||||
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
pip install -U pip
|
||||
pip install -U setuptools
|
||||
pip install -U wheel
|
||||
pip install -U -e .
|
||||
cd ${SEARX_SRC}
|
||||
pip install -e .
|
||||
EOF
|
||||
}
|
||||
|
||||
remove_pyenv() {
|
||||
rst_title "Remove virtualenv (python)" section
|
||||
if ! ask_yn "Do you really want to drop ${SEARX_PYENV} ?"; then
|
||||
return
|
||||
fi
|
||||
info_msg "remove pyenv activation from ~/.profile"
|
||||
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
grep -v 'source ${SEARX_PYENV}/bin/activate' ~/.profile > ~/.profile.##
|
||||
mv ~/.profile.## ~/.profile
|
||||
EOF
|
||||
rm -rf "${SEARX_PYENV}"
|
||||
}
|
||||
|
||||
configure_searx() {
|
||||
rst_title "Configure searx" section
|
||||
rst_para "Setup searx config located at $SEARX_SETTINGS_PATH"
|
||||
echo
|
||||
tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
sed -i -e "s/ultrasecretkey/$(openssl rand -hex 16)/g" "$SEARX_SETTINGS_PATH"
|
||||
sed -i -e "s/{instance_name}/${SEARX_INSTANCE_NAME}/g" "$SEARX_SETTINGS_PATH"
|
||||
EOF
|
||||
}
|
||||
|
||||
test_local_searx() {
|
||||
rst_title "Testing searx instance localy" section
|
||||
echo
|
||||
|
||||
if service_is_available "http://${SEARX_INTERNAL_HTTP}" &>/dev/null; then
|
||||
err_msg "URL/port http://${SEARX_INTERNAL_HTTP} is already in use, you"
|
||||
err_msg "should stop that service before starting local tests!"
|
||||
if ! ask_yn "Continue with local tests?"; then
|
||||
return
|
||||
fi
|
||||
fi
|
||||
sed -i -e "s/debug : False/debug : True/g" "$SEARX_SETTINGS_PATH"
|
||||
tee_stderr 0.1 <<EOF | sudo -H -u "${SERVICE_USER}" -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
export SEARX_SETTINGS_PATH="${SEARX_SETTINGS_PATH}"
|
||||
cd ${SEARX_SRC}
|
||||
timeout 10 python searx/webapp.py &
|
||||
sleep 3
|
||||
curl --location --verbose --head --insecure $SEARX_INTERNAL_HTTP
|
||||
EOF
|
||||
sed -i -e "s/debug : True/debug : False/g" "$SEARX_SETTINGS_PATH"
|
||||
}
|
||||
|
||||
install_searx_uwsgi() {
|
||||
rst_title "Install searx's uWSGI app (searx.ini)" section
|
||||
echo
|
||||
install_uwsgi
|
||||
uWSGI_install_app "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
remove_searx_uwsgi() {
|
||||
rst_title "Remove searx's uWSGI app (searx.ini)" section
|
||||
echo
|
||||
uWSGI_remove_app "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
activate_service() {
|
||||
rst_title "Activate $SEARX_INSTANCE_NAME (service)" section
|
||||
echo
|
||||
uWSGI_enable_app "$SEARX_UWSGI_APP"
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
deactivate_service() {
|
||||
rst_title "De-Activate $SEARX_INSTANCE_NAME (service)" section
|
||||
echo
|
||||
uWSGI_disable_app "$SEARX_UWSGI_APP"
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
enable_image_proxy() {
|
||||
info_msg "try to enable image_proxy ..."
|
||||
tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
sed -i -e "s/image_proxy : False/image_proxy : True/g" "$SEARX_SETTINGS_PATH"
|
||||
EOF
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
disable_image_proxy() {
|
||||
info_msg "try to enable image_proxy ..."
|
||||
tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
sed -i -e "s/image_proxy : True/image_proxy : False/g" "$SEARX_SETTINGS_PATH"
|
||||
EOF
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
enable_debug() {
|
||||
warn_msg "Do not enable debug in production enviroments!!"
|
||||
info_msg "try to enable debug mode ..."
|
||||
tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
sed -i -e "s/debug : False/debug : True/g" "$SEARX_SETTINGS_PATH"
|
||||
EOF
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
disable_debug() {
|
||||
info_msg "try to disable debug mode ..."
|
||||
tee_stderr 0.1 <<EOF | sudo -H -i 2>&1 | prefix_stdout "$_service_prefix"
|
||||
cd ${SEARX_SRC}
|
||||
sed -i -e "s/debug : True/debug : False/g" "$SEARX_SETTINGS_PATH"
|
||||
EOF
|
||||
uWSGI_restart "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
set_result_proxy() {
|
||||
|
||||
# usage: set_result_proxy <URL> [<key>]
|
||||
|
||||
info_msg "try to set result proxy: '$1' ($2)"
|
||||
cp "${SEARX_SETTINGS_PATH}" "${SEARX_SETTINGS_PATH}.bak"
|
||||
_set_result_proxy "$1" "$2" > "${SEARX_SETTINGS_PATH}"
|
||||
}
|
||||
|
||||
_set_result_proxy() {
|
||||
local line
|
||||
local stage=0
|
||||
local url=" url: $1"
|
||||
local key=" key: !!binary \"$2\""
|
||||
if [[ -z $2 ]]; then
|
||||
key=
|
||||
fi
|
||||
|
||||
while IFS= read -r line
|
||||
do
|
||||
if [[ $stage = 0 ]] || [[ $stage = 2 ]] ; then
|
||||
if [[ $line =~ ^[[:space:]]*#*[[:space:]]*result_proxy[[:space:]]*:[[:space:]]*$ ]]; then
|
||||
if [[ $stage = 0 ]]; then
|
||||
stage=1
|
||||
echo "result_proxy:"
|
||||
continue
|
||||
elif [[ $stage = 2 ]]; then
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
if [[ $stage = 1 ]] || [[ $stage = 2 ]] ; then
|
||||
if [[ $line =~ ^[[:space:]]*#*[[:space:]]*url[[:space:]]*:[[:space:]] ]]; then
|
||||
[[ $stage = 1 ]] && echo "$url"
|
||||
continue
|
||||
elif [[ $line =~ ^[[:space:]]*#*[[:space:]]*key[[:space:]]*:[[:space:]] ]]; then
|
||||
[[ $stage = 1 ]] && [[ -n $key ]] && echo "$key"
|
||||
continue
|
||||
elif [[ $line =~ ^[[:space:]]*$ ]]; then
|
||||
stage=2
|
||||
fi
|
||||
fi
|
||||
echo "$line"
|
||||
done < "${SEARX_SETTINGS_PATH}.bak"
|
||||
}
|
||||
|
||||
function has_substring() {
|
||||
[[ "$1" != "${2/$1/}" ]]
|
||||
}
|
||||
inspect_service() {
|
||||
rst_title "service status & log"
|
||||
cat <<EOF
|
||||
|
||||
sourced ${DOT_CONFIG#"$REPO_ROOT/"} :
|
||||
|
||||
PUBLIC_URL : ${PUBLIC_URL}
|
||||
SEARX_URL_PATH : ${SEARX_URL_PATH}
|
||||
SEARX_INSTANCE_NAME : ${SEARX_INSTANCE_NAME}
|
||||
SEARX_INTERNAL_HTTP : ${SEARX_INTERNAL_HTTP}
|
||||
|
||||
EOF
|
||||
|
||||
if service_account_is_available "$SERVICE_USER"; then
|
||||
info_msg "Service account $SERVICE_USER exists."
|
||||
else
|
||||
err_msg "Service account $SERVICE_USER does not exists!"
|
||||
fi
|
||||
|
||||
if pyenv_is_available; then
|
||||
info_msg "~$SERVICE_USER: python environment is available."
|
||||
else
|
||||
err_msg "~$SERVICE_USER: python environment is not available!"
|
||||
fi
|
||||
|
||||
if clone_is_available; then
|
||||
info_msg "~$SERVICE_USER: Searx software is installed."
|
||||
else
|
||||
err_msg "~$SERVICE_USER: Missing searx software!"
|
||||
fi
|
||||
|
||||
if uWSGI_app_enabled "$SEARX_UWSGI_APP"; then
|
||||
info_msg "uWSGI app $SEARX_UWSGI_APP is enabled."
|
||||
else
|
||||
err_msg "uWSGI app $SEARX_UWSGI_APP not enabled!"
|
||||
fi
|
||||
|
||||
uWSGI_app_available "$SEARX_UWSGI_APP" \
|
||||
|| err_msg "uWSGI app $SEARX_UWSGI_APP not available!"
|
||||
|
||||
if in_container; then
|
||||
lxc_suite_info
|
||||
else
|
||||
info_msg "public URL --> ${PUBLIC_URL}"
|
||||
info_msg "internal URL --> http://${SEARX_INTERNAL_HTTP}"
|
||||
fi
|
||||
|
||||
if ! service_is_available "http://${SEARX_INTERNAL_HTTP}"; then
|
||||
err_msg "uWSGI app (service) at http://${SEARX_INTERNAL_HTTP} is not available!"
|
||||
MSG="${_Green}[${_BCyan}CTRL-C${_Green}] to stop or [${_BCyan}KEY${_Green}] to continue"\
|
||||
wait_key
|
||||
fi
|
||||
|
||||
if ! service_is_available "${PUBLIC_URL}"; then
|
||||
warn_msg "Public service at ${PUBLIC_URL} is not available!"
|
||||
if ! in_container; then
|
||||
warn_msg "Check if public name is correct and routed or use the public IP from above."
|
||||
fi
|
||||
fi
|
||||
|
||||
local _debug_on
|
||||
if ask_yn "Enable searx debug mode?"; then
|
||||
enable_debug
|
||||
_debug_on=1
|
||||
fi
|
||||
echo
|
||||
|
||||
case $DIST_ID-$DIST_VERS in
|
||||
ubuntu-*|debian-*)
|
||||
systemctl --no-pager -l status "${SERVICE_NAME}"
|
||||
;;
|
||||
arch-*)
|
||||
systemctl --no-pager -l status "uwsgi@${SERVICE_NAME%.*}"
|
||||
;;
|
||||
fedora-*)
|
||||
systemctl --no-pager -l status uwsgi
|
||||
;;
|
||||
esac
|
||||
|
||||
# shellcheck disable=SC2059
|
||||
printf "// use ${_BCyan}CTRL-C${_creset} to stop monitoring the log"
|
||||
read -r -s -n1 -t 5
|
||||
echo
|
||||
|
||||
while true; do
|
||||
trap break 2
|
||||
case $DIST_ID-$DIST_VERS in
|
||||
ubuntu-*|debian-*) tail -f /var/log/uwsgi/app/searx.log ;;
|
||||
arch-*) journalctl -f -u "uwsgi@${SERVICE_NAME%.*}" ;;
|
||||
fedora-*) journalctl -f -u uwsgi ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ $_debug_on == 1 ]]; then
|
||||
disable_debug
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
install_apache_site() {
|
||||
rst_title "Install Apache site $APACHE_SEARX_SITE"
|
||||
|
||||
rst_para "\
|
||||
This installs the searx uwsgi app as apache site. If your server is public to
|
||||
the internet, you should instead use a reverse proxy (filtron) to block
|
||||
excessively bot queries."
|
||||
|
||||
! apache_is_installed && err_msg "Apache is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
else
|
||||
install_apache
|
||||
fi
|
||||
|
||||
apache_install_site --variant=uwsgi "${APACHE_SEARX_SITE}"
|
||||
|
||||
rst_title "Install searx's uWSGI app (searx.ini)" section
|
||||
echo
|
||||
uWSGI_install_app --variant=socket "$SEARX_UWSGI_APP"
|
||||
|
||||
if ! service_is_available "${PUBLIC_URL}"; then
|
||||
err_msg "Public service at ${PUBLIC_URL} is not available!"
|
||||
fi
|
||||
}
|
||||
|
||||
remove_apache_site() {
|
||||
|
||||
rst_title "Remove Apache site ${APACHE_SEARX_SITE}"
|
||||
|
||||
rst_para "\
|
||||
This removes apache site ${APACHE_SEARX_SITE}."
|
||||
|
||||
! apache_is_installed && err_msg "Apache is not installed."
|
||||
|
||||
if ! ask_yn "Do you really want to continue?" Yn; then
|
||||
return
|
||||
fi
|
||||
|
||||
apache_remove_site "${APACHE_SEARX_SITE}"
|
||||
|
||||
rst_title "Remove searx's uWSGI app (searx.ini)" section
|
||||
echo
|
||||
uWSGI_remove_app "$SEARX_UWSGI_APP"
|
||||
}
|
||||
|
||||
rst-doc() {
|
||||
local debian="${SEARX_PACKAGES_debian}"
|
||||
local arch="${SEARX_PACKAGES_arch}"
|
||||
local fedora="${SEARX_PACKAGES_fedora}"
|
||||
local debian_build="${BUILD_PACKAGES_debian}"
|
||||
local arch_build="${BUILD_PACKAGES_arch}"
|
||||
local fedora_build="${BUILD_PACKAGES_fedora}"
|
||||
debian="$(echo "${debian}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
arch="$(echo "${arch}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
fedora="$(echo "${fedora}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
debian_build="$(echo "${debian_build}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
arch_build="$(echo "${arch_build}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
fedora_build="$(echo "${fedora_build}" | sed 's/.*/ & \\/' | sed '$ s/.$//')"
|
||||
|
||||
eval "echo \"$(< "${REPO_ROOT}/docs/build-templates/searx.rst")\""
|
||||
|
||||
# I use ubuntu-20.04 here to demonstrate that versions are also suported,
|
||||
# normaly debian-* and ubuntu-* are most the same.
|
||||
|
||||
for DIST_NAME in ubuntu-20.04 arch fedora; do
|
||||
(
|
||||
DIST_ID=${DIST_NAME%-*}
|
||||
DIST_VERS=${DIST_NAME#*-}
|
||||
[[ $DIST_VERS =~ $DIST_ID ]] && DIST_VERS=
|
||||
uWSGI_distro_setup
|
||||
|
||||
echo -e "\n.. START searx uwsgi-description $DIST_NAME"
|
||||
|
||||
case $DIST_ID-$DIST_VERS in
|
||||
ubuntu-*|debian-*) cat <<EOF
|
||||
# init.d --> /usr/share/doc/uwsgi/README.Debian.gz
|
||||
# For uWSGI debian uses the LSB init process, this might be changed
|
||||
# one day, see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=833067
|
||||
|
||||
create ${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}
|
||||
enable: sudo -H ln -s ${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP} ${uWSGI_APPS_ENABLED}/
|
||||
start: sudo -H service uwsgi start ${SEARX_UWSGI_APP%.*}
|
||||
restart: sudo -H service uwsgi restart ${SEARX_UWSGI_APP%.*}
|
||||
stop: sudo -H service uwsgi stop ${SEARX_UWSGI_APP%.*}
|
||||
disable: sudo -H rm ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
|
||||
EOF
|
||||
;;
|
||||
arch-*) cat <<EOF
|
||||
# systemd --> /usr/lib/systemd/system/uwsgi@.service
|
||||
# For uWSGI archlinux uses systemd template units, see
|
||||
# - http://0pointer.de/blog/projects/instances.html
|
||||
# - https://uwsgi-docs.readthedocs.io/en/latest/Systemd.html#one-service-per-app-in-systemd
|
||||
|
||||
create: ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
|
||||
enable: sudo -H systemctl enable uwsgi@${SEARX_UWSGI_APP%.*}
|
||||
start: sudo -H systemctl start uwsgi@${SEARX_UWSGI_APP%.*}
|
||||
restart: sudo -H systemctl restart uwsgi@${SEARX_UWSGI_APP%.*}
|
||||
stop: sudo -H systemctl stop uwsgi@${SEARX_UWSGI_APP%.*}
|
||||
disable: sudo -H systemctl disable uwsgi@${SEARX_UWSGI_APP%.*}
|
||||
EOF
|
||||
;;
|
||||
fedora-*) cat <<EOF
|
||||
# systemd --> /usr/lib/systemd/system/uwsgi.service
|
||||
# The unit file starts uWSGI in emperor mode (/etc/uwsgi.ini), see
|
||||
# - https://uwsgi-docs.readthedocs.io/en/latest/Emperor.html
|
||||
|
||||
create: ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
|
||||
restart: sudo -H touch ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
|
||||
disable: sudo -H rm ${uWSGI_APPS_ENABLED}/${SEARX_UWSGI_APP}
|
||||
EOF
|
||||
;;
|
||||
esac
|
||||
echo -e ".. END searx uwsgi-description $DIST_NAME"
|
||||
|
||||
echo -e "\n.. START searx uwsgi-appini $DIST_NAME"
|
||||
eval "echo \"$(< "${TEMPLATES}/${uWSGI_APPS_AVAILABLE}/${SEARX_UWSGI_APP}")\""
|
||||
echo -e "\n.. END searx uwsgi-appini $DIST_NAME"
|
||||
|
||||
)
|
||||
done
|
||||
|
||||
}
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
main "$@"
|
||||
# ----------------------------------------------------------------------------
|
48
utils/site-python/sphinx_build_tools.py
Normal file
48
utils/site-python/sphinx_build_tools.py
Normal file
@ -0,0 +1,48 @@
|
||||
# -*- coding: utf-8; mode: python -*-
|
||||
"""Implement some sphinx-build tools.
|
||||
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from sphinx.util.pycompat import execfile_
|
||||
|
||||
# ------------------------------------------------------------------------------
|
||||
def load_sphinx_config(namespace):
|
||||
# ------------------------------------------------------------------------------
|
||||
|
||||
u"""Load an additional configuration file into *namespace*.
|
||||
|
||||
The name of the configuration file is taken from the environment
|
||||
``SPHINX_CONF``. The external configuration file extends (or overwrites) the
|
||||
configuration values from the origin ``conf.py``. With this you are able to
|
||||
maintain *build themes*. To your docs/conf.py add::
|
||||
|
||||
from sphinx_build_tools import load_sphinx_config
|
||||
...
|
||||
|
||||
# Since loadConfig overwrites settings from the global namespace, it has to be
|
||||
# the last statement in the conf.py file
|
||||
|
||||
load_sphinx_config(globals())
|
||||
|
||||
"""
|
||||
|
||||
config_file = os.environ.get("SPHINX_CONF", None)
|
||||
if (config_file is not None
|
||||
and os.path.normpath(namespace["__file__"]) != os.path.normpath(config_file) ):
|
||||
config_file = os.path.abspath(config_file)
|
||||
|
||||
if os.path.isfile(config_file):
|
||||
sys.stdout.write(
|
||||
"load additional sphinx-config: %s\n"
|
||||
% config_file)
|
||||
config = namespace.copy()
|
||||
config['__file__'] = config_file
|
||||
execfile_(config_file, config)
|
||||
del config['__file__']
|
||||
namespace.update(config)
|
||||
else:
|
||||
sys.stderr.write(
|
||||
"WARNING: additional sphinx-config not found: %s\n"
|
||||
% config_file)
|
1
utils/templates/etc/apache2
Symbolic link
1
utils/templates/etc/apache2
Symbolic link
@ -0,0 +1 @@
|
||||
httpd
|
129
utils/templates/etc/filtron/rules.json
Normal file
129
utils/templates/etc/filtron/rules.json
Normal file
@ -0,0 +1,129 @@
|
||||
[
|
||||
{
|
||||
"name": "roboagent limit",
|
||||
"filters": [
|
||||
"Header:User-Agent=(curl|cURL|Wget|python-requests|Scrapy|FeedFetcher|Go-http-client|Ruby|UniversalFeedParser)"
|
||||
],
|
||||
"limit": 0,
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "botlimit",
|
||||
"filters": [
|
||||
"Header:User-Agent=(Googlebot|bingbot|Baiduspider|yacybot|YandexMobileBot|YandexBot|Yahoo! Slurp|MJ12bot|AhrefsBot|archive.org_bot|msnbot|MJ12bot|SeznamBot|linkdexbot|Netvibes|SMTBot|zgrab|James BOT)"
|
||||
],
|
||||
"limit": 0,
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "suspiciously frequent IP",
|
||||
"filters": [],
|
||||
"interval": 600,
|
||||
"limit": 30,
|
||||
"aggregations": [
|
||||
"Header:X-Forwarded-For"
|
||||
],
|
||||
"actions":[
|
||||
{"name":"log"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "search request",
|
||||
"filters": [
|
||||
"Param:q",
|
||||
"Path=^(/|/search)$"
|
||||
],
|
||||
"interval": 61,
|
||||
"limit": 999,
|
||||
"subrules": [
|
||||
{
|
||||
"name": "missing Accept-Language",
|
||||
"filters": ["!Header:Accept-Language"],
|
||||
"limit": 0,
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{"name":"log"},
|
||||
{"name": "block",
|
||||
"params": {"message": "Rate limit exceeded"}}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "suspiciously Connection=close header",
|
||||
"filters": ["Header:Connection=close"],
|
||||
"limit": 0,
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{"name":"log"},
|
||||
{"name": "block",
|
||||
"params": {"message": "Rate limit exceeded"}}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "IP limit",
|
||||
"interval": 61,
|
||||
"limit": 9,
|
||||
"stop": true,
|
||||
"aggregations": [
|
||||
"Header:X-Forwarded-For"
|
||||
],
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "rss/json limit",
|
||||
"filters": [
|
||||
"Param:format=(csv|json|rss)"
|
||||
],
|
||||
"interval": 121,
|
||||
"limit": 2,
|
||||
"stop": true,
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "useragent limit",
|
||||
"interval": 61,
|
||||
"limit": 199,
|
||||
"aggregations": [
|
||||
"Header:User-Agent"
|
||||
],
|
||||
"actions": [
|
||||
{ "name": "log"},
|
||||
{ "name": "block",
|
||||
"params": {
|
||||
"message": "Rate limit exceeded"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
28
utils/templates/etc/httpd/sites-available/morty.conf
Normal file
28
utils/templates/etc/httpd/sites-available/morty.conf
Normal file
@ -0,0 +1,28 @@
|
||||
# -*- coding: utf-8; mode: apache -*-
|
||||
|
||||
LoadModule headers_module ${APACHE_MODULES}/mod_headers.so
|
||||
LoadModule proxy_module ${APACHE_MODULES}/mod_proxy.so
|
||||
LoadModule proxy_http_module ${APACHE_MODULES}/mod_proxy_http.so
|
||||
#LoadModule setenvif_module ${APACHE_MODULES}/mod_setenvif.so
|
||||
|
||||
# SetEnvIf Request_URI "${PUBLIC_URL_PATH_MORTY}" dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
<Location ${PUBLIC_URL_PATH_MORTY} >
|
||||
|
||||
<IfModule mod_security2.c>
|
||||
SecRuleEngine Off
|
||||
</IfModule>
|
||||
|
||||
Require all granted
|
||||
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
#Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyPass http://${MORTY_LISTEN}
|
||||
RequestHeader set X-Script-Name ${PUBLIC_URL_PATH_MORTY}
|
||||
|
||||
</Location>
|
33
utils/templates/etc/httpd/sites-available/searx.conf:filtron
Normal file
33
utils/templates/etc/httpd/sites-available/searx.conf:filtron
Normal file
@ -0,0 +1,33 @@
|
||||
# -*- coding: utf-8; mode: apache -*-
|
||||
|
||||
LoadModule headers_module ${APACHE_MODULES}/mod_headers.so
|
||||
LoadModule proxy_module ${APACHE_MODULES}/mod_proxy.so
|
||||
LoadModule proxy_http_module ${APACHE_MODULES}/mod_proxy_http.so
|
||||
#LoadModule setenvif_module ${APACHE_MODULES}/mod_setenvif.so
|
||||
|
||||
# SetEnvIf Request_URI "${FILTRON_URL_PATH}" dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
# SecRuleRemoveById 981054
|
||||
# SecRuleRemoveById 981059
|
||||
# SecRuleRemoveById 981060
|
||||
# SecRuleRemoveById 950907
|
||||
|
||||
<Location ${FILTRON_URL_PATH} >
|
||||
|
||||
<IfModule mod_security2.c>
|
||||
SecRuleEngine Off
|
||||
</IfModule>
|
||||
|
||||
Require all granted
|
||||
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
#Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyPass http://${FILTRON_LISTEN}
|
||||
RequestHeader set X-Script-Name ${FILTRON_URL_PATH}
|
||||
|
||||
</Location>
|
27
utils/templates/etc/httpd/sites-available/searx.conf:uwsgi
Normal file
27
utils/templates/etc/httpd/sites-available/searx.conf:uwsgi
Normal file
@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8; mode: apache -*-
|
||||
|
||||
LoadModule headers_module ${APACHE_MODULES}/mod_headers.so
|
||||
LoadModule proxy_module ${APACHE_MODULES}/mod_proxy.so
|
||||
LoadModule proxy_uwsgi_module ${APACHE_MODULES}/mod_proxy_uwsgi.so
|
||||
# LoadModule setenvif_module ${APACHE_MODULES}/mod_setenvif.so
|
||||
|
||||
# SetEnvIf Request_URI "${SEARX_URL_PATH}" dontlog
|
||||
# CustomLog /dev/null combined env=dontlog
|
||||
|
||||
<Location ${SEARX_URL_PATH}>
|
||||
|
||||
<IfModule mod_security2.c>
|
||||
SecRuleEngine Off
|
||||
</IfModule>
|
||||
|
||||
Require all granted
|
||||
|
||||
Order deny,allow
|
||||
Deny from all
|
||||
# Allow from fd00::/8 192.168.0.0/16 fe80::/10 127.0.0.0/8 ::1
|
||||
Allow from all
|
||||
|
||||
ProxyPreserveHost On
|
||||
ProxyPass unix:${SEARX_UWSGI_SOCKET}|uwsgi://uwsgi-uds-searx/
|
||||
|
||||
</Location>
|
11
utils/templates/etc/nginx/default.apps-available/morty.conf
Normal file
11
utils/templates/etc/nginx/default.apps-available/morty.conf
Normal file
@ -0,0 +1,11 @@
|
||||
# https://example.org/morty
|
||||
|
||||
location /morty {
|
||||
proxy_pass http://127.0.0.1:3000/;
|
||||
|
||||
proxy_set_header Host \$http_host;
|
||||
proxy_set_header Connection \$http_connection;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme \$scheme;
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
# https://example.org/searx
|
||||
|
||||
location ${SEARX_URL_PATH} {
|
||||
proxy_pass http://127.0.0.1:4004/;
|
||||
|
||||
proxy_set_header Host \$http_host;
|
||||
proxy_set_header Connection \$http_connection;
|
||||
proxy_set_header X-Real-IP \$remote_addr;
|
||||
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Scheme \$scheme;
|
||||
proxy_set_header X-Script-Name ${SEARX_URL_PATH};
|
||||
}
|
||||
|
||||
location ${SEARX_URL_PATH}/static {
|
||||
alias ${SEARX_SRC}/searx/static;
|
||||
}
|
80
utils/templates/etc/uwsgi/apps-archlinux/searx.ini
Normal file
80
utils/templates/etc/uwsgi/apps-archlinux/searx.ini
Normal file
@ -0,0 +1,80 @@
|
||||
[uwsgi]
|
||||
|
||||
# uWSGI core
|
||||
# ----------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#uwsgi-core
|
||||
|
||||
# Who will run the code
|
||||
uid = ${SERVICE_USER}
|
||||
gid = ${SERVICE_GROUP}
|
||||
|
||||
# chdir to specified directory before apps loading
|
||||
chdir = ${SEARX_SRC}/searx
|
||||
|
||||
# searx configuration (settings.yml)
|
||||
env = SEARX_SETTINGS_PATH=${SEARX_SETTINGS_PATH}
|
||||
|
||||
# disable logging for privacy
|
||||
logger = systemd
|
||||
disable-logging = true
|
||||
|
||||
# The right granted on the created socket
|
||||
chmod-socket = 666
|
||||
|
||||
# Plugin to use and interpretor config
|
||||
single-interpreter = true
|
||||
|
||||
# enable master process
|
||||
master = true
|
||||
|
||||
# load apps in each worker instead of the master
|
||||
lazy-apps = true
|
||||
|
||||
# load uWSGI plugins
|
||||
plugin = python
|
||||
|
||||
# By default the Python plugin does not initialize the GIL. This means your
|
||||
# app-generated threads will not run. If you need threads, remember to enable
|
||||
# them with enable-threads. Running uWSGI in multithreading mode (with the
|
||||
# threads options) will automatically enable threading support. This *strange*
|
||||
# default behaviour is for performance reasons.
|
||||
enable-threads = true
|
||||
|
||||
|
||||
# plugin: python
|
||||
# --------------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-python
|
||||
|
||||
# load a WSGI module
|
||||
module = searx.webapp
|
||||
|
||||
# set PYTHONHOME/virtualenv
|
||||
virtualenv = ${SEARX_PYENV}
|
||||
|
||||
# add directory (or glob) to pythonpath
|
||||
pythonpath = ${SEARX_SRC}
|
||||
|
||||
|
||||
# speak to upstream
|
||||
# -----------------
|
||||
#
|
||||
# Activate the 'http' configuration for filtron or activate the 'socket'
|
||||
# configuration if you setup your HTTP server to use uWSGI protocol via sockets.
|
||||
|
||||
# using IP:
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-http
|
||||
# Native HTTP support: https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html
|
||||
|
||||
http = ${SEARX_INTERNAL_HTTP}
|
||||
|
||||
# using unix-sockets:
|
||||
#
|
||||
# On some distributions you need to create the app folder for the sockets::
|
||||
#
|
||||
# mkdir -p /run/uwsgi/app/searx
|
||||
# chown -R ${SERVICE_USER}:${SERVICE_GROUP} /run/uwsgi/app/searx
|
||||
#
|
||||
# socket = /run/uwsgi/app/searx/socket
|
80
utils/templates/etc/uwsgi/apps-archlinux/searx.ini:socket
Normal file
80
utils/templates/etc/uwsgi/apps-archlinux/searx.ini:socket
Normal file
@ -0,0 +1,80 @@
|
||||
[uwsgi]
|
||||
|
||||
# uWSGI core
|
||||
# ----------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#uwsgi-core
|
||||
|
||||
# Who will run the code
|
||||
uid = ${SERVICE_USER}
|
||||
gid = ${SERVICE_GROUP}
|
||||
|
||||
# chdir to specified directory before apps loading
|
||||
chdir = ${SEARX_SRC}/searx
|
||||
|
||||
# searx configuration (settings.yml)
|
||||
env = SEARX_SETTINGS_PATH=${SEARX_SETTINGS_PATH}
|
||||
|
||||
# disable logging for privacy
|
||||
logger = systemd
|
||||
disable-logging = true
|
||||
|
||||
# The right granted on the created socket
|
||||
chmod-socket = 666
|
||||
|
||||
# Plugin to use and interpretor config
|
||||
single-interpreter = true
|
||||
|
||||
# enable master process
|
||||
master = true
|
||||
|
||||
# load apps in each worker instead of the master
|
||||
lazy-apps = true
|
||||
|
||||
# load uWSGI plugins
|
||||
plugin = python
|
||||
|
||||
# By default the Python plugin does not initialize the GIL. This means your
|
||||
# app-generated threads will not run. If you need threads, remember to enable
|
||||
# them with enable-threads. Running uWSGI in multithreading mode (with the
|
||||
# threads options) will automatically enable threading support. This *strange*
|
||||
# default behaviour is for performance reasons.
|
||||
enable-threads = true
|
||||
|
||||
|
||||
# plugin: python
|
||||
# --------------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-python
|
||||
|
||||
# load a WSGI module
|
||||
module = searx.webapp
|
||||
|
||||
# set PYTHONHOME/virtualenv
|
||||
virtualenv = ${SEARX_PYENV}
|
||||
|
||||
# add directory (or glob) to pythonpath
|
||||
pythonpath = ${SEARX_SRC}
|
||||
|
||||
|
||||
# speak to upstream
|
||||
# -----------------
|
||||
#
|
||||
# Activate the 'http' configuration for filtron or activate the 'socket'
|
||||
# configuration if you setup your HTTP server to use uWSGI protocol via sockets.
|
||||
|
||||
# using IP:
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-http
|
||||
# Native HTTP support: https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html
|
||||
|
||||
# http = ${SEARX_INTERNAL_HTTP}
|
||||
|
||||
# using unix-sockets:
|
||||
#
|
||||
# On some distributions you need to create the app folder for the sockets::
|
||||
#
|
||||
# mkdir -p /run/uwsgi/app/searx
|
||||
# chown -R ${SERVICE_USER}:${SERVICE_GROUP} /run/uwsgi/app/searx
|
||||
#
|
||||
socket = /run/uwsgi/app/searx/socket
|
79
utils/templates/etc/uwsgi/apps-available/searx.ini
Normal file
79
utils/templates/etc/uwsgi/apps-available/searx.ini
Normal file
@ -0,0 +1,79 @@
|
||||
[uwsgi]
|
||||
|
||||
# uWSGI core
|
||||
# ----------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#uwsgi-core
|
||||
|
||||
# Who will run the code
|
||||
uid = ${SERVICE_USER}
|
||||
gid = ${SERVICE_GROUP}
|
||||
|
||||
# chdir to specified directory before apps loading
|
||||
chdir = ${SEARX_SRC}/searx
|
||||
|
||||
# searx configuration (settings.yml)
|
||||
env = SEARX_SETTINGS_PATH=${SEARX_SETTINGS_PATH}
|
||||
|
||||
# disable logging for privacy
|
||||
disable-logging = true
|
||||
|
||||
# The right granted on the created socket
|
||||
chmod-socket = 666
|
||||
|
||||
# Plugin to use and interpretor config
|
||||
single-interpreter = true
|
||||
|
||||
# enable master process
|
||||
master = true
|
||||
|
||||
# load apps in each worker instead of the master
|
||||
lazy-apps = true
|
||||
|
||||
# load uWSGI plugins
|
||||
plugin = python3,http
|
||||
|
||||
# By default the Python plugin does not initialize the GIL. This means your
|
||||
# app-generated threads will not run. If you need threads, remember to enable
|
||||
# them with enable-threads. Running uWSGI in multithreading mode (with the
|
||||
# threads options) will automatically enable threading support. This *strange*
|
||||
# default behaviour is for performance reasons.
|
||||
enable-threads = true
|
||||
|
||||
|
||||
# plugin: python
|
||||
# --------------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-python
|
||||
|
||||
# load a WSGI module
|
||||
module = searx.webapp
|
||||
|
||||
# set PYTHONHOME/virtualenv
|
||||
virtualenv = ${SEARX_PYENV}
|
||||
|
||||
# add directory (or glob) to pythonpath
|
||||
pythonpath = ${SEARX_SRC}
|
||||
|
||||
|
||||
# speak to upstream
|
||||
# -----------------
|
||||
#
|
||||
# Activate the 'http' configuration for filtron or activate the 'socket'
|
||||
# configuration if you setup your HTTP server to use uWSGI protocol via sockets.
|
||||
|
||||
# using IP:
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-http
|
||||
# Native HTTP support: https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html
|
||||
|
||||
http = ${SEARX_INTERNAL_HTTP}
|
||||
|
||||
# using unix-sockets:
|
||||
#
|
||||
# On some distributions you need to create the app folder for the sockets::
|
||||
#
|
||||
# mkdir -p /run/uwsgi/app/searx
|
||||
# chmod -R ${SERVICE_USER}:${SERVICE_GROUP} /run/uwsgi/app/searx
|
||||
#
|
||||
# socket = /run/uwsgi/app/searx/socket
|
79
utils/templates/etc/uwsgi/apps-available/searx.ini:socket
Normal file
79
utils/templates/etc/uwsgi/apps-available/searx.ini:socket
Normal file
@ -0,0 +1,79 @@
|
||||
[uwsgi]
|
||||
|
||||
# uWSGI core
|
||||
# ----------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#uwsgi-core
|
||||
|
||||
# Who will run the code
|
||||
uid = ${SERVICE_USER}
|
||||
gid = ${SERVICE_GROUP}
|
||||
|
||||
# chdir to specified directory before apps loading
|
||||
chdir = ${SEARX_SRC}/searx
|
||||
|
||||
# searx configuration (settings.yml)
|
||||
env = SEARX_SETTINGS_PATH=${SEARX_SETTINGS_PATH}
|
||||
|
||||
# disable logging for privacy
|
||||
disable-logging = true
|
||||
|
||||
# The right granted on the created socket
|
||||
chmod-socket = 666
|
||||
|
||||
# Plugin to use and interpretor config
|
||||
single-interpreter = true
|
||||
|
||||
# enable master process
|
||||
master = true
|
||||
|
||||
# load apps in each worker instead of the master
|
||||
lazy-apps = true
|
||||
|
||||
# load uWSGI plugins
|
||||
plugin = python3,http
|
||||
|
||||
# By default the Python plugin does not initialize the GIL. This means your
|
||||
# app-generated threads will not run. If you need threads, remember to enable
|
||||
# them with enable-threads. Running uWSGI in multithreading mode (with the
|
||||
# threads options) will automatically enable threading support. This *strange*
|
||||
# default behaviour is for performance reasons.
|
||||
enable-threads = true
|
||||
|
||||
|
||||
# plugin: python
|
||||
# --------------
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-python
|
||||
|
||||
# load a WSGI module
|
||||
module = searx.webapp
|
||||
|
||||
# set PYTHONHOME/virtualenv
|
||||
virtualenv = ${SEARX_PYENV}
|
||||
|
||||
# add directory (or glob) to pythonpath
|
||||
pythonpath = ${SEARX_SRC}
|
||||
|
||||
|
||||
# speak to upstream
|
||||
# -----------------
|
||||
#
|
||||
# Activate the 'http' configuration for filtron or activate the 'socket'
|
||||
# configuration if you setup your HTTP server to use uWSGI protocol via sockets.
|
||||
|
||||
# using IP:
|
||||
#
|
||||
# https://uwsgi-docs.readthedocs.io/en/latest/Options.html#plugin-http
|
||||
# Native HTTP support: https://uwsgi-docs.readthedocs.io/en/latest/HTTP.html
|
||||
|
||||
# http = ${SEARX_INTERNAL_HTTP}
|
||||
|
||||
# using unix-sockets:
|
||||
#
|
||||
# On some distributions you need to create the app folder for the sockets::
|
||||
#
|
||||
# mkdir -p /run/uwsgi/app/searx
|
||||
# chown -R ${SERVICE_USER}:${SERVICE_GROUP} /run/uwsgi/app/searx
|
||||
#
|
||||
socket = /run/uwsgi/app/searx/socket
|
29
utils/templates/lib/systemd/system/filtron.service
Normal file
29
utils/templates/lib/systemd/system/filtron.service
Normal file
@ -0,0 +1,29 @@
|
||||
[Unit]
|
||||
|
||||
Description=${SERVICE_NAME}
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
|
||||
Type=simple
|
||||
User=${SERVICE_USER}
|
||||
Group=${SERVICE_GROUP}
|
||||
WorkingDirectory=${SERVICE_HOME}
|
||||
ExecStart=${SERVICE_HOME}/go-apps/bin/filtron -api '${FILTRON_API}' -listen '${FILTRON_LISTEN}' -rules '${FILTRON_RULES}' -target '${FILTRON_TARGET}'
|
||||
|
||||
Restart=always
|
||||
Environment=USER=${SERVICE_USER} HOME=${SERVICE_HOME}
|
||||
|
||||
# Some distributions may not support these hardening directives. If you cannot
|
||||
# start the service due to an unknown option, comment out the ones not supported
|
||||
# by your version of systemd.
|
||||
|
||||
ProtectSystem=full
|
||||
PrivateDevices=yes
|
||||
PrivateTmp=yes
|
||||
NoNewPrivileges=true
|
||||
|
||||
[Install]
|
||||
|
||||
WantedBy=multi-user.target
|
29
utils/templates/lib/systemd/system/morty.service
Normal file
29
utils/templates/lib/systemd/system/morty.service
Normal file
@ -0,0 +1,29 @@
|
||||
[Unit]
|
||||
|
||||
Description=${SERVICE_NAME}
|
||||
After=syslog.target
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
|
||||
Type=simple
|
||||
User=${SERVICE_USER}
|
||||
Group=${SERVICE_GROUP}
|
||||
WorkingDirectory=${SERVICE_HOME}
|
||||
ExecStart=${SERVICE_HOME}/go-apps/bin/morty -key '${MORTY_KEY}' -listen '${MORTY_LISTEN}' -timeout ${MORTY_TIMEOUT}
|
||||
|
||||
Restart=always
|
||||
Environment=USER=${SERVICE_USER} HOME=${SERVICE_HOME} DEBUG=${SERVICE_ENV_DEBUG}
|
||||
|
||||
# Some distributions may not support these hardening directives. If you cannot
|
||||
# start the service due to an unknown option, comment out the ones not supported
|
||||
# by your version of systemd.
|
||||
|
||||
ProtectSystem=full
|
||||
PrivateDevices=yes
|
||||
PrivateTmp=yes
|
||||
NoNewPrivileges=true
|
||||
|
||||
[Install]
|
||||
|
||||
WantedBy=multi-user.target
|
Loading…
Reference in New Issue
Block a user