Hosting Searxng on Alpine
2023-07-25
Here’s how you could host Searxng on Alpine Linux.
Note that I don’t wish to create a venv.
[ $(id -u) -eq 0 ] || exit 1
apk add git python3 py3-gunicorn py3-pip py3-yaml
mkdir /usr/local/searx
addgroup -S searx
adduser -S -D -h /usr/local/searx -s /sbin/nologin -G searx searx
chown -R searx:searx /usr/local/searx
doas -u searx git clone https://github.com/searxng/searxng.git /usr/local/searx/searx-src
doas -u searx pip install -r /usr/local/searx/searx-src/requirements.txt
Follow the official guide for the /etc/searxng/settings.yml
stuff and then try to run.
cd /usr/local/searx/
doas -u searx gunicorn -b 127.0.0.1:8001 --chdir /usr/local/searx/searx-src/searx --pythonpath /usr/local/searx/searx-src searx.webapp
Hope to see something like this:
/usr/local/searx # doas -u searx gunicorn -b 127.0.0.1:8001 --chdir /usr/local/searx/searx-src/searx --pythonpath /usr/local/searx/searx-src searx.webapp
[2023-07-25 21:40:38 +0000] [2837] [INFO] Starting gunicorn 20.1.0
[2023-07-25 21:40:38 +0000] [2837] [INFO] Listening at: http://127.0.0.1:8001 (2837)
[2023-07-25 21:40:38 +0000] [2837] [INFO] Using worker: sync
[2023-07-25 21:40:38 +0000] [2838] [INFO] Booting worker with pid: 2838
Now you got searxng running but if you want it public we should prepare filtron and morty, and make them services. 🥵
doas apk add go
go install github.com/asciimoo/filtron@latest
go install github.com/asciimoo/morty@latest
doas mv ~/go/bin/filtron ~/go/bin/morty /usr/local/bin
doas addgroup -S filtron
doas adduser -S -D -H -s /sbin/nologin -G filtron filtron
doas addgroup -S morty
doas adduser -S -D -H -s /sbin/nologin -G morty morty
Now, let me omit obvious explainations. The point is you should get to have something like this:
searx:~$ cat /etc/init.d/filtron
#!/sbin/openrc-run
supervisor=supervise-daemon
name=filtron
command="/usr/local/bin/filtron"
command_args="-api '127.0.0.1:4005' -listen '127.0.0.1:4004' -rules '/etc/filtron/rules.json' -target '127.0.0.1:8001'"
command_user="${FILTRON_USER:-filtron}"
pidfile="/run/filtron.pid"
depend() {
need net
after firewall
}
searx:~$ doas rc-service filtron start
* Starting filtron ... [ ok ]
searx:~$ doas rc-update add filtron
* service filtron added to runlevel default
searx:~$ cat /etc/init.d/morty
#!/sbin/openrc-run
supervisor=supervise-daemon
name=morty
command="/usr/local/bin/morty"
command_user="${FILTRON_USER:-morty}"
supervise_daemon_args="--env DEBUG=false --env MORTY_ADDRESS=127.0.0.1:3000 --env MORTY_KEY=<your secret key generated with `openssl rand -base64 33`>"
pidfile="/run/morty.pid"
depend() {
need net
after firewall
}
searx:~$ doas rc-service morty start
* Starting morty ... [ ok ]
searx:~$ doas rc-update add morty
* service morty added to runlevel default
searx:~$ cat /etc/init.d/searx
#!/sbin/openrc-run
supervisor=supervise-daemon
name=searx
command="/usr/bin/gunicorn"
command_args="-b 127.0.0.1:8001 --chdir /usr/local/searx/searx-src/searx --pythonpath /usr/local/searx/searx-src searx.webapp"
command_user="${SEARX_USER:-searx}"
pidfile="/run/searx.pid"
depend() {
need net
after firewall
}
searx:~$ doas rc-service searx start
* Caching service dependencies ... [ ok ]
* Starting searx ... [ ok ]
searx:~$ doas rc-update add searx
* service searx added to runlevel default
Got it?
searx:~$ doas netstat -ltp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 searx.searx.fmac.xyz:8001 0.0.0.0:* LISTEN 4526/gunicorn: mast
tcp 0 0 searx.searx.fmac.xyz:4005 0.0.0.0:* LISTEN 4337/filtron
tcp 0 0 searx.searx.fmac.xyz:4004 0.0.0.0:* LISTEN 4337/filtron
tcp 0 0 searx.searx.fmac.xyz:3000 0.0.0.0:* LISTEN 4367/morty
Cool. We can now serve this through a nice reverse proxy.
doas apk add caddy
searx:~$ cat /etc/caddy/Caddyfile
# Refer to the Caddy docs for more information:
# https://caddyserver.com/docs/caddyfile
searx.fmac.xyz {
tls {
protocols tls1.2 tls1.3
ciphers TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
}
root * /usr/local/searx/searx-src/searx
@static {
method GET
path /static/*
}
file_server @static
@searx {
not path /static/*
not path /morty/*
}
reverse_proxy @searx 127.0.0.1:4004 {
header_up X-Real-IP {http.request.remote.host}
}
reverse_proxy /morty/* 127.0.0.1:3000 {
header_up Host {http.reverse_proxy.upstream.hostport}
header_up X-Real-IP {http.request.remote.host}
}
header * Strict-Transport-Security "max-age=63072000"
header * Feature-Policy "accelerometer 'none';ambient-light-sensor 'none'; autoplay 'none';camera 'none';encrypted-media 'none';focus-without-user-activation 'none'; geolocation 'none';gyroscope 'none';magnetometer 'none';microphone 'none';midi 'none';payment 'none';picture-in-picture 'none'; speaker 'none';sync-xhr 'none';usb 'none';vr 'none'"
header * Content-Security-Policy "upgrade-insecure-requests; default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; form-action 'self'; font-src 'self'; frame-ancestors 'self'; base-uri 'self'; connect-src 'self' https://overpass-api.de; img-src * data: https://*.tile.openstreetmap.org; frame-src https://www.youtube-nocookie.com https://player.vimeo.com https://www.dailymotion.com https://www.deezer.com https://www.mixcloud.com https://w.soundcloud.com https://embed.spotify.com"
header * X-Frame-Options "SAMEORIGIN"
header * -Server
encode zstd gzip
log {
output file /var/log/caddy/searx.fmac.xyz.access.log {
roll_size 1gb
roll_keep 12
roll_keep_for 48h
}
level error
}
}
searx:~$ doas rc-service caddy start
searx:~$ doas rc-update add caddy
Enjoy c: