-
Notifications
You must be signed in to change notification settings - Fork 0
08_Deploy_tutorial
fireballz22 edited this page Aug 9, 2024
·
1 revision
- This page is a moving target
- Things may get out of date, due to the incompleteness of everything
- Other contributors nee to start working on their parts of the system
- Assumes an archlinux machine/vm
- Assumes root user everywhere
- Change usernames and passwords from examples here

- the meili executable only cares about its
config.toml, in it contains values for:- which data dir to write to
- api key
- exposed host address port
- performance tuning params
- the mysql part only cares about the configs stored in
/etc/my.cnf.d/my.cnf, lots of things to tweak here - nginx only cares about whats in
/etc/nginx/, other than basic http/https/server configs:- ayase-quarts unix socket it has to proxy pass to
- meili's debug page it has to proxy passs to if its meili is in dev mode
- the media storage directory
- ayase quart has more moving parts:
- the python deps:
- uses
virtualenv-wrapperto switch between sets of deps easily workon your_env; pip install ~/aq/requirements.txt
- uses
- hypercorn:
- connection to nginx via uds
- manages the app workers
- configs in
~/hyperconf.toml
- the code:
git pull mainto pull in the source - the boards we want to expose:
meta.py - the connection to meili and mysql:
configs.py
- the python deps:
# find good mirrors
reflector --sort rate --latest 10 --protocol https --country US --save /etc/pacman.d/mirrorlist
# update package db + keyring first
pacman -Sy && yes Y | pacman -S archlinux-keyring
# minimum packages
# extra favorites: neovim zstd stow ncdu htop eza bat fd xh ripgrep tmux rsync
yes Y | pacman -S git chrony cronie curl ufw
# start base services
systemctl enable --now cronie chronyd ufw
# upgrade full system & remove packages
yes Y | pacman -Syu && yes Y | pacman -Scc
# firewall up
ufw allow ssh
ufw allow http
ufw allow https
# create meili dir
mkdir /srv/meili
# create media dir
mkdir /srv/http/media
# download a thumbnail dump
curl -L -o /srv/http/media/4ch-be-thumbs_20151031.tar.gz https://archive.org/download/4ch.be/4ch-be-thumbs_20151031.tar.gz
# unpack thumbnail dump
tar -xzf /srv/http/media/4ch-be-thumbs_20151031.tar.gz
# rename
mv /srv/http/media/boards /srv/http/media/neo
# download aq
git clone --depth 1 https://github.com/sky-cake/ayase-quart.git ~/aq
# generate secret file
tr -dc A-Za-z0-9 < /dev/urandom | head -c 64 > ~/aq/src/secret.txt
# reboot, check everything still works
reboot -h now- Files edited with
nanohave their example content later down
# packages for native
yes y | pacman -S python python-virtualenvwrapper mariadb nginx nginx-mod-brotli
# set virtualenv dir
export WORKON_HOME=~/.virtualenvs
# export virtualenv commands to sesssion
source /usr/bin/virtualenvwrapper.sh
# create .bashrc if not exists
[[ -f ~/.bashrc ]] && touch ~/.bashrc
# virtualenv commands in bashrc
echo "export WORKON_HOME=~/.virtualenvs" >> ~/.bashrc
echo "source /usr/bin/virtualenvwrapper.sh" >> ~/.bashrc
# must source .bashrc for each new ssh connection until full logout
## BEGIN MARIADB
# backup default config if exists and copy config over (edit as needed)
[[ -f /etc/my.cnf.d/my.cnf ]] && mv /etc/my.cnf.d/my.cnf /etc/my.cnf.d/my.cnf.bak
nano /etc/my.cnf.d/my.cnf
# must happen before starting systemd service, but after my.cnf planted for innodb support
mariadb-install-db --user=mysql --basedir=/usr --datadir=/var/lib/mysql
# start mariadb systemd service
systemctl enable --now mariadb
# create db and aq user
mariadb -e "CREATE DATABASE IF NOT EXISTS hayden CHARACTER SET = 'utf8mb4' COLLATE = 'utf8mb4_general_ci';"
mariadb -e "CREATE USER 'hayden_user'@'localhost' IDENTIFIED BY 'hayden_password';"
mariadb -e "GRANT ALL PRIVILEGES ON hayden.* TO 'hayden_user'@'localhost'; FLUSH PRIVILEGES;"
# get an sql dump
curl -LO https://archive.org/download/4ch.be/4ch-be-db_20151031.sql.gz
# load dump
gunzip -c ~/4ch-be-db_20151031.sql.gz | sed -e 's/ENGINE=TokuDB/ENGINE=InnoDB/g' | sed -e 's/CHARSET=utf8 /CHARSET=utf8mb4 /g' | sed -e 's/CHARSET=utf8mb4.*;/CHARSET=utf8mb4;/g' | mariadb hayden
## END MARIADB
## BEGIN MEILI
# direct meilisearch download
curl -L https://github.com/meilisearch/meilisearch/releases/download/v1.9.0/meilisearch-linux-amd64 -o /srv/meili/meilisearch
chmod +x /srv/meili/meilisearch
# Setup meili config
nano /srv/meili/config.toml
# start meili and put in bg
/srv/meili/meilisearch --config-file-path=/srv/meili/config.toml &
## END MEILI
## BEGIN AYASE-QUART
# create virtualenv
mkvirtualenv aq1
# activate it
workon aq1
# install deps
pip install -r aq/requirements.txt
# fix AQ files
# get into src dir
cd aq/src
# edit hypercorn config
nano ~/hyperconf.toml
# start aq into bg
hypercorn --config ~/hyperconf.toml main:app &
# create index in gui
# populate meili
python -m search load g ck mu
# back to home
cd
## END AYASE-QUART
## BEGIN NGINX
systemctl enable --now nginx
# Insert ayase-quart config and modify nginx
nano /etc/nginx/aq.conf
nano /etc/nginx/nginx.conf
# check configs are valid
nginx -t
# reload with good configs
nginx -s reload
## END NGINX
~/aq/src/configs.py- copy the template over
cp ~/aq/src/rename_to_configs.py ~/aq/src/configs.py
- Edit the relevant parts
class CONSTS(NamedTuple):
TESTING = False
autoreload = False
# site details
site_name = "Ayase Quart"
site_url = "https://aq.domain.tld" # change to actual site address
# mysql settings
db_type = DbType.mysql
db_host = '127.0.0.1'
db_port = 3306
db_database = 'hayden'
db_user = 'hayden_user'
db_password = 'hayden_password'
# media link generation base paths
image_uri = "/static/neo/{board_shortname}/image"
thumb_uri = "/static/neo/{board_shortname}/thumb"
# search engine settings
index_search_provider = IndexSearchType.meili
index_search_host = 'http://127.0.0.1:7700' # set in /srv/meili/config.toml
index_search_auth_key = '84661694560523325849' # set in /srv/meili/config.toml
index_search_config = dict(
headers={
'content-type': 'application/json',
'Authorization': f'Bearer {index_search_auth_key}',
}
)/srv/meili/config.toml
no_analytics = true
env = "development" # Value must be either `production` or `development`.
master_key = "84661694560523325849" # change this, its the api key for the debug page too
http_addr = '127.0.0.1:7700' # 0.0.0.0 to expose over network
http_payload_size_limit = "100 MB"
log_level = "INFO" # `OFF`, `ERROR`, `WARN`, `INFO`, `DEBUG`, `TRACE`
max_indexing_threads = 4 # set to all number of real cores (not SMT/HT)
max_indexing_memory = "2 GiB" # Set to full ram - (mysql innodb + 256MB + 80MB/hypercorn worker)
db_path = "/srv/meili/data" # main storage
dump_dir = "/srv/meili/dumps/"
snapshot_dir = "/srv/meili/snapshots/"
ignore_missing_dump = false
ignore_dump_if_db_exists = false
schedule_snapshot = false # false or interval in seconds
ignore_missing_snapshot = false
ignore_snapshot_if_db_exists = false/etc/nginx/aq.conf- In addtion to everything else in
/etc/nginx/nginx.conf - Replace
domain.tldwith your own- Generate certs with
yes y | pacman -S certbot certbot certonly --manual --agree-tos --register-unsafely-without-email --preferred-challenges dns -d *.domain.tld -d domain.tld # follow onscreen instructions
- Copy the certs over to nginx dir or change config to point to
/etc/letsencrypt/live/domain.tld
- Import it in
nginx.confwithinclude /etc/nginx/aq.conf;in thehttpblock
# Cert & key
ssl_certificate /etc/nginx/certs/domain.tld/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/domain.tld/privkey.pem;
# Ca-cert for ocsp
ssl_trusted_certificate /etc/nginx/certs/domain.tld/chain.pem;
upstream aqbackend {
# don't put in /tmp, not multi process usable
server unix:/var/run/aq.sock;
keepalive 400;
}
# main server
server {
listen 443 ssl http2;
server_name domain.tld;
location / {
proxy_pass http://aqbackend/;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
proxy_redirect off;
client_max_body_size 1M;
proxy_read_timeout 300;
proxy_connect_timeout 300;
}
location /static {
alias /root/aq/src/static;
# 30 days
add_header 'Cache-Control' 'max-age=2592000';
}
location /static/neo {
alias /srv/http/media/neo;
add_header 'Cache-Control' 'max-age=2592000';
etag off;
}
}
# Meili's JS won't load from a sub-path, needs a subdomain of its down
server {
listen 443 ssl http2;
server_name meili.domain.tld;
location / {
proxy_pass http://127.0.0.1:7700;
proxy_http_version 1.1;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffering off;
proxy_request_buffering off;
}
}
# https redirect
server {
listen 80;
listen [::]:80;
server_name domain.tld;
default_type "";
return 301 https://$host$request_uri;
}
# https catchall
server {
listen 443 ssl http2;
server_name .domain.tld;
return 444;
}/etc/my.cnf.d/my.cnf
[client]
port = 3306
socket = /run/mysqld/mysqld.sock
default-character-set = utf8mb4
[mysqld_safe]
socket = /run/mysqld/mysqld.sock
nice = 0
[mysqld]
pid-file = /run/mysqld/mysqld.pid
# bind-address = 127.0.0.1 # default is localhost
port = 3306
socket = /run/mysqld/mysqld.sock
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc_messages_dir = /usr/share/mariadb
lc_messages = en_US
# UTC timezone
default-time-zone=+00:00
old-mode='NO_DUP_KEY_WARNINGS_WITH_IGNORE'
skip-external-locking
key_buffer_size = 128M
max_connections = 100
connect_timeout = 5
# affects insert query sizes of mysqldumps
max_allowed_packet = 512M
# must be higher than pool connecting lifetime
wait_timeout = 3600
net_read_timeout = 3600
net_write_timeout = 3600
thread_cache_size = 128
thread_stack = 192K
sort_buffer_size = 4M
bulk_insert_buffer_size = 32M
tmp_table_size = 32M
max_heap_table_size = 32M
#performance_schema = on
character_set_server = utf8mb4
collation_server = utf8mb4_general_ci
transaction_isolation = READ-COMMITTED
binlog_format = MIXED
large_pages = ON
query_cache_type = OFF
skip-log-bin = 1
max_binlog_size = 100M
# Innodb
default_storage_engine = InnoDB
innodb_page_size = 4K
innodb_buffer_pool_size = 256M
innodb_log_buffer_size = 8M
innodb_file_per_table = 1
innodb_open_files = 1000
innodb_io_capacity = 3000
innodb_flush_method = O_DIRECT
innodb_stats_on_metadata = OFF
innodb_flush_log_at_trx_commit = 2
[mysqldump]
quick
quote-names
max_allowed_packet = 256M~/hyperconf.toml
bind = 'unix:/var/run/aq.sock'
# bind = 'http://0.0.0.0:9001'
backlog = 500
umask = 79 # must be decimal int, not octal, 0o117 == 79
user = 33 # http user
group = 33 # http group
workers = 4 # num cores * 2
loglevel = 'WARNING'