mirror of https://github.com/searxng/searxng.git
Merge branch 'master' into duckduckgo_correction
This commit is contained in:
commit
93cbd85b8a
|
@ -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,6 +1,7 @@
|
||||||
# to sync with .dockerignore
|
# to sync with .dockerignore
|
||||||
.coverage
|
.coverage
|
||||||
coverage/
|
coverage/
|
||||||
|
cache/
|
||||||
.installed.cfg
|
.installed.cfg
|
||||||
engines.cfg
|
engines.cfg
|
||||||
env
|
env
|
||||||
|
|
65
Makefile
65
Makefile
|
@ -1,24 +1,31 @@
|
||||||
# -*- coding: utf-8; mode: makefile-gmake -*-
|
# -*- coding: utf-8; mode: makefile-gmake -*-
|
||||||
|
.DEFAULT_GOAL=help
|
||||||
|
|
||||||
|
# START Makefile setup
|
||||||
export GIT_URL=https://github.com/asciimoo/searx
|
export GIT_URL=https://github.com/asciimoo/searx
|
||||||
|
export GIT_BRANCH=master
|
||||||
export SEARX_URL=https://searx.me
|
export SEARX_URL=https://searx.me
|
||||||
export DOCS_URL=https://asciimoo.github.io/searx
|
export DOCS_URL=https://asciimoo.github.io/searx
|
||||||
|
# END Makefile setup
|
||||||
|
|
||||||
|
include utils/makefile.include
|
||||||
|
|
||||||
PYOBJECTS = searx
|
PYOBJECTS = searx
|
||||||
DOC = docs
|
DOC = docs
|
||||||
PY_SETUP_EXTRAS ?= \[test\]
|
PY_SETUP_EXTRAS ?= \[test\]
|
||||||
|
|
||||||
PYDIST=./dist/py
|
|
||||||
PYBUILD=./build/py
|
|
||||||
|
|
||||||
include utils/makefile.include
|
|
||||||
include utils/makefile.python
|
include utils/makefile.python
|
||||||
include utils/makefile.sphinx
|
include utils/makefile.sphinx
|
||||||
|
|
||||||
all: clean install
|
all: clean install
|
||||||
|
|
||||||
PHONY += help
|
PHONY += help-min help-all help
|
||||||
help:
|
|
||||||
|
help: help-min
|
||||||
|
@echo ''
|
||||||
|
@echo 'to get more help: make help-all'
|
||||||
|
|
||||||
|
help-min:
|
||||||
@echo ' test - run developer tests'
|
@echo ' test - run developer tests'
|
||||||
@echo ' docs - build documentation'
|
@echo ' docs - build documentation'
|
||||||
@echo ' docs-live - autobuild HTML documentation while editing'
|
@echo ' docs-live - autobuild HTML documentation while editing'
|
||||||
|
@ -33,9 +40,18 @@ help:
|
||||||
@echo ' docker - build Docker image'
|
@echo ' docker - build Docker image'
|
||||||
@echo ' node.env - download & install npm dependencies locally'
|
@echo ' node.env - download & install npm dependencies locally'
|
||||||
@echo ''
|
@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 ''
|
@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
|
PHONY += install
|
||||||
install: buildenv pyenvinstall
|
install: buildenv pyenvinstall
|
||||||
|
@ -44,7 +60,7 @@ PHONY += uninstall
|
||||||
uninstall: pyenvuninstall
|
uninstall: pyenvuninstall
|
||||||
|
|
||||||
PHONY += clean
|
PHONY += clean
|
||||||
clean: pyclean node.clean test.clean
|
clean: pyclean docs-clean node.clean test.clean
|
||||||
$(call cmd,common_clean)
|
$(call cmd,common_clean)
|
||||||
|
|
||||||
PHONY += run
|
PHONY += run
|
||||||
|
@ -61,14 +77,24 @@ run: buildenv pyenvinstall
|
||||||
# docs
|
# docs
|
||||||
# ----
|
# ----
|
||||||
|
|
||||||
|
sphinx-doc-prebuilds:: buildenv pyenvinstall prebuild-includes
|
||||||
|
|
||||||
PHONY += docs
|
PHONY += docs
|
||||||
docs: buildenv pyenvinstall sphinx-doc
|
docs: sphinx-doc-prebuilds sphinx-doc
|
||||||
$(call cmd,sphinx,html,docs,docs)
|
$(call cmd,sphinx,html,docs,docs)
|
||||||
|
|
||||||
PHONY += docs-live
|
PHONY += docs-live
|
||||||
docs-live: buildenv pyenvinstall sphinx-live
|
docs-live: sphinx-doc-prebuilds sphinx-live
|
||||||
$(call cmd,sphinx_autobuild,html,docs,docs)
|
$(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)::
|
$(GH_PAGES)::
|
||||||
@echo "doc available at --> $(DOCS_URL)"
|
@echo "doc available at --> $(DOCS_URL)"
|
||||||
|
|
||||||
|
@ -94,12 +120,14 @@ useragents.update: pyenvinstall
|
||||||
buildenv:
|
buildenv:
|
||||||
$(Q)echo "build searx/brand.py"
|
$(Q)echo "build searx/brand.py"
|
||||||
$(Q)echo "GIT_URL = '$(GIT_URL)'" > 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 "ISSUE_URL = 'https://github.com/asciimoo/searx/issues'" >> searx/brand.py
|
||||||
$(Q)echo "SEARX_URL = '$(SEARX_URL)'" >> searx/brand.py
|
$(Q)echo "SEARX_URL = '$(SEARX_URL)'" >> searx/brand.py
|
||||||
$(Q)echo "DOCS_URL = '$(DOCS_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 "PUBLIC_INSTANCES = 'https://searx.space'" >> searx/brand.py
|
||||||
$(Q)echo "build utils/brand.env"
|
$(Q)echo "build utils/brand.env"
|
||||||
$(Q)echo "export GIT_URL='$(GIT_URL)'" > 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 ISSUE_URL='https://github.com/asciimoo/searx/issues'" >> utils/brand.env
|
||||||
$(Q)echo "export SEARX_URL='$(SEARX_URL)'" >> utils/brand.env
|
$(Q)echo "export SEARX_URL='$(SEARX_URL)'" >> utils/brand.env
|
||||||
$(Q)echo "export DOCS_URL='$(DOCS_URL)'" >> utils/brand.env
|
$(Q)echo "export DOCS_URL='$(DOCS_URL)'" >> utils/brand.env
|
||||||
|
@ -182,8 +210,7 @@ gecko.driver:
|
||||||
# test
|
# 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
|
test: buildenv test.pylint test.pep8 test.unit gecko.driver test.robot
|
||||||
|
|
||||||
ifeq ($(PY),2)
|
ifeq ($(PY),2)
|
||||||
|
@ -191,6 +218,7 @@ test.pylint:
|
||||||
@echo "LINT skip liniting py2"
|
@echo "LINT skip liniting py2"
|
||||||
else
|
else
|
||||||
# TODO: balance linting with pylint
|
# TODO: balance linting with pylint
|
||||||
|
|
||||||
test.pylint: pyenvinstall
|
test.pylint: pyenvinstall
|
||||||
$(call cmd,pylint,\
|
$(call cmd,pylint,\
|
||||||
searx/preferences.py \
|
searx/preferences.py \
|
||||||
|
@ -202,6 +230,17 @@ endif
|
||||||
# E402 module level import not at top of file
|
# E402 module level import not at top of file
|
||||||
# W503 line break before binary operator
|
# 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
|
test.pep8: pyenvinstall
|
||||||
@echo "TEST pep8"
|
@echo "TEST pep8"
|
||||||
$(Q)$(PY_ENV_ACT); pep8 --exclude=searx/static --max-line-length=120 --ignore "E402,W503" searx tests
|
$(Q)$(PY_ENV_ACT); pep8 --exclude=searx/static --max-line-length=120 --ignore "E402,W503" searx tests
|
||||||
|
|
|
@ -33,7 +33,7 @@ p.sidebar-title, .sidebar p {
|
||||||
/* admonitions
|
/* admonitions
|
||||||
*/
|
*/
|
||||||
|
|
||||||
div.admonition, div.topic {
|
div.admonition, div.topic, div.toctree-wrapper {
|
||||||
background-color: #fafafa;
|
background-color: #fafafa;
|
||||||
margin: 8px 0px;
|
margin: 8px 0px;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
|
@ -42,6 +42,16 @@ div.admonition, div.topic {
|
||||||
border-right: none;
|
border-right: none;
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
border-left: 5pt solid #ccc;
|
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 {
|
p.admonition-title:after {
|
||||||
|
@ -128,3 +138,32 @@ caption {
|
||||||
caption-side: top;
|
caption-side: top;
|
||||||
text-align: left;
|
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"];
|
edge [fontname="Sans"];
|
||||||
|
|
||||||
browser [label="Browser", shape=Mdiamond];
|
browser [label="Browser", shape=Mdiamond];
|
||||||
rp [label="Reverse Proxy", href="url to configure reverse proxy"];
|
rp [label="Reverse Proxy", href="https://asciimoo.github.io/searx/utils/filtron.sh.html#public-reverse-proxy"];
|
||||||
filtron [label="Filtron", href="https://github.com/asciimoo/filtron"];
|
filtron [label="Filtron", href="https://asciimoo.github.io/searx/utils/filtron.sh.html"];
|
||||||
morty [label="Morty", href="https://github.com/asciimoo/morty"];
|
morty [label="Morty", href="https://asciimoo.github.io/searx/utils/morty.sh.html"];
|
||||||
static [label="Static files", href="url to configure static files"];
|
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"];
|
searx1 [label="Searx #1"];
|
||||||
searx2 [label="Searx #2"];
|
searx2 [label="Searx #2"];
|
||||||
searx3 [label="Searx #3"];
|
searx3 [label="Searx #3"];
|
||||||
|
|
|
@ -4,17 +4,21 @@
|
||||||
Architecture
|
Architecture
|
||||||
============
|
============
|
||||||
|
|
||||||
.. sidebar:: Needs work!
|
.. sidebar:: Further reading
|
||||||
|
|
||||||
This article needs some work / Searx is a collaborative effort. If you have
|
- Reverse Proxy: :ref:`Apache <apache searx site>` & :ref:`nginx <nginx searx
|
||||||
any contribution, feel welcome to send us your :pull:`PR <../pulls>`, see
|
site>`
|
||||||
:ref:`how to contribute`.
|
- 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
|
Herein you will find some hints and suggestions about typical architectures of
|
||||||
searx infrastructures.
|
searx infrastructures.
|
||||||
|
|
||||||
We start with a contribution from :pull:`@dalf <1776#issuecomment-567917320>`.
|
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:
|
.. _arch public:
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,27 @@ Buildhosts
|
||||||
If you have any contribution send us your :pull:`PR <../pulls>`, see
|
If you have any contribution send us your :pull:`PR <../pulls>`, see
|
||||||
:ref:`how to contribute`.
|
:ref:`how to contribute`.
|
||||||
|
|
||||||
|
.. contents:: Contents
|
||||||
|
:depth: 2
|
||||||
|
:local:
|
||||||
|
:backlinks: entry
|
||||||
|
|
||||||
To get best results from build, its recommend to install additional packages
|
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:
|
.. _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.
|
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
|
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
|
as images (``sphinx.ext.imgmath`` extension).
|
||||||
docs``) shows warnings like this::
|
|
||||||
|
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 \
|
WARNING: dot(1) not found, for better output quality install \
|
||||||
graphviz from http://www.graphviz.org
|
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
|
you need to install additional packages on your build host, to get better HTML
|
||||||
output.
|
output.
|
||||||
|
|
||||||
.. _system requirements:
|
|
||||||
|
|
||||||
.. tabs::
|
.. tabs::
|
||||||
|
|
||||||
.. group-tab:: Ubuntu / debian
|
.. group-tab:: Ubuntu / debian
|
||||||
|
@ -92,12 +118,38 @@ For PDF output you also need:
|
||||||
|
|
||||||
$ sudo dnf install \
|
$ sudo dnf install \
|
||||||
texlive-collection-fontsrecommended texlive-collection-latex \
|
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
|
Lint shell scripts
|
||||||
:language: python
|
==================
|
||||||
:start-after: # sphinx.ext.imgmath setup
|
|
||||||
:end-before: # sphinx.ext.imgmath setup END
|
|
||||||
|
|
||||||
|
.. _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
|
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.
|
it is advised to limit the number of requests processed by searx.
|
||||||
|
|
||||||
An application firewall, ``filtron`` solves exactly this problem. Information
|
An application firewall, filtron_ solves exactly this problem. Filtron is just
|
||||||
on how to install it can be found at the `project page of filtron
|
a middleware between your web server (nginx, apache, ...) and searx, we describe
|
||||||
<https://github.com/asciimoo/filtron>`__.
|
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
|
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
|
An example configuration can be find below. This configuration limits the access
|
||||||
of:
|
of:
|
||||||
|
|
||||||
|
@ -24,58 +57,49 @@ of:
|
||||||
|
|
||||||
.. code:: json
|
.. code:: json
|
||||||
|
|
||||||
[{
|
[
|
||||||
|
{
|
||||||
"name": "search request",
|
"name": "search request",
|
||||||
"filters": [
|
"filters": [
|
||||||
"Param:q",
|
"Param:q",
|
||||||
"Path=^(/|/search)$"
|
"Path=^(/|/search)$"
|
||||||
],
|
],
|
||||||
"interval":"<time-interval-in-sec (int)>",
|
"interval": "<time-interval-in-sec (int)>"
|
||||||
"limit": "<max-request-number-in-interval (int)>",
|
"limit": "<max-request-number-in-interval (int)>",
|
||||||
"subrules": [
|
"subrules": [
|
||||||
{
|
{
|
||||||
"name":"roboagent limit",
|
"name": "missing Accept-Language",
|
||||||
"interval":"<time-interval-in-sec (int)>",
|
"filters": ["!Header:Accept-Language"],
|
||||||
"limit": "<max-request-number-in-interval (int)>",
|
"limit": "<max-request-number-in-interval (int)>",
|
||||||
"filters":[
|
"stop": true,
|
||||||
"Header:User-Agent=(curl|cURL|Wget|python-requests|Scrapy|FeedFetcher|Go-http-client)"
|
|
||||||
],
|
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{"name":"log"},
|
||||||
"name":"block",
|
{"name": "block",
|
||||||
"params":{
|
"params": {"message": "Rate limit exceeded"}}
|
||||||
"message":"Rate limit exceeded"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name":"botlimit",
|
"name": "suspiciously Connection=close header",
|
||||||
"limit":0,
|
"filters": ["Header:Connection=close"],
|
||||||
|
"limit": "<max-request-number-in-interval (int)>",
|
||||||
"stop": true,
|
"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": [
|
"actions": [
|
||||||
{
|
{"name":"log"},
|
||||||
"name":"block",
|
{"name": "block",
|
||||||
"params":{
|
"params": {"message": "Rate limit exceeded"}}
|
||||||
"message":"Rate limit exceeded"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "IP limit",
|
"name": "IP limit",
|
||||||
"interval":"<time-interval-in-sec (int)>",
|
"interval": "<time-interval-in-sec (int)>"
|
||||||
"limit": "<max-request-number-in-interval (int)>",
|
"limit": "<max-request-number-in-interval (int)>",
|
||||||
"stop": true,
|
"stop": true,
|
||||||
"aggregations": [
|
"aggregations": [
|
||||||
"Header:X-Forwarded-For"
|
"Header:X-Forwarded-For"
|
||||||
],
|
],
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{ "name": "log"},
|
||||||
"name":"block",
|
{ "name": "block",
|
||||||
"params": {
|
"params": {
|
||||||
"message": "Rate limit exceeded"
|
"message": "Rate limit exceeded"
|
||||||
}
|
}
|
||||||
|
@ -84,15 +108,15 @@ of:
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "rss/json limit",
|
"name": "rss/json limit",
|
||||||
"interval":"<time-interval-in-sec (int)>",
|
|
||||||
"limit":"<max-request-number-in-interval (int)>",
|
|
||||||
"stop":true,
|
|
||||||
"filters": [
|
"filters": [
|
||||||
"Param:format=(csv|json|rss)"
|
"Param:format=(csv|json|rss)"
|
||||||
],
|
],
|
||||||
|
"interval": "<time-interval-in-sec (int)>"
|
||||||
|
"limit": "<max-request-number-in-interval (int)>",
|
||||||
|
"stop": true,
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{ "name": "log"},
|
||||||
"name":"block",
|
{ "name": "block",
|
||||||
"params": {
|
"params": {
|
||||||
"message": "Rate limit exceeded"
|
"message": "Rate limit exceeded"
|
||||||
}
|
}
|
||||||
|
@ -101,14 +125,14 @@ of:
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "useragent limit",
|
"name": "useragent limit",
|
||||||
"interval":"<time-interval-in-sec (int)>",
|
"interval": "<time-interval-in-sec (int)>"
|
||||||
"limit": "<max-request-number-in-interval (int)>",
|
"limit": "<max-request-number-in-interval (int)>",
|
||||||
"aggregations": [
|
"aggregations": [
|
||||||
"Header:User-Agent"
|
"Header:User-Agent"
|
||||||
],
|
],
|
||||||
"actions": [
|
"actions": [
|
||||||
{
|
{ "name": "log"},
|
||||||
"name":"block",
|
{ "name": "block",
|
||||||
"params": {
|
"params": {
|
||||||
"message": "Rate limit exceeded"
|
"message": "Rate limit exceeded"
|
||||||
}
|
}
|
||||||
|
@ -116,13 +140,21 @@ of:
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}]
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
.. _filtron route request:
|
||||||
|
|
||||||
Route request through filtron
|
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:
|
Filtron can be started using the following command:
|
||||||
|
|
||||||
.. code:: sh
|
.. code:: sh
|
||||||
|
@ -136,13 +168,24 @@ Use it along with ``nginx`` with the following example configuration.
|
||||||
|
|
||||||
.. code:: nginx
|
.. code:: nginx
|
||||||
|
|
||||||
location / {
|
# https://example.org/searx
|
||||||
|
|
||||||
|
location /searx {
|
||||||
|
proxy_pass http://127.0.0.1:4004/;
|
||||||
|
|
||||||
proxy_set_header Host $http_host;
|
proxy_set_header Host $http_host;
|
||||||
|
proxy_set_header Connection $http_connection;
|
||||||
proxy_set_header X-Real-IP $remote_addr;
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
proxy_set_header X-Scheme $scheme;
|
proxy_set_header X-Scheme $scheme;
|
||||||
proxy_pass http://127.0.0.1:4004/;
|
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
|
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::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 2
|
||||||
|
:caption: Contents
|
||||||
|
|
||||||
installation
|
installation
|
||||||
|
installation-searx
|
||||||
|
installation-uwsgi
|
||||||
|
installation-nginx
|
||||||
|
installation-apache
|
||||||
|
installation-docker
|
||||||
|
update-searx
|
||||||
settings
|
settings
|
||||||
api
|
api
|
||||||
architecture
|
architecture
|
||||||
|
|
|
@ -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
|
|
@ -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 .
|
|
@ -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;
|
||||||
|
# ...
|
||||||
|
}
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
Installation
|
||||||
============
|
============
|
||||||
|
|
||||||
.. contents::
|
*You're spoilt for choice*, choose your preferred method of installation.
|
||||||
:depth: 3
|
|
||||||
|
|
||||||
Basic installation
|
- :ref:`installation docker`
|
||||||
==================
|
- :ref:`installation scripts`
|
||||||
|
- :ref:`installation basic`
|
||||||
|
|
||||||
Step by step installation for Debian/Ubuntu with virtualenv. For Ubuntu, be sure
|
The :ref:`installation basic` is good enough for intranet usage and it is a
|
||||||
to have enable universe repository.
|
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 \
|
Installation scripts
|
||||||
git build-essential libxslt-dev \
|
====================
|
||||||
python-dev python-virtualenv python-babel \
|
|
||||||
zlib1g-dev libffi-dev libssl-dev
|
|
||||||
|
|
||||||
Install searx:
|
.. sidebar:: Update OS first!
|
||||||
|
|
||||||
.. code:: sh
|
To avoid unwanted side effects, update your OS before installing searx.
|
||||||
|
|
||||||
cd /usr/local
|
The following will install a setup as shown in :ref:`architecture`. First you
|
||||||
sudo -H git clone https://github.com/asciimoo/searx.git
|
need to get a clone. The clone is only needed for the installation procedure
|
||||||
sudo -H useradd searx -d /usr/local/searx
|
and some maintenance tasks (alternatively you can create your own fork).
|
||||||
sudo -H chown searx:searx -R /usr/local/searx
|
|
||||||
|
|
||||||
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
|
**Install** :ref:`searx service <searx.sh>`
|
||||||
sudo -H -u searx -i
|
|
||||||
|
|
||||||
.. code:: sh
|
This installs searx as described in :ref:`installation basic`.
|
||||||
|
|
||||||
(searx)$ virtualenv searx-ve
|
.. code:: bash
|
||||||
(searx)$ . ./searx-ve/bin/activate
|
|
||||||
(searx)$ ./manage.sh update_packages
|
|
||||||
|
|
||||||
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
|
How to setup result proxy
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
|
.. sidebar:: further reading
|
||||||
|
|
||||||
|
- :ref:`morty.sh`
|
||||||
|
|
||||||
.. _morty: https://github.com/asciimoo/morty
|
.. _morty: https://github.com/asciimoo/morty
|
||||||
.. _morty's README: https://github.com/asciimoo/morty
|
.. _morty's README: https://github.com/asciimoo/morty
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,17 @@
|
||||||
``settings.yml``
|
``settings.yml``
|
||||||
================
|
================
|
||||||
|
|
||||||
|
This page describe the options possibilities of the :origin:`searx/settings.yml`
|
||||||
|
file.
|
||||||
|
|
||||||
.. sidebar:: Further reading ..
|
.. sidebar:: Further reading ..
|
||||||
|
|
||||||
- :ref:`search API`
|
- :ref:`search API`
|
||||||
|
|
||||||
This page describe the options possibilities of the settings.yml file.
|
.. contents:: Contents
|
||||||
|
:depth: 2
|
||||||
|
:local:
|
||||||
|
:backlinks: entry
|
||||||
|
|
||||||
.. _settings global:
|
.. _settings global:
|
||||||
|
|
||||||
|
|
|
@ -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::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 2
|
||||||
|
:caption: Contents
|
||||||
|
|
||||||
python3
|
python3
|
||||||
admin
|
admin
|
||||||
|
|
|
@ -13,7 +13,7 @@ Private engines
|
||||||
To solve this issue private engines were introduced in :pull:`1823`.
|
To solve this issue private engines were introduced in :pull:`1823`.
|
||||||
A new option was added to engines named `tokens`. It expects a list
|
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 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.
|
and make search requests.
|
||||||
|
|
||||||
Example configuration to restrict access to the Arch Linux Wiki engine:
|
Example configuration to restrict access to the Arch Linux Wiki engine:
|
||||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import sys, os
|
import sys, os
|
||||||
|
from sphinx_build_tools import load_sphinx_config
|
||||||
from searx.version import VERSION_STRING
|
from searx.version import VERSION_STRING
|
||||||
from pallets_sphinx_themes import ProjectLink
|
from pallets_sphinx_themes import ProjectLink
|
||||||
|
|
||||||
from searx.brand import GIT_URL
|
from searx.brand import GIT_URL
|
||||||
|
GIT_BRANCH = os.environ.get("GIT_BRANCH", "master")
|
||||||
from searx.brand import SEARX_URL
|
from searx.brand import SEARX_URL
|
||||||
from searx.brand import DOCS_URL
|
from searx.brand import DOCS_URL
|
||||||
|
|
||||||
|
@ -22,6 +24,8 @@ master_doc = "index"
|
||||||
source_suffix = '.rst'
|
source_suffix = '.rst'
|
||||||
numfig = True
|
numfig = True
|
||||||
|
|
||||||
|
exclude_patterns = ['build-templates/*.rst']
|
||||||
|
|
||||||
from searx import webapp
|
from searx import webapp
|
||||||
jinja_contexts = {
|
jinja_contexts = {
|
||||||
'webapp': dict(**webapp.__dict__)
|
'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 ')
|
extlinks['pull'] = ('https://github.com/asciimoo/searx/pull/%s', 'PR ')
|
||||||
|
|
||||||
# links to custom brand
|
# 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['patch'] = (GIT_URL + '/commit/%s', '#')
|
||||||
extlinks['search'] = (SEARX_URL + '/%s', '#')
|
extlinks['search'] = (SEARX_URL + '/%s', '#')
|
||||||
extlinks['docs'] = (DOCS_URL + '/%s', 'docs: ')
|
extlinks['docs'] = (DOCS_URL + '/%s', 'docs: ')
|
||||||
|
@ -61,6 +65,8 @@ extensions = [
|
||||||
"pallets_sphinx_themes",
|
"pallets_sphinx_themes",
|
||||||
"sphinx_issues", # https://github.com/sloria/sphinx-issues/blob/master/README.rst
|
"sphinx_issues", # https://github.com/sloria/sphinx-issues/blob/master/README.rst
|
||||||
"sphinxcontrib.jinja", # https://github.com/tardyp/sphinx-jinja
|
"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.rstFlatTable', # Implementation of the 'flat-table' reST-directive.
|
||||||
'linuxdoc.kfigure', # Sphinx extension which implements scalable image handling.
|
'linuxdoc.kfigure', # Sphinx extension which implements scalable image handling.
|
||||||
"sphinx_tabs.tabs", # https://github.com/djungelorm/sphinx-tabs
|
"sphinx_tabs.tabs", # https://github.com/djungelorm/sphinx-tabs
|
||||||
|
@ -112,3 +118,9 @@ html_show_sourcelink = False
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
(master_doc, "searx-{}.tex".format(VERSION_STRING), html_title, author, "manual")
|
(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
|
How to contribute
|
||||||
=================
|
=================
|
||||||
|
|
||||||
|
.. contents:: Contents
|
||||||
|
:depth: 2
|
||||||
|
:local:
|
||||||
|
:backlinks: entry
|
||||||
|
|
||||||
Prime directives: Privacy, Hackability
|
Prime directives: Privacy, Hackability
|
||||||
======================================
|
======================================
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@ Developer documentation
|
||||||
=======================
|
=======================
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 2
|
||||||
|
:caption: Contents
|
||||||
|
|
||||||
quickstart
|
quickstart
|
||||||
contribution_guide
|
contribution_guide
|
||||||
|
|
|
@ -11,23 +11,17 @@ Makefile Targets
|
||||||
Before looking deeper at the targets, first read about :ref:`makefile setup`
|
Before looking deeper at the targets, first read about :ref:`makefile setup`
|
||||||
and :ref:`make pyenv`.
|
and :ref:`make pyenv`.
|
||||||
|
|
||||||
|
To install system requirements follow :ref:`buildhosts`.
|
||||||
|
|
||||||
With the aim to simplify development cycles, started with :pull:`1756` a
|
With the aim to simplify development cycles, started with :pull:`1756` a
|
||||||
``Makefile`` based boilerplate was added. If you are not familiar with
|
``Makefile`` based boilerplate was added. If you are not familiar with
|
||||||
Makefiles, we recommend to read gnu-make_ introduction.
|
Makefiles, we recommend to read gnu-make_ introduction.
|
||||||
|
|
||||||
The usage is simple, just type ``make {target-name}`` to *build* a target.
|
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
|
.. contents:: Contents
|
||||||
:depth: 2
|
:depth: 2
|
||||||
|
@ -37,27 +31,33 @@ Calling the ``help`` target gives a first overview::
|
||||||
|
|
||||||
.. _makefile setup:
|
.. _makefile setup:
|
||||||
|
|
||||||
Setup
|
Makefile setup
|
||||||
=====
|
==============
|
||||||
|
|
||||||
.. _git stash: https://git-scm.com/docs/git-stash
|
.. _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
|
.. sidebar:: fork & upstream
|
||||||
|
|
||||||
Commit changes in your (local) branch, fork or whatever, but do not push them
|
Commit changes in your (local) branch, fork or whatever, but do not push them
|
||||||
upstream / `git stash`_ is your friend.
|
upstream / `git stash`_ is your friend.
|
||||||
|
|
||||||
|
The main setup is done in the :origin:`Makefile`.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../Makefile
|
||||||
|
:start-after: START Makefile setup
|
||||||
|
:end-before: END Makefile setup
|
||||||
|
|
||||||
:GIT_URL: Changes this, to point to your searx fork.
|
: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.
|
:SEARX_URL: Changes this, to point to your searx instance.
|
||||||
|
:DOCS_URL: If you host your own (*brand*) documentation, change this URL.
|
||||||
|
|
||||||
:DOCS_URL: If you host your own (branded) 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:
|
.. _make pyenv:
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ e.g.:
|
||||||
|
|
||||||
.. code:: sh
|
.. code:: sh
|
||||||
|
|
||||||
$ make test.pep8 test.unit
|
$ make test.pep8 test.unit test.sh
|
||||||
. ./local/py3/bin/activate; ./manage.sh pep8_check
|
. ./local/py3/bin/activate; ./manage.sh pep8_check
|
||||||
[!] Running pep8 check
|
[!] Running pep8 check
|
||||||
. ./local/py3/bin/activate; ./manage.sh unit_tests
|
. ./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
|
cd ~/myprojects
|
||||||
git clone https://github.com/asciimoo/searx.git
|
git clone https://github.com/asciimoo/searx.git
|
||||||
cd searx
|
cd searx
|
||||||
virtualenv searx-ve
|
python3 -m venv searx-ve
|
||||||
. ./searx-ve/bin/activate
|
. ./searx-ve/bin/activate
|
||||||
./manage.sh update_dev_packages
|
./manage.sh update_dev_packages
|
||||||
|
|
||||||
|
|
|
@ -325,8 +325,9 @@ Literal blocks
|
||||||
|
|
||||||
The simplest form of :duref:`literal-blocks` is a indented block introduced by
|
The simplest form of :duref:`literal-blocks` is a indented block introduced by
|
||||||
two colons (``::``). For highlighting use :dudir:`highlight` or :ref:`reST
|
two colons (``::``). For highlighting use :dudir:`highlight` or :ref:`reST
|
||||||
code` directive. To include literals from external files use directive
|
code` directive. To include literals from external files use
|
||||||
:dudir:`literalinclude`.
|
:rst:dir:`literalinclude` or :ref:`kernel-include <kernel-include-directive>`
|
||||||
|
directive (latter one expands environment variables in the path name).
|
||||||
|
|
||||||
.. _reST literal:
|
.. _reST literal:
|
||||||
|
|
||||||
|
@ -1312,9 +1313,8 @@ others are basic-tabs_ and code-tabs_. Below a *group-tab* example from
|
||||||
|
|
||||||
.. literalinclude:: ../admin/buildhosts.rst
|
.. literalinclude:: ../admin/buildhosts.rst
|
||||||
:language: reST
|
:language: reST
|
||||||
:start-after: .. _system requirements:
|
:start-after: .. SNIP sh lint requirements
|
||||||
:end-before: .. _system requirements END:
|
:end-before: .. SNAP sh lint requirements
|
||||||
|
|
||||||
|
|
||||||
.. _math:
|
.. _math:
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@ Parameters
|
||||||
Theme of instance.
|
Theme of instance.
|
||||||
|
|
||||||
Please note, available themes depend on an instance. It is possible that an
|
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.
|
See the available options in the preferences page of the instance.
|
||||||
|
|
||||||
``oscar-style`` : default ``logicodev``
|
``oscar-style`` : default ``logicodev``
|
||||||
|
@ -91,7 +91,7 @@ Parameters
|
||||||
``oscar``.
|
``oscar``.
|
||||||
|
|
||||||
Please note, available styles depend on an instance. It is possible that an
|
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.
|
instance. See the available options in the preferences page of the instance.
|
||||||
|
|
||||||
``enabled_plugins`` : optional
|
``enabled_plugins`` : optional
|
||||||
|
|
|
@ -2,7 +2,14 @@
|
||||||
Welcome to searx
|
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
|
.. sidebar:: Features
|
||||||
|
|
||||||
|
@ -16,19 +23,14 @@ Search without being tracked.
|
||||||
- Hosted by organizations, such as *La Quadrature du Net*, which promote
|
- Hosted by organizations, such as *La Quadrature du Net*, which promote
|
||||||
digital rights
|
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::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
:caption: Contents
|
||||||
|
|
||||||
user/index
|
user/index
|
||||||
admin/index
|
admin/index
|
||||||
dev/index
|
dev/index
|
||||||
|
utils/index
|
||||||
blog/index
|
blog/index
|
||||||
|
|
||||||
.. _Searx-instances: https://searx.space
|
.. _Searx-instances: https://searx.space
|
||||||
|
|
|
@ -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::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 2
|
||||||
|
:caption: Contents
|
||||||
|
|
||||||
search_syntax
|
search_syntax
|
||||||
own-instance
|
own-instance
|
||||||
|
|
|
@ -2,8 +2,10 @@
|
||||||
Why use a private instance?
|
Why use a private instance?
|
||||||
===========================
|
===========================
|
||||||
|
|
||||||
"Is it worth to run my own instance?" is a common question among searx users.
|
*"Is it worth to run my own instance?"*
|
||||||
Before answering this question, see what options a searx user has.
|
|
||||||
|
\.\. 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
|
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
|
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?
|
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
|
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
|
Also, public instances without proper protection are more vulnerable to abusing
|
||||||
the search service, In this case the external service in exchange returns
|
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/>`__
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
linuxdoc @ git+http://github.com/return42/linuxdoc.git
|
||||||
sphinx-jinja
|
sphinx-jinja
|
||||||
sphinx-tabs
|
sphinx-tabs
|
||||||
|
sphinxcontrib-programoutput
|
||||||
|
twine
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
GIT_URL = 'https://github.com/asciimoo/searx'
|
GIT_URL = 'https://github.com/asciimoo/searx'
|
||||||
|
GIT_BRANCH = 'master'
|
||||||
ISSUE_URL = 'https://github.com/asciimoo/searx/issues'
|
ISSUE_URL = 'https://github.com/asciimoo/searx/issues'
|
||||||
SEARX_URL = 'https://searx.me'
|
SEARX_URL = 'https://searx.me'
|
||||||
DOCS_URL = 'https://asciimoo.github.io/searx'
|
DOCS_URL = 'https://asciimoo.github.io/searx'
|
||||||
|
|
|
@ -117,14 +117,10 @@ def response(resp):
|
||||||
'img_format': img_format,
|
'img_format': img_format,
|
||||||
'template': 'images.html'
|
'template': 'images.html'
|
||||||
}
|
}
|
||||||
try:
|
result['author'] = author.encode('utf-8', 'ignore').decode('utf-8')
|
||||||
result['author'] = author
|
result['source'] = source.encode('utf-8', 'ignore').decode('utf-8')
|
||||||
result['title'] = title
|
result['title'] = title.encode('utf-8', 'ignore').decode('utf-8')
|
||||||
result['content'] = content
|
result['content'] = content.encode('utf-8', 'ignore').decode('utf-8')
|
||||||
except:
|
|
||||||
result['author'] = ''
|
|
||||||
result['title'] = ''
|
|
||||||
result['content'] = ''
|
|
||||||
results.append(result)
|
results.append(result)
|
||||||
|
|
||||||
return results
|
return results
|
||||||
|
|
|
@ -33,7 +33,7 @@ supported_languages_url = 'https://search.yahoo.com/web/advanced'
|
||||||
results_xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' Sr ')]"
|
results_xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' Sr ')]"
|
||||||
url_xpath = './/h3/a/@href'
|
url_xpath = './/h3/a/@href'
|
||||||
title_xpath = './/h3/a'
|
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"
|
suggestion_xpath = "//div[contains(concat(' ', normalize-space(@class), ' '), ' AlsoTry ')]//a"
|
||||||
|
|
||||||
time_range_dict = {'day': ['1d', 'd'],
|
time_range_dict = {'day': ['1d', 'd'],
|
||||||
|
|
|
@ -6,19 +6,37 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
$(document.getElementById($(this).attr("for"))).prop('checked', true);
|
$(document.getElementById($(this).attr("for"))).prop('checked', true);
|
||||||
if($('#q').val()) {
|
if($('#q').val()) {
|
||||||
|
if (getHttpRequest() == "GET") {
|
||||||
|
$('#search_form').attr('action', $('#search_form').serialize());
|
||||||
|
}
|
||||||
$('#search_form').submit();
|
$('#search_form').submit();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
$('#time-range').change(function(e) {
|
$('#time-range').change(function(e) {
|
||||||
if($('#q').val()) {
|
if($('#q').val()) {
|
||||||
|
if (getHttpRequest() == "GET") {
|
||||||
|
$('#search_form').attr('action', $('#search_form').serialize());
|
||||||
|
}
|
||||||
$('#search_form').submit();
|
$('#search_form').submit();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('#language').change(function(e) {
|
$('#language').change(function(e) {
|
||||||
if($('#q').val()) {
|
if($('#q').val()) {
|
||||||
|
if (getHttpRequest() == "GET") {
|
||||||
|
$('#search_form').attr('action', $('#search_form').serialize());
|
||||||
|
}
|
||||||
$('#search_form').submit();
|
$('#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;
|
-ms-user-select: none;
|
||||||
}
|
}
|
||||||
.onoffswitch-checkbox {
|
.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 {
|
.onoffswitch-label {
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -104,7 +118,7 @@ input[type=checkbox]:not(:checked) + .label_hide_if_checked + .label_hide_if_not
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
border: 2px solid #FFFFFF !important;
|
border: 2px solid #FFFFFF;
|
||||||
border-radius: 50px !important;
|
border-radius: 50px !important;
|
||||||
transition: all 0.3s ease-in 0s;
|
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;
|
right: 71px;
|
||||||
background-color: #A1A1A1;
|
background-color: #A1A1A1;
|
||||||
}
|
}
|
||||||
|
.onoffswitch-checkbox:focus + .onoffswitch-label .onoffswitch-switch {
|
||||||
|
border: 3px solid #444444;
|
||||||
|
}
|
||||||
.result_header {
|
.result_header {
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
|
@ -377,6 +394,17 @@ Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb
|
||||||
.search-margin {
|
.search-margin {
|
||||||
margin-bottom: 0.6em;
|
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 {
|
#advanced-search-container {
|
||||||
display: none;
|
display: none;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
@ -407,8 +435,8 @@ Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
border-bottom: #01d7d4 5px solid;
|
border-bottom: #01d7d4 5px solid;
|
||||||
}
|
}
|
||||||
#check-advanced {
|
#check-advanced:focus + label {
|
||||||
display: none;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
#check-advanced:checked ~ #advanced-search-container {
|
#check-advanced:checked ~ #advanced-search-container {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -43,7 +43,21 @@ input[type=checkbox]:not(:checked) + .label_hide_if_checked + .label_hide_if_not
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
}
|
}
|
||||||
.onoffswitch-checkbox {
|
.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 {
|
.onoffswitch-label {
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -77,7 +91,7 @@ input[type=checkbox]:not(:checked) + .label_hide_if_checked + .label_hide_if_not
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
border: 2px solid #FFFFFF !important;
|
border: 2px solid #FFFFFF;
|
||||||
border-radius: 50px !important;
|
border-radius: 50px !important;
|
||||||
transition: all 0.3s ease-in 0s;
|
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;
|
right: 71px;
|
||||||
background-color: #A1A1A1;
|
background-color: #A1A1A1;
|
||||||
}
|
}
|
||||||
|
.onoffswitch-checkbox:focus + .onoffswitch-label .onoffswitch-switch {
|
||||||
|
border: 3px solid #444444;
|
||||||
|
}
|
||||||
.result_header {
|
.result_header {
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
|
@ -350,6 +367,17 @@ Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb
|
||||||
.search-margin {
|
.search-margin {
|
||||||
margin-bottom: 0.6em;
|
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 {
|
#advanced-search-container {
|
||||||
display: none;
|
display: none;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
@ -380,8 +408,8 @@ Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
border-bottom: #01d7d4 5px solid;
|
border-bottom: #01d7d4 5px solid;
|
||||||
}
|
}
|
||||||
#check-advanced {
|
#check-advanced:focus + label {
|
||||||
display: none;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
#check-advanced:checked ~ #advanced-search-container {
|
#check-advanced:checked ~ #advanced-search-container {
|
||||||
display: block;
|
display: block;
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -291,7 +291,7 @@ $(document).ready(function(){
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.fail(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>");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -90,7 +90,7 @@ $(document).ready(function(){
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.fail(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 {
|
#check-advanced:focus + label {
|
||||||
display: none;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
#check-advanced:checked ~ #advanced-search-container {
|
#check-advanced:checked ~ #advanced-search-container {
|
||||||
|
|
|
@ -9,7 +9,21 @@
|
||||||
-ms-user-select: none;
|
-ms-user-select: none;
|
||||||
}
|
}
|
||||||
.onoffswitch-checkbox {
|
.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 {
|
.onoffswitch-label {
|
||||||
display: block;
|
display: block;
|
||||||
|
@ -44,7 +58,7 @@
|
||||||
top: 0;
|
top: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
border: 2px solid #FFFFFF !important;
|
border: 2px solid #FFFFFF;
|
||||||
border-radius: 50px !important;
|
border-radius: 50px !important;
|
||||||
transition: all 0.3s ease-in 0s;
|
transition: all 0.3s ease-in 0s;
|
||||||
}
|
}
|
||||||
|
@ -55,3 +69,6 @@
|
||||||
right: 71px;
|
right: 71px;
|
||||||
background-color: #A1A1A1;
|
background-color: #A1A1A1;
|
||||||
}
|
}
|
||||||
|
.onoffswitch-checkbox:focus + .onoffswitch-label .onoffswitch-switch {
|
||||||
|
border: 3px solid #444444;
|
||||||
|
}
|
||||||
|
|
|
@ -78,3 +78,13 @@ Ny0yNFQxMToxNTowMCswMjowMP7RDgQAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb
|
||||||
.search-margin {
|
.search-margin {
|
||||||
margin-bottom: 0.6em;
|
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 */
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/*! simple/searx.min.js | 06-08-2019 | https://github.com/asciimoo/searx */
|
/*! simple/searx.min.js | 15-06-2020 | */
|
||||||
|
|
||||||
(function(t,e){"use strict";var a=e.currentScript||function(){var t=e.getElementsByTagName("script");return t[t.length-1]}();t.searx={touch:"ontouchstart"in t||t.DocumentTouch&&document instanceof DocumentTouch||false,method:a.getAttribute("data-method"),autocompleter:a.getAttribute("data-autocompleter")==="true",search_on_category_select:a.getAttribute("data-search-on-category-select")==="true",infinite_scroll:a.getAttribute("data-infinite-scroll")==="true",static_path:a.getAttribute("data-static-path"),no_item_found:a.getAttribute("data-no-item-found")};e.getElementsByTagName("html")[0].className=t.searx.touch?"js touch":"js"})(window,document);
|
(function(t,e){"use strict";var a=e.currentScript||function(){var t=e.getElementsByTagName("script");return t[t.length-1]}();t.searx={touch:"ontouchstart"in t||t.DocumentTouch&&document instanceof DocumentTouch||false,method:a.getAttribute("data-method"),autocompleter:a.getAttribute("data-autocompleter")==="true",search_on_category_select:a.getAttribute("data-search-on-category-select")==="true",infinite_scroll:a.getAttribute("data-infinite-scroll")==="true",static_path:a.getAttribute("data-static-path"),no_item_found:a.getAttribute("data-no-item-found")};e.getElementsByTagName("html")[0].className=t.searx.touch?"js touch":"js"})(window,document);
|
||||||
//# sourceMappingURL=searx.head.min.js.map
|
//# sourceMappingURL=searx.head.min.js.map
|
|
@ -1314,7 +1314,7 @@ module.exports = AutoComplete;
|
||||||
})
|
})
|
||||||
.catch(function() {
|
.catch(function() {
|
||||||
result_table_loadicon.classList.remove('invisible');
|
result_table_loadicon.classList.remove('invisible');
|
||||||
result_table_loadicon.innerHTML = "could not load data!";
|
result_table_loadicon.innerHTML = could_not_load;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -97,7 +97,7 @@
|
||||||
})
|
})
|
||||||
.catch(function() {
|
.catch(function() {
|
||||||
result_table_loadicon.classList.remove('invisible');
|
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>
|
<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>
|
<ul>
|
||||||
<a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a>
|
<li><a href="https://support.mozilla.org/en-US/kb/add-or-remove-search-engine-firefox">Firefox</a></li>
|
||||||
searx as a search engine on any version of Firefox! (javascript required)
|
<li><a href="https://support.microsoft.com/en-us/help/4028574/microsoft-edge-change-the-default-search-engine" >Microsoft Egde</a></li>
|
||||||
</dd>
|
<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>
|
<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>
|
<Image>{{ urljoin(host, url_for('static', filename='img/favicon.png')) }}</Image>
|
||||||
<LongName>searx metasearch</LongName>
|
<LongName>searx metasearch</LongName>
|
||||||
{% if opensearch_method == 'get' %}
|
{% if opensearch_method == 'get' %}
|
||||||
<Url type="text/html" method="get" template="{{ host }}search?q={searchTerms}"/>
|
<Url rel="results" 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 %}
|
|
||||||
{% else %}
|
{% 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}" />
|
<Param name="q" value="{searchTerms}" />
|
||||||
</Url>
|
</Url>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% if autocomplete %}
|
||||||
|
<Url rel="suggestions" type="application/json" template="{{ host }}autocompleter"/>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</OpenSearchDescription>
|
</OpenSearchDescription>
|
||||||
|
|
|
@ -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">{{- "" -}}
|
<label for="check-advanced">{{- "" -}}
|
||||||
<span class="glyphicon glyphicon-cog"></span>
|
<span class="glyphicon glyphicon-cog"></span>
|
||||||
{{- _('Advanced settings') -}}
|
{{- _('Advanced settings') -}}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{% from 'oscar/macros.html' import icon %}
|
{% from 'oscar/macros.html' import icon %}
|
||||||
<!DOCTYPE html>
|
<!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>
|
<head>
|
||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<meta name="description" content="searx - a privacy-respecting, hackable metasearch engine" />
|
<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 http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="generator" content="searx/{{ searx_version }}">
|
<meta name="generator" content="searx/{{ searx_version }}">
|
||||||
<meta name="referrer" content="no-referrer">
|
<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 %}
|
{% block meta %}{% endblock %}
|
||||||
|
<script src="{{ url_for('js_translations') }}"></script>
|
||||||
<title>{% block title %}{% endblock %}{{ instance_name }}</title>
|
<title>{% block title %}{% endblock %}{{ instance_name }}</title>
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}" type="text/css" />
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/bootstrap.min.css') }}" type="text/css" />
|
||||||
{% if preferences.get_value('oscar-style') -%}
|
{% if preferences.get_value('oscar-style') -%}
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
{% if cookies['oscar-style'] == 'pointhi' %}
|
{% 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>
|
<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 %}
|
{% 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" />
|
<img class="center-block img-responsive" src="{{ url_for('static', filename='img/logo_searx_a.png') }}" alt="searx logo" />
|
||||||
searx
|
searx
|
||||||
</h1>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
{% for u in infobox.urls %}{% if u.official %} <a href="{{ u.url }}">{{ u.domain }}</a>{% endif %}{% endfor %}
|
{% for u in infobox.urls %}{% if u.official %} <a href="{{ u.url }}">{{ u.domain }}</a>{% endif %}{% endfor %}
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<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 %}
|
{% 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">
|
<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>
|
<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) -%}
|
{%- for lang_id,lang_name,country_name,english_name in language_codes | sort(attribute=1) -%}
|
||||||
|
|
|
@ -60,15 +60,15 @@
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
{% macro preferences_item_header(info, label, rtl) -%}
|
{% macro preferences_item_header(info, label, rtl, id) -%}
|
||||||
{% if rtl %}
|
{% if rtl %}
|
||||||
<div class="row form-group">
|
<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>
|
<span class="col-sm-5 col-md-6 help-block pull-left">{{ info }}</span>
|
||||||
<div class="col-sm-4 col-md-4">
|
<div class="col-sm-4 col-md-4">
|
||||||
{% else %}
|
{% else %}
|
||||||
<div class="row form-group">
|
<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">
|
<div class="col-sm-4 col-md-4">
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
@ -91,6 +91,7 @@
|
||||||
<span class="onoffswitch-inner"></span>
|
<span class="onoffswitch-inner"></span>
|
||||||
<span class="onoffswitch-switch"></span>
|
<span class="onoffswitch-switch"></span>
|
||||||
</label>
|
</label>
|
||||||
|
<label class="visually-hidden" for="{{ id }}">{{ _('Allow') }}</label>
|
||||||
</div>
|
</div>
|
||||||
{%- endmacro %}
|
{%- endmacro %}
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
<div class="col-sm-11 col-md-10">
|
<div class="col-sm-11 col-md-10">
|
||||||
{% include 'oscar/categories.html' %}
|
{% include 'oscar/categories.html' %}
|
||||||
</div>
|
</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 %}
|
{% 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">
|
<div class="col-sm-11 col-md-10 search-categories">
|
||||||
{% include 'oscar/categories.html' %}
|
{% include 'oscar/categories.html' %}
|
||||||
</div>
|
</div>
|
||||||
|
@ -40,14 +40,14 @@
|
||||||
</div>
|
</div>
|
||||||
{% set language_label = _('Search language') %}
|
{% set language_label = _('Search language') %}
|
||||||
{% set language_info = _('What language do you prefer for search?') %}
|
{% 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' %}
|
{% include 'oscar/languages.html' %}
|
||||||
{{ preferences_item_footer(language_info, language_label, rtl) }}
|
{{ preferences_item_footer(language_info, language_label, rtl) }}
|
||||||
|
|
||||||
{% set locale_label = _('Interface language') %}
|
{% set locale_label = _('Interface language') %}
|
||||||
{% set locale_info = _('Change the language of the layout') %}
|
{% set locale_info = _('Change the language of the layout') %}
|
||||||
{{ preferences_item_header(locale_info, locale_label, rtl) }}
|
{{ preferences_item_header(locale_info, locale_label, rtl, 'locale') }}
|
||||||
<select class="form-control" name='locale'>
|
<select class="form-control" name="locale" id="locale">
|
||||||
{% for locale_id,locale_name in locales.items() | sort %}
|
{% for locale_id,locale_name in locales.items() | sort %}
|
||||||
<option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option>
|
<option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -56,8 +56,8 @@
|
||||||
|
|
||||||
{% set autocomplete_label = _('Autocomplete') %}
|
{% set autocomplete_label = _('Autocomplete') %}
|
||||||
{% set autocomplete_info = _('Find stuff as you type') %}
|
{% set autocomplete_info = _('Find stuff as you type') %}
|
||||||
{{ preferences_item_header(autocomplete_info, autocomplete_label, rtl) }}
|
{{ preferences_item_header(autocomplete_info, autocomplete_label, rtl, 'autocomplete') }}
|
||||||
<select class="form-control" name="autocomplete">
|
<select class="form-control" name="autocomplete" id="autocomplete">
|
||||||
<option value=""> - </option>
|
<option value=""> - </option>
|
||||||
{% for backend in autocomplete_backends %}
|
{% for backend in autocomplete_backends %}
|
||||||
<option value="{{ backend }}" {% if backend == autocomplete %}selected="selected"{% endif %}>{{ backend }}</option>
|
<option value="{{ backend }}" {% if backend == autocomplete %}selected="selected"{% endif %}>{{ backend }}</option>
|
||||||
|
@ -67,8 +67,8 @@
|
||||||
|
|
||||||
{% set image_proxy_label = _('Image proxy') %}
|
{% set image_proxy_label = _('Image proxy') %}
|
||||||
{% set image_proxy_info = _('Proxying image results through searx') %}
|
{% set image_proxy_info = _('Proxying image results through searx') %}
|
||||||
{{ preferences_item_header(image_proxy_info, image_proxy_label, rtl) }}
|
{{ preferences_item_header(image_proxy_info, image_proxy_label, rtl, 'image_proxy') }}
|
||||||
<select class="form-control" name='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="1" {% if image_proxy %}selected="selected"{% endif %}>{{ _('Enabled') }}</option>
|
||||||
<option value="" {% if not image_proxy %}selected="selected"{% endif %}>{{ _('Disabled')}}</option>
|
<option value="" {% if not image_proxy %}selected="selected"{% endif %}>{{ _('Disabled')}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -76,8 +76,8 @@
|
||||||
|
|
||||||
{% set method_label = _('Method') %}
|
{% 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>') %}
|
{% 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) }}
|
{{ preferences_item_header(method_info, method_label, rtl, 'method') }}
|
||||||
<select class="form-control" name='method'>
|
<select class="form-control" name="method" id="method">
|
||||||
<option value="POST" {% if method == 'POST' %}selected="selected"{% endif %}>POST</option>
|
<option value="POST" {% if method == 'POST' %}selected="selected"{% endif %}>POST</option>
|
||||||
<option value="GET" {% if method == 'GET' %}selected="selected"{% endif %}>GET</option>
|
<option value="GET" {% if method == 'GET' %}selected="selected"{% endif %}>GET</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -85,8 +85,8 @@
|
||||||
|
|
||||||
{% set safesearch_label = _('SafeSearch') %}
|
{% set safesearch_label = _('SafeSearch') %}
|
||||||
{% set safesearch_info = _('Filter content') %}
|
{% set safesearch_info = _('Filter content') %}
|
||||||
{{ preferences_item_header(safesearch_info, safesearch_label, rtl) }}
|
{{ preferences_item_header(safesearch_info, safesearch_label, rtl, 'safesearch') }}
|
||||||
<select class="form-control" name='safesearch'>
|
<select class="form-control" name="safesearch" id="safesearch">
|
||||||
<option value="2" {% if safesearch == '2' %}selected="selected"{% endif %}>{{ _('Strict') }}</option>
|
<option value="2" {% if safesearch == '2' %}selected="selected"{% endif %}>{{ _('Strict') }}</option>
|
||||||
<option value="1" {% if safesearch == '1' %}selected="selected"{% endif %}>{{ _('Moderate') }}</option>
|
<option value="1" {% if safesearch == '1' %}selected="selected"{% endif %}>{{ _('Moderate') }}</option>
|
||||||
<option value="0" {% if safesearch == '0' %}selected="selected"{% endif %}>{{ _('None') }}</option>
|
<option value="0" {% if safesearch == '0' %}selected="selected"{% endif %}>{{ _('None') }}</option>
|
||||||
|
@ -95,16 +95,16 @@
|
||||||
|
|
||||||
{% set theme_label = _('Themes') %}
|
{% set theme_label = _('Themes') %}
|
||||||
{% set theme_info = _('Change searx layout') %}
|
{% set theme_info = _('Change searx layout') %}
|
||||||
{{ preferences_item_header(theme_info, theme_label, rtl) }}
|
{{ preferences_item_header(theme_info, theme_label, rtl, 'theme') }}
|
||||||
<select class="form-control" name="theme">
|
<select class="form-control" name="theme" id="theme">
|
||||||
{% for name in themes %}
|
{% for name in themes %}
|
||||||
<option value="{{ name }}" {% if name == theme %}selected="selected"{% endif %}>{{ name }}</option>
|
<option value="{{ name }}" {% if name == theme %}selected="selected"{% endif %}>{{ name }}</option>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</select>
|
</select>
|
||||||
{{ preferences_item_footer(theme_info, theme_label, rtl) }}
|
{{ preferences_item_footer(theme_info, theme_label, rtl) }}
|
||||||
|
|
||||||
{{ preferences_item_header(_('Choose style for this theme'), _('Style'), rtl) }}
|
{{ preferences_item_header(_('Choose style for this theme'), _('Style'), rtl, 'oscar_style') }}
|
||||||
<select class="form-control" name='oscar-style'>
|
<select class="form-control" name="oscar-style" id="oscar_style">
|
||||||
<option value="logicodev" >Logicodev</option>
|
<option value="logicodev" >Logicodev</option>
|
||||||
<option value="pointhi" {% if preferences.get_value('oscar-style') == 'pointhi' %}selected="selected"{% endif %}>Pointhi</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>
|
<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 label = _('Results on new tabs') %}
|
||||||
{% set info = _('Open result links on new browser tabs') %}
|
{% set info = _('Open result links on new browser tabs') %}
|
||||||
{{ preferences_item_header(info, label, rtl) }}
|
{{ preferences_item_header(info, label, rtl, 'results_on_new_tab') }}
|
||||||
<select class="form-control" name='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="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>
|
<option value="0" {% if not results_on_new_tab %}selected="selected"{% endif %}>{{ _('Off')}}</option>
|
||||||
</select>
|
</select>
|
||||||
|
@ -122,8 +122,8 @@
|
||||||
|
|
||||||
{% set label = _('Open Access DOI resolver') %}
|
{% set label = _('Open Access DOI resolver') %}
|
||||||
{% set info = _('Redirect to open-access versions of publications when available (plugin required)') %}
|
{% set info = _('Redirect to open-access versions of publications when available (plugin required)') %}
|
||||||
{{ preferences_item_header(info, label, rtl) }}
|
{{ preferences_item_header(info, label, rtl, 'doi_resolver') }}
|
||||||
<select class="form-control" id='doi_resolver' name='doi_resolver'>
|
<select class="form-control" name="doi_resolver" id="doi_resolver">
|
||||||
{% for doi_resolver_name,doi_resolver_url in doi_resolvers.items() %}
|
{% 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 %}>
|
<option value="{{ doi_resolver_name }}" {% if doi_resolver_name == current_doi_resolver %}selected="selected"{% endif %}>
|
||||||
{{ doi_resolver_name }} - {{ doi_resolver_url }}
|
{{ doi_resolver_name }} - {{ doi_resolver_url }}
|
||||||
|
@ -134,8 +134,8 @@
|
||||||
|
|
||||||
{% set label = _('Engine tokens') %}
|
{% set label = _('Engine tokens') %}
|
||||||
{% set info = _('Access tokens for private engines') %}
|
{% set info = _('Access tokens for private engines') %}
|
||||||
{{ preferences_item_header(info, label, rtl) }}
|
{{ preferences_item_header(info, label, rtl, 'tokens') }}
|
||||||
<input class="form-control" id='tokens' name='tokens' value='{{ preferences.tokens.get_value() }}'/>
|
<input class="form-control" id="tokens" name="tokens" value='{{ preferences.tokens.get_value() }}'/>
|
||||||
{{ preferences_item_footer(info, label, rtl) }}
|
{{ preferences_item_footer(info, label, rtl) }}
|
||||||
</div>
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
|
@ -173,23 +173,23 @@
|
||||||
<table class="table table-hover table-condensed table-striped">
|
<table class="table table-hover table-condensed table-striped">
|
||||||
<tr>
|
<tr>
|
||||||
{% if not rtl %}
|
{% if not rtl %}
|
||||||
<th>{{ _("Allow") }}</th>
|
<th scope="col">{{ _("Allow") }}</th>
|
||||||
<th>{{ _("Engine name") }}</th>
|
<th scope="col">{{ _("Engine name") }}</th>
|
||||||
<th>{{ _("Shortcut") }}</th>
|
<th scope="col">{{ _("Shortcut") }}</th>
|
||||||
<th>{{ _("Selected language") }}</th>
|
<th scope="col">{{ _("Selected language") }}</th>
|
||||||
<th>{{ _("SafeSearch") }}</th>
|
<th scope="col">{{ _("SafeSearch") }}</th>
|
||||||
<th>{{ _("Time range") }}</th>
|
<th scope="col">{{ _("Time range") }}</th>
|
||||||
<th>{{ _("Avg. time") }}</th>
|
<th scope="col">{{ _("Avg. time") }}</th>
|
||||||
<th>{{ _("Max time") }}</th>
|
<th scope="col">{{ _("Max time") }}</th>
|
||||||
{% else %}
|
{% else %}
|
||||||
<th class="text-right">{{ _("Max time") }}</th>
|
<th scope="col" class="text-right">{{ _("Max time") }}</th>
|
||||||
<th class="text-right">{{ _("Avg. time") }}</th>
|
<th scope="col" class="text-right">{{ _("Avg. time") }}</th>
|
||||||
<th class="text-right">{{ _("Time range") }}</th>
|
<th scope="col" class="text-right">{{ _("Time range") }}</th>
|
||||||
<th class="text-right">{{ _("SafeSearch") }}</th>
|
<th scope="col" class="text-right">{{ _("SafeSearch") }}</th>
|
||||||
<th class="text-right">{{ _("Selected language") }}</th>
|
<th scope="col" class="text-right">{{ _("Selected language") }}</th>
|
||||||
<th class="text-right">{{ _("Shortcut") }}</th>
|
<th scope="col" class="text-right">{{ _("Shortcut") }}</th>
|
||||||
<th class="text-right">{{ _("Engine name") }}</th>
|
<th scope="col" class="text-right">{{ _("Engine name") }}</th>
|
||||||
<th class="text-right">{{ _("Allow") }}</th>
|
<th scope="col" class="text-right">{{ _("Allow") }}</th>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
{% for search_engine in engines_by_category[categ] %}
|
{% for search_engine in engines_by_category[categ] %}
|
||||||
|
@ -199,21 +199,21 @@
|
||||||
<td class="onoff-checkbox">
|
<td class="onoff-checkbox">
|
||||||
{{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
|
{{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
|
||||||
</td>
|
</td>
|
||||||
<th>{{ search_engine.name }}</th>
|
<th scope="row">{{ search_engine.name }}</th>
|
||||||
<td class="name">{{ shortcuts[search_engine.name] }}</td>
|
<td class="name">{{ shortcuts[search_engine.name] }}</td>
|
||||||
<td>{{ support_toggle(stats[search_engine.name].supports_selected_language) }}</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.safesearch==True) }}</td>
|
||||||
<td>{{ support_toggle(search_engine.time_range_support==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_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 '' }}">{{ search_engine.timeout }}</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 %}
|
{% 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_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 }}</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.time_range_support==True) }}</td>
|
||||||
<td>{{ support_toggle(search_engine.safesearch==True) }}</td>
|
<td>{{ support_toggle(search_engine.safesearch==True) }}</td>
|
||||||
<td>{{ support_toggle(stats[search_engine.name].supports_selected_language) }}</td>
|
<td>{{ support_toggle(stats[search_engine.name].supports_selected_language) }}</td>
|
||||||
<td>{{ shortcuts[search_engine.name] }}</td>
|
<td>{{ shortcuts[search_engine.name] }}</td>
|
||||||
<th>{{ search_engine.name }}</th>
|
<th scope="row">{{ search_engine.name }}</th>
|
||||||
<td class="onoff-checkbox">
|
<td class="onoff-checkbox">
|
||||||
{{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
|
{{ checkbox_toggle('engine_' + search_engine.name|replace(' ', '_') + '__' + categ|replace(' ', '_'), (search_engine.name, categ) in disabled_engines) }}
|
||||||
</td>
|
</td>
|
||||||
|
@ -241,7 +241,7 @@
|
||||||
<h3 class="panel-title">{{ _(plugin.name) }}</h3>
|
<h3 class="panel-title">{{ _(plugin.name) }}</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel-body">
|
<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="col-xs-6 col-sm-4 col-md-6">
|
||||||
<div class="onoff-checkbox">
|
<div class="onoff-checkbox">
|
||||||
{{ checkbox_toggle('plugin_' + plugin.id, plugin.id not in allowed_plugins) }}
|
{{ checkbox_toggle('plugin_' + plugin.id, plugin.id not in allowed_plugins) }}
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
{%- if result.img_src -%}
|
{%- if result.img_src -%}
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<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 -%}
|
{% if result.content %}<p class="result-content col-xs-8 col-sm-8 col-md-8">{{ result.content|safe }}</p>{% endif -%}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="row">
|
<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.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.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 %}
|
{% 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">{{- "" -}}
|
<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 ""}}>
|
<option id="time-range-anytime" value="" {{ "selected" if time_range=="" or not time_range else ""}}>
|
||||||
{{- _('Anytime') -}}
|
{{- _('Anytime') -}}
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge, chrome=1">
|
||||||
<title>{% block title %}{% endblock %}{{ instance_name }}</title>
|
<title>{% block title %}{% endblock %}{{ instance_name }}</title>
|
||||||
{% block meta %}{% endblock %}
|
{% block meta %}{% endblock %}
|
||||||
|
<script src="{{ url_for('js_translations') }}"></script>
|
||||||
{% if rtl %}
|
{% if rtl %}
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/searx-rtl.min.css') }}" type="text/css" media="screen" />
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/searx-rtl.min.css') }}" type="text/css" media="screen" />
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -335,8 +335,15 @@ def image_proxify(url):
|
||||||
if not request.preferences.get_value('image_proxy'):
|
if not request.preferences.get_value('image_proxy'):
|
||||||
return url
|
return url
|
||||||
|
|
||||||
if url.startswith('data:image/jpeg;base64,'):
|
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
|
return url
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
if settings.get('result_proxy'):
|
if settings.get('result_proxy'):
|
||||||
return proxify(url)
|
return proxify(url)
|
||||||
|
@ -949,7 +956,7 @@ def opensearch():
|
||||||
|
|
||||||
resp = Response(response=ret,
|
resp = Response(response=ret,
|
||||||
status=200,
|
status=200,
|
||||||
mimetype="text/xml")
|
mimetype="application/opensearchdescription+xml")
|
||||||
return resp
|
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)
|
@app.errorhandler(404)
|
||||||
def page_not_found(e):
|
def page_not_found(e):
|
||||||
return render('404.html'), 404
|
return render('404.html'), 404
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
export GIT_URL='https://github.com/asciimoo/searx'
|
export GIT_URL='https://github.com/asciimoo/searx'
|
||||||
|
export GIT_BRANCH='master'
|
||||||
export ISSUE_URL='https://github.com/asciimoo/searx/issues'
|
export ISSUE_URL='https://github.com/asciimoo/searx/issues'
|
||||||
export SEARX_URL='https://searx.me'
|
export SEARX_URL='https://searx.me'
|
||||||
export DOCS_URL='https://asciimoo.github.io/searx'
|
export DOCS_URL='https://asciimoo.github.io/searx'
|
||||||
|
|
|
@ -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 "$@"
|
||||||
|
# ----------------------------------------------------------------------------
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||||
|
)
|
||||||
|
}
|
|
@ -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 -*-
|
# -*- 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:
|
make-help:
|
||||||
|
else
|
||||||
|
make-help: lxc-help
|
||||||
|
endif
|
||||||
@echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
|
@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'
|
@echo ' make V=2 [targets] 2 => give reason for rebuild of target'
|
||||||
|
|
||||||
quiet_cmd_common_clean = CLEAN $@
|
quiet_cmd_common_clean = CLEAN $@
|
||||||
cmd_common_clean = \
|
cmd_common_clean = \
|
||||||
rm -rf tests/build ;\
|
|
||||||
find . -name '*.orig' -exec rm -f {} + ;\
|
find . -name '*.orig' -exec rm -f {} + ;\
|
||||||
find . -name '*.rej' -exec rm -f {} + ;\
|
find . -name '*.rej' -exec rm -f {} + ;\
|
||||||
find . -name '*~' -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
|
# printing commands
|
||||||
cmd = @$(echo-cmd) $(cmd_$(1))
|
cmd = @$(echo-cmd) $(cmd_$(1))
|
||||||
|
|
||||||
|
.PHONY: $(PHONY)
|
||||||
|
|
|
@ -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
|
export PY_ENV PYDIST PYBUILD
|
||||||
|
|
||||||
# folder where the python distribution takes place
|
# folder where the python distribution takes place
|
||||||
PYDIST ?= ./py_dist
|
PYDIST = ./$(LXC_ENV_FOLDER)dist
|
||||||
# folder where the python intermediate build files take place
|
# folder where the python intermediate build files take place
|
||||||
PYBUILD ?= ./py_build
|
PYBUILD = ./$(LXC_ENV_FOLDER)build
|
||||||
# python version to use
|
# python version to use
|
||||||
PY ?=3
|
PY ?=3
|
||||||
# $(PYTHON) points to the python interpreter from the OS! The python from the
|
# $(PYTHON) points to the python interpreter from the OS! The python from the
|
||||||
|
@ -30,8 +30,7 @@ PYLINT_RC ?= .pylintrc
|
||||||
TEST_FOLDER ?= ./tests
|
TEST_FOLDER ?= ./tests
|
||||||
TEST ?= .
|
TEST ?= .
|
||||||
|
|
||||||
VTENV_OPTS = "--no-site-packages"
|
PY_ENV = ./$(LXC_ENV_FOLDER)local/py$(PY)
|
||||||
PY_ENV = ./local/py$(PY)
|
|
||||||
PY_ENV_BIN = $(PY_ENV)/bin
|
PY_ENV_BIN = $(PY_ENV)/bin
|
||||||
PY_ENV_ACT = . $(PY_ENV_BIN)/activate
|
PY_ENV_ACT = . $(PY_ENV_BIN)/activate
|
||||||
|
|
||||||
|
@ -41,6 +40,7 @@ ifeq ($(OS),Windows_NT)
|
||||||
PY_ENV_ACT = $(PY_ENV_BIN)/activate
|
PY_ENV_ACT = $(PY_ENV_BIN)/activate
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
VTENV_OPTS ?=
|
||||||
ifeq ($(PYTHON),python)
|
ifeq ($(PYTHON),python)
|
||||||
VIRTUALENV = virtualenv
|
VIRTUALENV = virtualenv
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
# -*- coding: utf-8; mode: makefile-gmake -*-
|
# -*- 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.
|
# You can set these variables from the command line.
|
||||||
SPHINXOPTS ?=
|
SPHINXOPTS ?=
|
||||||
SPHINXBUILD ?= $(PY_ENV_BIN)/sphinx-build
|
SPHINXBUILD ?= $(PY_ENV_BIN)/sphinx-build
|
||||||
SPHINX_CONF ?= conf.py
|
SPHINX_CONF ?= conf.py
|
||||||
|
|
||||||
DOCS_FOLDER ?= docs
|
DOCS_FOLDER = ./docs
|
||||||
DOCS_BUILD ?= build/docs
|
DOCS_BUILD = ./$(LXC_ENV_FOLDER)build/docs
|
||||||
DOCS_DIST ?= dist/docs
|
DOCS_DIST = ./$(LXC_ENV_FOLDER)dist/docs
|
||||||
GH_PAGES ?= gh-pages
|
GH_PAGES ?= gh-pages
|
||||||
|
|
||||||
BOOKS_FOLDER ?= docs
|
BOOKS_FOLDER = ./docs
|
||||||
BOOKS_DIST ?= dist/books
|
BOOKS_DIST = ./$(LXC_ENV_FOLDER)dist/books
|
||||||
|
|
||||||
ifeq ($(KBUILD_VERBOSE),1)
|
ifeq ($(KBUILD_VERBOSE),1)
|
||||||
SPHINX_VERBOSE = "-v"
|
SPHINX_VERBOSE = "-v"
|
||||||
|
@ -54,11 +56,13 @@ docs-help:
|
||||||
# requirements
|
# requirements
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
|
||||||
sphinx-doc: $(PY_ENV)
|
sphinx-doc-prebuilds:: $(PY_ENV)
|
||||||
|
|
||||||
|
sphinx-doc: sphinx-doc-prebuilds
|
||||||
@echo "PYENV installing Sphinx$(SPHINXVERS)"
|
@echo "PYENV installing Sphinx$(SPHINXVERS)"
|
||||||
$(Q)$(PY_ENV_BIN)/pip install $(PIP_VERBOSE) '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)"
|
@echo "PYENV installing Sphinx$(SPHINXVERS)"
|
||||||
$(Q)$(PY_ENV_BIN)/pip install $(PIP_VERBOSE) 'Sphinx$(SPHINXVERS)' sphinx-autobuild
|
$(Q)$(PY_ENV_BIN)/pip install $(PIP_VERBOSE) 'Sphinx$(SPHINXVERS)' sphinx-autobuild
|
||||||
|
|
||||||
|
@ -154,7 +158,7 @@ $(BOOKS_HTML): sphinx-doc | $(BOOKS_DIST)
|
||||||
-b html \
|
-b html \
|
||||||
-c $(DOCS_FOLDER) \
|
-c $(DOCS_FOLDER) \
|
||||||
-d $(DOCS_BUILD)/books/$(patsubst books/%.html,%,$@)/.doctrees \
|
-d $(DOCS_BUILD)/books/$(patsubst books/%.html,%,$@)/.doctrees \
|
||||||
$(patsubst books/%.html,%,$@) \
|
$(BOOKS_FOLDER)/$(patsubst books/%.html,%,$@) \
|
||||||
$(BOOKS_DIST)/$(patsubst books/%.html,%,$@)
|
$(BOOKS_DIST)/$(patsubst books/%.html,%,$@)
|
||||||
@echo "SPHINX $@ --> file://$(abspath $(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 \
|
-b html \
|
||||||
-c $(DOCS_FOLDER) \
|
-c $(DOCS_FOLDER) \
|
||||||
-d $(DOCS_BUILD)/books/$(patsubst books/%.live,%,$@)/.doctrees \
|
-d $(DOCS_BUILD)/books/$(patsubst books/%.live,%,$@)/.doctrees \
|
||||||
$(patsubst books/%.live,%,$@) \
|
$(BOOKS_FOLDER)/$(patsubst books/%.live,%,$@) \
|
||||||
$(BOOKS_DIST)/$(patsubst books/%.live,%,$@)
|
$(BOOKS_DIST)/$(patsubst books/%.live,%,$@)
|
||||||
|
|
||||||
$(BOOKS_PDF): %.pdf : %.latex
|
$(BOOKS_PDF): %.pdf : %.latex
|
||||||
|
@ -182,7 +186,7 @@ $(BOOKS_LATEX): sphinx-doc | $(BOOKS_DIST)
|
||||||
-b latex \
|
-b latex \
|
||||||
-c $(DOCS_FOLDER) \
|
-c $(DOCS_FOLDER) \
|
||||||
-d $(DOCS_BUILD)/books/$(patsubst books/%.latex,%,$@)/.doctrees \
|
-d $(DOCS_BUILD)/books/$(patsubst books/%.latex,%,$@)/.doctrees \
|
||||||
$(patsubst books/%.latex,%,$@) \
|
$(BOOKS_FOLDER)/$(patsubst books/%.latex,%,$@) \
|
||||||
$(DOCS_BUILD)/latex/$(patsubst books/%.latex,%,$@)
|
$(DOCS_BUILD)/latex/$(patsubst books/%.latex,%,$@)
|
||||||
@echo "SPHINX $@ --> file://$(abspath $(DOCS_BUILD)/latex/$(patsubst books/%.latex,%,$@))"
|
@echo "SPHINX $@ --> file://$(abspath $(DOCS_BUILD)/latex/$(patsubst books/%.latex,%,$@))"
|
||||||
|
|
||||||
|
|
|
@ -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 "$@"
|
||||||
|
# ----------------------------------------------------------------------------
|
|
@ -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 "$@"
|
||||||
|
# ----------------------------------------------------------------------------
|
|
@ -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)
|
|
@ -0,0 +1 @@
|
||||||
|
httpd
|
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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;
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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