From b26d0f4b9216cf2216f343741d8531ce38ce24d8 Mon Sep 17 00:00:00 2001 From: edshot99 Date: Thu, 7 Nov 2024 19:49:23 -0600 Subject: [PATCH] document installing e621ng on OpenBSD be gone Docker and Linux ! --- INSTALL.md | 198 ++++++++++++++++++++++++++++++++++++++ docker/nginx.conf.example | 138 ++++++++++++++++++++++++++ 2 files changed, 336 insertions(+) create mode 100644 INSTALL.md create mode 100644 docker/nginx.conf.example diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 000000000..4b7d109c7 --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,198 @@ +# Installation +The first step you will need to take is to install the following packages: +``` +# pkg_add postgresql-server postgresql-contrib +# pkg_add opensearch +# pkg_add nginx nginx-securelink +# pkg_add redis memcached +# pkg_add -D unsigned iqdb autocompleted +# pkg_add ruby git libxslt libgit2 +# pkg_add yarn +# pkg_add ffmpeg libvips +``` + +Package Notes: +iqdb and autocompleted will need to be compiled on your own for the time being. +You can find the port files at this repository: https://git.groovyexpress.com/edshot99/OpenBSD-Unofficial-Ports +With OpenBSD 7.6 there will compilation problems with autocompleted. You can install an older Rust compiler from OpenBSD 7.5 to get around this. + +OpenBSD 7.6 uses a new version of libgit2 that is incompatible with the Ruby rugged gem. This will also require compiling an older version of libgit2 if you are using OpenBSD 7.6 + +Lastly, libvips is currently compiled with a lot of features disabled. One of these features being ICC support which causes problem with e621ng. +This will also require a recompile with lcms2 support enabled. + +This is quite cumbersome to deal with, but will eventually be taken care of to make installation easier. + +## PostgreSQL +You can follow the guide at /usr/local/share/doc/pkg-readmes/postgresql on setting up PostgreSQL. +Once you have PostgreSQL set up you can set up the e621 account as follows: +``` +CREATE ROLE e621 WITH CREATEDB LOGIN PASSWORD 'XXX'; +``` + +## OpenSearch +You can follow the guide at /usr/local/share/doc/pkg-readmes/opensearch on tuning your system for OpenSearch. +Don't follow the 'Initial Node/Cluster Configuration' section. e621ng will not be needing the OpenSearch security plugin. + +Once finished tuning your system, you can then edit your /etc/opensearch/opensearch.yml configuration to something like this: +``` +cluster.name: e621ng +node.name: node-1 +path.data: /var/opensearch/ +path.logs: /var/log/opensearch/ +network.host: 127.0.0.1 +plugins.security.disabled: true +``` + +and then enable and start the OpenSearch daemon: +``` +# rcctl enable opensearch +# rcctl start opensearch +``` + +## Nginx +You can follow the guide at /usr/local/share/doc/pkg-readmes/nginx on setting up log rotation for nginx. + +Afterwards you can copy the example nginx configuration file from 'docker/nginx.conf.example' in this repository to /etc/nginx/ +Once copied you can set the file permissions to 600 to prevent wheel and world group users from seeing the HMAC secrets and then modify the file to your needs. + +You will also want to copy the example acme-client.conf configuration file from /etc/examples/ to /etc/ and modify it to your needs. + +Once configuration is complete you can then enable nginx, start nginx, and request a x509 certificate: +``` +# rcctl enable nginx +# rcctl start nginx +# acme-client -v my-domain-name.net +``` + +Note: You will need to temporarily disable ssl_* options in your nginx file so nginx can start properly. + +### Redis / memcached / iqdb / autocompleted +Only autocompleted needs configuring which can be done with the /etc/autocompleted.env file. + +Once configured you can then enable and start all these daemons: +``` +# rcctl enable redis +# rcctl start redis +# rcctl enable memcached +# rcctl start memcached +# rcctl enable iqdb +# rcctl start iqdb +# rcctl enable autocompleted +# rcctl start autocompleted +``` + +By default, the iqdb database is stored at /var/db/iqdb/e621_v2.db and can be configured by setting daemon flags. + +## e621ng - Part One - System Account +You can start by creating a dedicated user for running the software: +``` +# useradd -m -c "e621ng booru software" -d /var/e621ng -k /dev/null -L e621ng -s /sbin/nologin e621ng +# chmod 750 /var/e621ng +``` + +Increasing the user limits: +``` +# cp -av /etc/login.conf.d/postgresql /etc/login.conf.d/e621ng +# vi /etc/login.conf.d/e621ng +``` + +and editing the file with vi (or some other editor) to something like this: +``` +e621ng:\ + :datasize-max=8192M:\ + :datasize-cur=8192M:\ + :tc=daemon: +``` + +and lastly setting up the folder for e621ng to store the data at: +``` +# mkdir -p /var/www/e621ng/public/data +# chown -R e621ng:e621ng /var/www/e621ng/ +``` + +This is necessary because nginx runs in a chroot and won't be able to access any files outside of /var/www + +## e621ng - Part Two - Software +Log in to the e621ng user: +``` +$ doas su -l -s /bin/ksh e621ng +$ whoami +``` +(This can also be done without 'doas' if you do not have it set-up) + +Clone the repository and install the necessary packages: +``` +$ git clone https://git.groovyexpress.com/edshot99/e621ng.git +$ cd e621ng +$ bundle config set path ~/.local/share/gem +$ bundle install +$ gem install -v 1.16.4 nokogiri -- --use-system-libraries +$ gem install libgit2 -- --use-system-libraries +$ gem install foreman +$ yarn install +``` + +## e621ng - Part Three - Configuring +Create the .danbooru folder which will be used to store site specific configuration: +``` +$ cd ~/ +$ mkdir .danbooru +$ cp -av e621ng/config/initializers/content_security_policy.rb .danbooru/ +$ cp -av e621ng/docker/danbooru_local_config.rb .danbooru/ +$ openssl rand -base64 48 >.danbooru/secret_token +$ openssl rand -base64 2048 >.danbooru/session_secret_key +$ chmod 400 .danbooru/secret_token .danbooru/session_secret_key +$ chmod 640 .danbooru/danbooru_local_config.rb +``` + +You can then edit content_security_policy.rb and danbooru_local_config.rb for your needs. +The .danbooru/secret_token and .danbooru/session_secret_key don't necessarily have to be files and can be stored in the .env file, but I just prefer to do it this way. + +Once you have finished configuration you can then set up the .env file which is needed for Rails production mode: +``` +$ cp -av e621ng/.env.sample .env +$ chmod 640 .env +$ vi .env +``` + +The .env should look something like this: +``` +RAILS_ENV=production +DB_PASSWORD="XXX" +DB_HOST=localhost +DB_PORT=5432 +DB_WORKER_POOL_SIZE=10 +DB_POOL_SIZE=10 +``` + +Note: If you are planning to development you will have to modify config/databases.yml instead. + +## e621ng - Part Four - Starting +Load the configuration files into the e621ng folder: +``` +$ cd e621ng +$ ln -s /var/e621ng/.env . +$ ln -s /var/e621ng/.danbooru/danbooru_local_config.rb e621ng/danbooru_local_config.rb +$ ln -sf /var/e621ng/.danbooru/content_security_policy.rb e621ng/config/initializers/content_security_policy.rb +``` + +Modify the db/seeds.rb file to modify the admin account name and password and the auto_moderator account password. +You can also modify what forum categories are created and disable default e621 mascot and whitelist creation. + +Once this is done you can then initialize opensearch indices, the database, the webpack and then start the software: +``` +RAILS_ENV=production ./bin/rails runner '[Post, PostVersion].each { |model| model.document_store.create_index! }' +RAILS_ENV=production ./bin/rails db:create +RAILS_ENV=production ./bin/rails db:schema:load +RAILS_ENV=production ./bin/rails db:seed +./node_modules/.bin/webpack -c config/webpack/production.js +~/.local/share/gem/ruby/3.3/bin/foreman33 start +``` + +Note: Running webpack is not requried when running in developemnt mode. + +You should now be able to access the website through nginx now. +If everything is working you can also do a 'git restore db/seeds.rb' file to restore the original file. + +If something is not working you should check the log/production.log file for what is wrong. diff --git a/docker/nginx.conf.example b/docker/nginx.conf.example new file mode 100644 index 000000000..9c03d486a --- /dev/null +++ b/docker/nginx.conf.example @@ -0,0 +1,138 @@ + +user www; +worker_processes 3; + +load_module "modules/ngx_http_hmac_secure_link_module.so"; + +worker_rlimit_nofile 1024; +events { + worker_connections 800; +} + +http { + include mime.types; + default_type application/octet-stream; + + server { + listen 80; + listen [::]:80; + server_name example.com; + + location /.well-known/acme-challenge/ { + alias /acme/; + } + + location / { + return https://$HTTP_HOST$REQUEST_URI; + } + } + + server { + listen 80; + listen [::]:80; + server_name static1.example.com; + + location /.well-known/acme-challenge/ { + alias /acme/; + } + + location / { + return https://$HTTP_HOST$REQUEST_URI; + } + } + + server { + listen 443 ssl; + listen [::]:443 ssl; + server_name example.com; + root /e621ng/public-packs; + index index.html; + + client_max_body_size 512m; + + ssl_certificate /etc/ssl/example.com.fullchain.pem; + ssl_certificate_key /etc/ssl/private/example.com.key; + + ssl_ciphers HIGH+kEECDH:!aNULL; + ssl_prefer_server_ciphers on; + + location /tags/autocomplete.json { + proxy_pass http://127.0.0.1:8118/; + proxy_redirect off; + } + + location @app_server { + proxy_pass http://127.0.0.1:9000; + proxy_redirect off; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host:$server_port; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Port $server_port; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location = / { + return https://$HTTP_HOST/posts$REQUEST_URI; + } + + location / { + try_files $uri @app_server; + } + + error_page 404 /404.html; + error_page 500 502 503 504 /500.html; + } + + upstream app_server { + server 127.0.0.1:9000; + } + + server { + listen 443 ssl; + listen [::]:443 ssl; + server_name static1.example.com; + root /e621ng/public; + + ssl_certificate /etc/ssl/static1.example.com.fullchain.pem; + ssl_certificate_key /etc/ssl/private/static1.example.com.key; + + ssl_ciphers HIGH+kEECDH:!aNULL; + ssl_prefer_server_ciphers on; + + location /data { + expires max; + break; + } + + location /data/deleted/ { + add_header Cache-Control "private"; + secure_link_hmac $arg_auth,$arg_expires; + secure_link_hmac_secret "DANBOORU_PROTECTED_FILE_SECRET GOES HERE"; + secure_link_hmac_message "$secure_link_hmac_expires|$uri|$arg_uid"; + secure_link_hmac_algorithm md5; + + if ($secure_link_hmac = "") { + return 403; + } + if ($secure_link_hmac = "0") { + return 403; + } + } + + location /data/replacements/ { + add_header Cache-Control "private"; + secure_link_hmac $arg_auth,$arg_expires; + secure_link_hmac_secret "DANBOORU_REPLACEMENT_FILE_SECRET GOES HERE"; + secure_link_hmac_message "$secure_link_hmac_expires|$uri|$arg_uid"; + secure_link_hmac_algorithm md5; + + if ($secure_link_hmac = "") { + return 403; + } + if ($secure_link_hmac = "0") { + return 403; + } + } + } +} +