diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env diff --git a/containers/Bastille/Bastille.md b/containers/Bastille/Bastille.md new file mode 100644 index 0000000..9d70d9a --- /dev/null +++ b/containers/Bastille/Bastille.md @@ -0,0 +1,213 @@ +# Bastille + +This is my guide for getting Bastille BSD up-and-running. + +First make sure that FreeBSD is up-to-date: + +*NOTE* This takes a *long* time on a Raspberry PI. Only do this if you have a lot of time on your hands! + +You may be smart to `tmux` first. + +```sh +tmux +``` + +```sh +freebsd-update fetch install +``` + +```sh +reboot +``` + +After reboot, check again: + +```sh +freebsd-update install +``` + +Verify your version: + +```sh +freebsd-version +``` + +## Setup + +First we need to make a backup of `pf.conf`, if you already setup pf before, otherwise you can skip this step. + +```sh +mv /etc/pf.conf /etc/pf.conf.backup +``` + +And then + +```sh +bastille setup +``` + +This will setup the loopback interface and create a `/etc/pf.conf`. + +You need to manually add the following to `/etc/pf.conf`, at the bottom, in order to allow http, https and RDP: + +``` +pass in inet proto tcp from any to any port { 80, 443, 3389 } flags S/SA keep state +``` + +Then start it: + +```sh +service pf start +``` + +The `bastille setup` will try to configure the wrong config file and complain. We need to fix the zfs stuff manually. + +And change, assuming you created a zpool named `data`. + +For example (WATCH OUT, BELOW COMMAND IS DANGEROUS): + +```sh +zpool create -f data /dev/ada0 +``` + +Change bastille.conf + +```sh +nvim /usr/local/etc/bastille/bastille.conf +``` + +``` +bastille_zfs_enable="YES" +bastille_zfs_zpool="data" +``` + +And just in case, run the setup again: + +```sh +bastille setup zfs +``` + +## Start + +Ok, now start Bastille: + +```sh +service bastille restart +``` + +Bootstrap: + +```sh +bastille bootstrap 14.2-RELEASE update +``` + +## Create a container + +Figure out your network card: + +```sh +ifconfig +``` + +You don't want the loopback but your real card that connects to the internet. The KVM virtual machine has `vtnet0` and the Raspberry PI has `genet0`, the Lenovo Thinkcentre has `em0`. + +```sh +# Lenovo Thinkcentre +bastille create alcatraz 14.2-RELEASE 192.168.1.201 em0 +``` + +If you want to have exlusive packages in the jail and not share the host packages, do this: + +```sh +bastille pkg alcatraz bootstrap +bastille pkg alcatraz update +``` + +Alternatively, you can mount the package cache: + +```sh +# Optional +bastille mount alcatraz /var/cache/pkg/ /var/cache/pkg/ nullfs rw 0 0 +``` + +I like to install my favorites since I use them quite often: + +```sh +bastille pkg alcatraz install -y tmux git neovim +``` + +Test it: + +```sh +bastille pkg alcatraz install -y apache24 +bastille sysrc alcatraz apache24_enable=YES +bastille service alcatraz apache24 start +``` + +Now go to the ip address with your browser on another machine: + +http://192.168.1.201/ + +You should see "It works!" + +Alternatively: + +```sh +curl http://192.168.1.201/ +``` + +You should see: + +```html +

It works!

+``` + +Now destroy it: + +```sh +bastille stop alcatraz +bastille destroy force alcatraz +``` + +# Using ports + +```sh +bastille create alcatraz 14.2-RELEASE 192.168.1.201 em0 +bastille pkg alcatraz bootstrap +bastille pkg alcatraz update +bastille pkg alcatraz install -y git +bastille cmd alcatraz git clone --depth 1 https://git.FreeBSD.org/ports.git /usr/ports +``` + +and then go in the console: + +```sh +bastille console alcatraz +``` + +within the console... + +```sh +export BATCH=yes +cd /usr/ports/www/apache24/ && make install clean +exit +``` + +enable and start it ... + +```sh +bastille sysrc alcatraz apache24_enable=YES +bastille service alcatraz apache24 start +``` + +Test it: + +```sh +curl http://192.168.1.201/ +``` + +Destroy it: + +```sh +bastille destroy force alcatraz +``` diff --git a/containers/Bastille/Caddy.md b/containers/Bastille/Caddy.md new file mode 100644 index 0000000..fca7ad8 --- /dev/null +++ b/containers/Bastille/Caddy.md @@ -0,0 +1,42 @@ +# Caddy + +```sh +bastille create caddy 14.2-RELEASE 192.168.1.200 genet0 +bastille pkg caddy bootstrap +bastille pkg caddy update +bastille pkg caddy install -y caddy +``` + +After installing Caddy you see some instructions. To reshow them: + +```sh +bastille pkg caddy info -D caddy +``` + +Edit the Caddyfile: + +```sh +bastille pkg caddy install -y tmux neovim +bastille console caddy +tmux +nvim /usr/local/etc/caddy/Caddyfile +``` + +Start the service. + +```sh +bastille service caddy caddy enable +bastille service caddy caddy start +``` + +See the logs: + +```sh +bastille cmd caddy cat /var/log/caddy/caddy.log +``` + +To quickly look at the caddyfile: + +```sh +bastille cmd caddy cat /usr/local/etc/caddy/Caddyfile +``` \ No newline at end of file diff --git a/containers/Bastille/MariaDB.md b/containers/Bastille/MariaDB.md new file mode 100644 index 0000000..4166b3d --- /dev/null +++ b/containers/Bastille/MariaDB.md @@ -0,0 +1,31 @@ +# MariaDB + +```sh +bastille pkg alcatraz install -y mariadb114-server mariadb114-client +``` + +Repeat the message: + +```sh +bastille pkg alcatraz info -D mariadb114-server +``` + +Enable and start + +```sh +bastille sysrc alcatraz mysql_enable=YES +bastille service alcatraz mysql-server start +``` + +Create nextcloud database and user + +```sh +bastille cmd alcatraz mysql +``` + +```sql +CREATE DATABASE nextcloud; +CREATE USER 'nextcloud'@'192.168.1.201' IDENTIFIED BY '1234sys!'; +GRANT ALL PRIVILEGES ON nextcloud.* TO 'nextcloud'@'192.168.1.201'; +FLUSH PRIVILEGES; +``` diff --git a/containers/Bastille/Nextcloud/Nextcloud.md b/containers/Bastille/Nextcloud/Nextcloud.md new file mode 100644 index 0000000..81586b4 --- /dev/null +++ b/containers/Bastille/Nextcloud/Nextcloud.md @@ -0,0 +1,73 @@ +# Nextcloud + +My standard setup: + +```sh +bastille create alcatraz 14.2-RELEASE 192.168.1.201 em0 +bastille mount alcatraz /var/cache/pkg/ /var/cache/pkg/ nullfs rw 0 0 +bastille pkg alcatraz install -y tmux git neovim sudo +``` + +## Trying it my way + +```sh +bastille pkg alcatraz install -y php83 nextcloud-php83 php83-pecl-APCu php83-extensions sd nginx +``` + +Repeat the message: + +```sh +bastille pkg alcatraz info -D www/nextcloud +``` + +Additional: + +```sh +bastille cmd alcatraz cp /usr/local/etc/php.ini-production /usr/local/etc/php.ini +bastille cmd alcatraz sd 'memory_limit = 128M' 'memory_limit = -1' /usr/local/etc/php.ini +``` + +We need to go in and out of the console for this one: + +```sh +bastille console alcatraz +echo 'apc.enable_cli = 1' >> /usr/local/etc/php.ini +exit +``` + +Follow the instructions for [MariaDB](../MariaDB.md). + +Now run the installer + +```sh +bastille cmd alcatraz sudo -u www php /usr/local/www/nextcloud/occ maintenance:install \ +--database='mysql' --database-host='127.0.0.1' --database-name='nextcloud' \ +--database-user='nextcloud' --database-pass='1234sys!' \ +--admin-user='admin' --admin-pass='1234sys!' +``` + +You should see: + +``` +[alcatraz]: +Nextcloud was successfully installed +[alcatraz]: 0 +``` + +Edit nginx.conf for nextcloud. + +```sh +bastille cmd alcatraz nvim /usr/local/etc/nginx/nginx.conf +``` + +Use [this file](./nginx.conf). + +It's based on: https://docs.nextcloud.com/server/stable/admin_manual/installation/nginx.html#nextcloud-in-the-webroot-of-nginx + + +```sh +bastille service alcatraz php_fpm enable +bastille service alcatraz php_fpm start +bastille service alcatraz nginx enable +bastille service alcatraz nginx start +``` \ No newline at end of file diff --git a/containers/Bastille/Nextcloud/nginx.conf b/containers/Bastille/Nextcloud/nginx.conf new file mode 100644 index 0000000..45971b1 --- /dev/null +++ b/containers/Bastille/Nextcloud/nginx.conf @@ -0,0 +1,265 @@ +#user nobody; +worker_processes 1; + +# This default error log path is compiled-in to make sure configuration parsing +# errors are logged somewhere, especially during unattended boot when stderr +# isn't normally logged anywhere. This path will be touched on every nginx +# start regardless of error log location configured here. See +# https://trac.nginx.org/nginx/ticket/147 for more info. +# +#error_log /var/log/nginx/error.log; +# + +#pid logs/nginx.pid; + +events { + worker_connections 1024; +} + + +http { + include mime.types; + default_type application/octet-stream; + + #log_format main '$remote_addr - $remote_user [$time_local] "$request" ' + # '$status $body_bytes_sent "$http_referer" ' + # '"$http_user_agent" "$http_x_forwarded_for"'; + + #access_log logs/access.log main; + + sendfile on; + #tcp_nopush on; + + #keepalive_timeout 0; + keepalive_timeout 65; + + #gzip on; + + upstream php-handler { + server 127.0.0.1:9000; + #server unix:/var/run/php/php7.4-fpm.sock; + } + + # Set the `immutable` cache control options only for assets with a cache busting `v` argument + map $arg_v $asset_immutable { + "" ""; + default ", immutable"; + } + + # server { + # listen 80; + # listen [::]:80; + # server_name cloud.example.com; + # # enforce https + # return 301 https://$server_name:443$request_uri; + # } + + server { + #listen 80; + #listen [::]:80; + server_name 192.168.1.201; + + # Path to the root of your installation + root /usr/local/www/nextcloud; + + # Use Mozilla's guidelines for SSL/TLS settings + # https://mozilla.github.io/server-side-tls/ssl-config-generator/ + #ssl_certificate /etc/ssl/nginx/cloud.example.com.crt; + #ssl_certificate_key /etc/ssl/nginx/cloud.example.com.key; + + # Prevent nginx HTTP Server Detection + server_tokens off; + + # HSTS settings + # WARNING: Only add the preload option once you read about + # the consequences in https://hstspreload.org/. This option + # will add the domain to a hardcoded list that is shipped + # in all major browsers and getting removed from this list + # could take several months. + #add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always; + + # set max upload size and increase upload timeout: + client_max_body_size 512M; + client_body_timeout 300s; + fastcgi_buffers 64 4K; + + # Enable gzip but do not remove ETag headers + gzip on; + gzip_vary on; + gzip_comp_level 4; + gzip_min_length 256; + gzip_proxied expired no-cache no-store private no_last_modified no_etag auth; + gzip_types application/atom+xml text/javascript application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy; + + # Pagespeed is not supported by Nextcloud, so if your server is built + # with the `ngx_pagespeed` module, uncomment this line to disable it. + #pagespeed off; + + # The settings allows you to optimize the HTTP2 bandwidth. + # See https://blog.cloudflare.com/delivering-http-2-upload-speed-improvements/ + # for tuning hints + client_body_buffer_size 512k; + + # HTTP response headers borrowed from Nextcloud `.htaccess` + add_header Referrer-Policy "no-referrer" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header X-Robots-Tag "noindex, nofollow" always; + add_header X-XSS-Protection "1; mode=block" always; + + # Remove X-Powered-By, which is an information leak + fastcgi_hide_header X-Powered-By; + + # Set .mjs and .wasm MIME types + # Either include it in the default mime.types list + # and include that list explicitly or add the file extension + # only for Nextcloud like below: + include mime.types; + types { + text/javascript mjs; + application/wasm wasm; + } + + # Specify how to handle directories -- specifying `/index.php$request_uri` + # here as the fallback means that Nginx always exhibits the desired behaviour + # when a client requests a path that corresponds to a directory that exists + # on the server. In particular, if that directory contains an index.php file, + # that file is correctly served; if it doesn't, then the request is passed to + # the front-end controller. This consistent behaviour means that we don't need + # to specify custom rules for certain paths (e.g. images and other assets, + # `/updater`, `/ocs-provider`), and thus + # `try_files $uri $uri/ /index.php$request_uri` + # always provides the desired behaviour. + index index.php index.html /index.php$request_uri; + + # Rule borrowed from `.htaccess` to handle Microsoft DAV clients + location = / { + if ( $http_user_agent ~ ^DavClnt ) { + return 302 /remote.php/webdav/$is_args$args; + } + } + + location = /robots.txt { + allow all; + log_not_found off; + access_log off; + } + + # Make a regex exception for `/.well-known` so that clients can still + # access it despite the existence of the regex rule + # `location ~ /(\.|autotest|...)` which would otherwise handle requests + # for `/.well-known`. + location ^~ /.well-known { + # The rules in this block are an adaptation of the rules + # in `.htaccess` that concern `/.well-known`. + + location = /.well-known/carddav { return 301 /remote.php/dav/; } + location = /.well-known/caldav { return 301 /remote.php/dav/; } + + location /.well-known/acme-challenge { try_files $uri $uri/ =404; } + location /.well-known/pki-validation { try_files $uri $uri/ =404; } + + # Let Nextcloud's API for `/.well-known` URIs handle all other + # requests by passing them to the front-end controller. + return 301 /index.php$request_uri; + } + + # Rules borrowed from `.htaccess` to hide certain paths from clients + location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/) { return 404; } + location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console) { return 404; } + + # Ensure this block, which passes PHP files to the PHP process, is above the blocks + # which handle static assets (as seen below). If this block is not declared first, + # then Nginx will encounter an infinite rewriting loop when it prepends `/index.php` + # to the URI, resulting in a HTTP 500 error response. + location ~ \.php(?:$|/) { + # Required for legacy support + rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|ocs-provider\/.+|.+\/richdocumentscode(_arm64)?\/proxy) /index.php$request_uri; + + fastcgi_split_path_info ^(.+?\.php)(/.*)$; + set $path_info $fastcgi_path_info; + + try_files $fastcgi_script_name =404; + + include fastcgi_params; + fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; + fastcgi_param PATH_INFO $path_info; + fastcgi_param HTTPS on; + + fastcgi_param modHeadersAvailable true; # Avoid sending the security headers twice + fastcgi_param front_controller_active true; # Enable pretty urls + fastcgi_pass php-handler; + + fastcgi_intercept_errors on; + fastcgi_request_buffering off; + + fastcgi_max_temp_file_size 0; + } + + # Serve static files + location ~ \.(?:css|js|mjs|svg|gif|ico|jpg|png|webp|wasm|tflite|map|ogg|flac)$ { + try_files $uri /index.php$request_uri; + # HTTP response headers borrowed from Nextcloud `.htaccess` + add_header Cache-Control "public, max-age=15778463$asset_immutable"; + add_header Referrer-Policy "no-referrer" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Permitted-Cross-Domain-Policies "none" always; + add_header X-Robots-Tag "noindex, nofollow" always; + add_header X-XSS-Protection "1; mode=block" always; + access_log off; # Optional: Don't log access to assets + } + + location ~ \.(otf|woff2?)$ { + try_files $uri /index.php$request_uri; + expires 7d; # Cache-Control policy borrowed from `.htaccess` + access_log off; # Optional: Don't log access to assets + } + + # Rule borrowed from `.htaccess` + location /remote { + return 301 /remote.php$request_uri; + } + + location / { + try_files $uri $uri/ /index.php$request_uri; + } + } + + # another virtual host using mix of IP-, name-, and port-based configuration + # + #server { + # listen 8000; + # listen somename:8080; + # server_name somename alias another.alias; + + # location / { + # root html; + # index index.html index.htm; + # } + #} + + + # HTTPS server + # + #server { + # listen 443 ssl; + # server_name localhost; + + # ssl_certificate cert.pem; + # ssl_certificate_key cert.key; + + # ssl_session_cache shared:SSL:1m; + # ssl_session_timeout 5m; + + # ssl_ciphers HIGH:!aNULL:!MD5; + # ssl_prefer_server_ciphers on; + + # location / { + # root html; + # index index.html index.htm; + # } + #} + +} diff --git a/containers/Bastille/Postgres.md b/containers/Bastille/Postgres.md new file mode 100644 index 0000000..ddd64c6 --- /dev/null +++ b/containers/Bastille/Postgres.md @@ -0,0 +1,54 @@ +# Postgres + +```sh +bastille create postgresql 14.2-RELEASE 192.168.1.203 em0 +bastille config postgresql set allow.sysvipc=1 +bastille restart postgresql +bastille pkg postgresql bootstrap +bastille pkg postgresql update +bastille pkg postgresql install -y postgresql15-server postgresql15-client +bastille service postgresql postgresql enable +bastille service postgresql postgresql initdb +bastille service postgresql postgresql start +``` + +You need to change `/var/db/postgres/data15/postgresql.conf` + +```sh +nvim /var/db/postgres/data15/postgresql.conf +``` + +To listen to the ip address: + +``` +listen_addresses = '192.168.1.203' +``` + +And restart. + +We need to allow communications via the jails. Add this to pf.conf on the host: + +``` +pass in on $ext_if proto tcp from 192.168.1.202 to 192.168.1.203 port 5432 +pass out on $ext_if proto tcp from 192.168.1.203 to 192.168.1.202 port 5432 +``` + +Add a user, for example nextcloud: + +```sh +su - postgres +createuser nextcloud +createdb nextcloud -O admin +psql nextcloud +alter role nextcloud with encrypted password 'yourpassword'; +grant all privileges on database nextcloud to nextcloud; +exit +exit +``` + +Add this to `/var/db/postgres/data15/pg_hba.conf` + +``` +host nextcloud nextcloud 0.0.0.0/0 scram-sha-256 +host nextcloud nextcloud ::/0 scram-sha-256 +``` diff --git a/containers/Bastille/nginx.md b/containers/Bastille/nginx.md new file mode 100644 index 0000000..a6f75e8 --- /dev/null +++ b/containers/Bastille/nginx.md @@ -0,0 +1,10 @@ +# nginx + +```sh +bastille create nginx 14.2-RELEASE 192.168.1.200 genet0 +bastille pkg nginx bootstrap +bastille pkg nginx update +bastille pkg nginx install -y nginx +bastille service nginx nginx enable +bastille service nginx nginx start +``` diff --git a/containers/docker/audiobookshelf/compose.yaml b/containers/docker/audiobookshelf/compose.yaml new file mode 100644 index 0000000..c99d15a --- /dev/null +++ b/containers/docker/audiobookshelf/compose.yaml @@ -0,0 +1,13 @@ +services: + audiobookshelf: + image: ghcr.io/advplyr/audiobookshelf:latest + # user: 1004:1004 + ports: + - 13378:80 + volumes: + - /home/audiobookshelf/audiobookshelf/audiobooks:/audiobooks + - /home/audiobookshelf/audiobookshelf/podcasts:/podcasts + - /home/audiobookshelf/audiobookshelf/config:/config + - /home/audiobookshelf/audiobookshelf/metadata:/metadata + environment: + - TZ=Europe/Amsterdam diff --git a/containers/docker/httpd/compose.yaml b/containers/docker/httpd/compose.yaml new file mode 100644 index 0000000..9da83c0 --- /dev/null +++ b/containers/docker/httpd/compose.yaml @@ -0,0 +1,9 @@ +services: + + httpd: + image: httpd + restart: always + ports: + - 8081:80 + # volumes: + # - ./www:/usr/local/apache2/htdocs diff --git a/containers/docker/httpd/www/index.html b/containers/docker/httpd/www/index.html new file mode 100644 index 0000000..7f7697a --- /dev/null +++ b/containers/docker/httpd/www/index.html @@ -0,0 +1,8 @@ + + + Hello world! + + +

Hello world!

+ + \ No newline at end of file diff --git a/containers/docker/immich/compose.yaml b/containers/docker/immich/compose.yaml new file mode 100644 index 0000000..f16611f --- /dev/null +++ b/containers/docker/immich/compose.yaml @@ -0,0 +1,84 @@ +# You need to get the example .env file: +# wget -O .env https://github.com/immich-app/immich/releases/latest/download/example.env + +name: immich + +services: + immich-server: + container_name: immich_server + image: ghcr.io/immich-app/immich-server:${IMMICH_VERSION:-release} + extends: + file: hwaccel.transcoding.yml + service: quicksync # set to one of [nvenc, quicksync, rkmpp, vaapi, vaapi-wsl] for accelerated transcoding + volumes: + # Do not edit the next line. If you want to change the media storage location on your system, edit the value of UPLOAD_LOCATION in the .env file + - ${UPLOAD_LOCATION}:/usr/src/app/upload + - /etc/localtime:/etc/localtime:ro + - /home/immich/external/:/external + env_file: + - .env + ports: + - '2283:2283' + depends_on: + - redis + - database + restart: always + healthcheck: + disable: false + + immich-machine-learning: + container_name: immich_machine_learning + # For hardware acceleration, add one of -[armnn, cuda, openvino] to the image tag. + # Example tag: ${IMMICH_VERSION:-release}-cuda + image: ghcr.io/immich-app/immich-machine-learning:${IMMICH_VERSION:-release} + # extends: # uncomment this section for hardware acceleration - see https://immich.app/docs/features/ml-hardware-acceleration + # file: hwaccel.ml.yml + # service: cpu # set to one of [armnn, cuda, openvino, openvino-wsl] for accelerated inference - use the `-wsl` version for WSL2 where applicable + volumes: + - model-cache:/cache + env_file: + - .env + restart: always + healthcheck: + disable: false + + redis: + container_name: immich_redis + image: docker.io/redis:6.2-alpine@sha256:eaba718fecd1196d88533de7ba49bf903ad33664a92debb24660a922ecd9cac8 + healthcheck: + test: redis-cli ping || exit 1 + restart: always + + database: + container_name: immich_postgres + image: docker.io/tensorchord/pgvecto-rs:pg14-v0.2.0@sha256:90724186f0a3517cf6914295b5ab410db9ce23190a2d9d0b9dd6463e3fa298f0 + environment: + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_USER: ${DB_USERNAME} + POSTGRES_DB: ${DB_DATABASE_NAME} + POSTGRES_INITDB_ARGS: '--data-checksums' + volumes: + # Do not edit the next line. If you want to change the database storage location on your system, edit the value of DB_DATA_LOCATION in the .env file + - ${DB_DATA_LOCATION}:/var/lib/postgresql/data + healthcheck: + test: >- + pg_isready --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" || exit 1; + Chksum="$$(psql --dbname="$${POSTGRES_DB}" --username="$${POSTGRES_USER}" --tuples-only --no-align + --command='SELECT COALESCE(SUM(checksum_failures), 0) FROM pg_stat_database')"; + echo "checksum failure count is $$Chksum"; + [ "$$Chksum" = '0' ] || exit 1 + interval: 5m + start_interval: 30s + start_period: 5m + command: >- + postgres + -c shared_preload_libraries=vectors.so + -c 'search_path="$$user", public, vectors' + -c logging_collector=on + -c max_wal_size=2GB + -c shared_buffers=512MB + -c wal_compression=on + restart: always + +volumes: + model-cache: diff --git a/containers/docker/immich/hwaccel.transcoding.yml b/containers/docker/immich/hwaccel.transcoding.yml new file mode 100644 index 0000000..33fb7b3 --- /dev/null +++ b/containers/docker/immich/hwaccel.transcoding.yml @@ -0,0 +1,54 @@ +# Configurations for hardware-accelerated transcoding + +# If using Unraid or another platform that doesn't allow multiple Compose files, +# you can inline the config for a backend by copying its contents +# into the immich-microservices service in the docker-compose.yml file. + +# See https://immich.app/docs/features/hardware-transcoding for more info on using hardware transcoding. + +services: + cpu: {} + + nvenc: + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: + - gpu + - compute + - video + + quicksync: + devices: + - /dev/dri:/dev/dri + + rkmpp: + security_opt: # enables full access to /sys and /proc, still far better than privileged: true + - systempaths=unconfined + - apparmor=unconfined + group_add: + - video + devices: + - /dev/rga:/dev/rga + - /dev/dri:/dev/dri + - /dev/dma_heap:/dev/dma_heap + - /dev/mpp_service:/dev/mpp_service + #- /dev/mali0:/dev/mali0 # only required to enable OpenCL-accelerated HDR -> SDR tonemapping + volumes: + #- /etc/OpenCL:/etc/OpenCL:ro # only required to enable OpenCL-accelerated HDR -> SDR tonemapping + #- /usr/lib/aarch64-linux-gnu/libmali.so.1:/usr/lib/aarch64-linux-gnu/libmali.so.1:ro # only required to enable OpenCL-accelerated HDR -> SDR tonemapping + + vaapi: + devices: + - /dev/dri:/dev/dri + + vaapi-wsl: # use this for VAAPI if you're running Immich in WSL2 + devices: + - /dev/dri:/dev/dri + volumes: + - /usr/lib/wsl:/usr/lib/wsl + environment: + - LIBVA_DRIVER_NAME=d3d12 diff --git a/containers/docker/jellyfin/compose.yaml b/containers/docker/jellyfin/compose.yaml new file mode 100644 index 0000000..25a3691 --- /dev/null +++ b/containers/docker/jellyfin/compose.yaml @@ -0,0 +1,30 @@ +services: + jellyfin: + image: jellyfin/jellyfin + container_name: jellyfin + user: 1003:1003 + network_mode: 'host' + volumes: + - /home/jellyfin/jellyfin/config:/config + - /home/jellyfin/jellyfin/cache:/cache + - type: bind + source: /home/jellyfin/jellyfin/media + target: /media + # - type: bind + # source: /path/to/media2 + # target: /media2 + # read_only: true + # Optional - extra fonts to be used during transcoding with subtitle burn-in + # - type: bind + # source: /path/to/fonts + # target: /usr/local/share/fonts/custom + # read_only: true + restart: 'unless-stopped' + # Optional - alternative address used for autodiscovery + # environment: + # - JELLYFIN_PublishedServerUrl=http://example.com + # Optional - may be necessary for docker healthcheck to pass if running in host network mode + # extra_hosts: + # - 'host.docker.internal:host-gateway' + devices: + - "/dev/dri:/dev/dri" # Intel QSV \ No newline at end of file diff --git a/containers/docker/multitenant/.gitignore b/containers/docker/multitenant/.gitignore new file mode 100644 index 0000000..293d9b7 --- /dev/null +++ b/containers/docker/multitenant/.gitignore @@ -0,0 +1,3 @@ +infra/nginx-proxy-manager_data/ +infra/portainer_data/ +lemmy/volumes/ diff --git a/containers/docker/multitenant/README.md b/containers/docker/multitenant/README.md new file mode 100644 index 0000000..3f7020e --- /dev/null +++ b/containers/docker/multitenant/README.md @@ -0,0 +1,55 @@ +# multitenant + +## nginx-proxy-manager + +```sh +docker network create infra +``` + +Admin: http://127.0.0.1:81/ + +``` +admin@example.com +changeme +``` + +## Wordpress + +We need to add domain names in our `/etc/hosts` file: + +``` +127.0.0.1 moni0.codecompost.nl +127.0.0.1 moni1.codecompost.nl +``` + +And pass a project name to the docker-compose command: + +``` +docker-compose -p moni0 up --build --force-recreate -d +``` + +This will prepend `moni0_` to the containers (and add a `_1` apparently) + +``` +Creating network "moni0_internal_network" with the default driver +Creating volume "moni0_wordpress" with default driver +Creating volume "moni0_db" with default driver +Creating moni0_db_1 ... done +Creating moni0_wordpress_1 ... done +``` + +In the Nginx Proxy Manager, we can add the proxy host: + +![moni0 wordpress proxy host](moni0_proxy_host.png) + +We can go ahead and start a second wordpress with: + +``` +docker-compose -p moni1 up --build --force-recreate -d +``` + +And then you can configure it like this: + +![Alt text](moni1_proxy_host.png) + +Make sure that `moni1.codecompost.nl` is also in your hosts file, otherwise it won't work! \ No newline at end of file diff --git a/containers/docker/multitenant/infra/docker-compose.yml b/containers/docker/multitenant/infra/docker-compose.yml new file mode 100644 index 0000000..040df87 --- /dev/null +++ b/containers/docker/multitenant/infra/docker-compose.yml @@ -0,0 +1,31 @@ +version: '3.8' +services: + + nginx-proxy-manager: + image: 'jc21/nginx-proxy-manager:latest' + restart: unless-stopped + ports: + - '80:80' + - '81:81' + - '443:443' + volumes: + - ./nginx-proxy-manager_data/data:/data + - ./nginx-proxy-manager_data/letsencrypt:/etc/letsencrypt + networks: + - infra + +# portainer: +# image: 'portainer/portainer-ce:latest' +# restart: always +# ports: +# - '8000:8000' +# - '9443:9443' +# volumes: +# - /var/run/docker.sock:/var/run/docker.sock +# - ./portainer_data:/data +# networks: +# - infra + +networks: + infra: + external: true diff --git a/containers/docker/multitenant/jellyfin/run_with_podman.sh b/containers/docker/multitenant/jellyfin/run_with_podman.sh new file mode 100755 index 0000000..d521033 --- /dev/null +++ b/containers/docker/multitenant/jellyfin/run_with_podman.sh @@ -0,0 +1,12 @@ +podman run \ + --detach \ + --label "io.containers.autoupdate=registry" \ + --name jellyfin \ + --publish 8096:8096/tcp \ + --rm \ + --user $(id -u):$(id -g) \ + --userns keep-id \ + --volume jellyfin-cache:/cache:Z \ + --volume jellyfin-config:/config:Z \ + --mount type=bind,source=/home/moni/media/,destination=/media,ro=true,relabel=private \ + docker.io/jellyfin/jellyfin:latest \ No newline at end of file diff --git a/containers/docker/multitenant/lemmy/customPostgresql.conf b/containers/docker/multitenant/lemmy/customPostgresql.conf new file mode 100644 index 0000000..49428e4 --- /dev/null +++ b/containers/docker/multitenant/lemmy/customPostgresql.conf @@ -0,0 +1,30 @@ +# DB Version: 15 +# OS Type: linux +# DB Type: web +# Total Memory (RAM): 8 GB +# CPUs num: 4 +# Data Storage: ssd + +max_connections = 200 +shared_buffers = 2GB +effective_cache_size = 6GB +maintenance_work_mem = 512MB +checkpoint_completion_target = 0.9 +checkpoint_timeout = 86400 +wal_buffers = 16MB +default_statistics_target = 100 +random_page_cost = 1.1 +effective_io_concurrency = 200 +work_mem = 5242kB +min_wal_size = 1GB +max_wal_size = 30GB +max_worker_processes = 4 +max_parallel_workers_per_gather = 2 +max_parallel_workers = 4 +max_parallel_maintenance_workers = 2 + +# Other custom params +temp_file_size=1GB +synchronous_commit=off +# This one shouldn't be on regularly, because DB migrations often take a long time +# statement_timeout = 10000 diff --git a/containers/docker/multitenant/lemmy/docker-compose.yml b/containers/docker/multitenant/lemmy/docker-compose.yml new file mode 100644 index 0000000..b6b2f62 --- /dev/null +++ b/containers/docker/multitenant/lemmy/docker-compose.yml @@ -0,0 +1,114 @@ +version: "3.7" + +x-logging: &default-logging + driver: "json-file" + options: + max-size: "50m" + max-file: "4" + +services: + proxy: + image: nginx:1-alpine + # ports: + # # actual and only port facing any connection from outside + # # Note, change the left number if port 1236 is already in use on your system + # # You could use port 80 if you won't use a reverse proxy + # - "1236:8536" + volumes: + - ./nginx_internal.conf:/etc/nginx/nginx.conf:ro,Z + restart: always + logging: *default-logging + depends_on: + - pictrs + - lemmy-ui + networks: + - lemmy-internal + - infra + + lemmy: + image: dessalines/lemmy:latest + hostname: lemmy + restart: always + logging: *default-logging + environment: + - RUST_LOG="warn" + - LEMMY_CORS_ORIGIN=http://lemmy.codecompost.nl + volumes: + - ./lemmy.hjson:/config/config.hjson:Z + depends_on: + - postgres + - pictrs + networks: + - lemmy-internal + + lemmy-ui: + image: dessalines/lemmy-ui:latest + environment: + - LEMMY_UI_LEMMY_INTERNAL_HOST=lemmy:8536 + - LEMMY_UI_LEMMY_EXTERNAL_HOST=lemmy.codecompost.nl + - LEMMY_UI_HTTPS=true + volumes: + - ./volumes/lemmy-ui/extra_themes:/app/extra_themes + depends_on: + - lemmy + restart: always + logging: *default-logging + networks: + - lemmy-internal + + pictrs: + image: asonix/pictrs:0.4.0-rc.7 + # this needs to match the pictrs url in lemmy.hjson + hostname: pictrs + # we can set options to pictrs like this, here we set max. image size and forced format for conversion + # entrypoint: /sbin/tini -- /usr/local/bin/pict-rs -p /mnt -m 4 --image-format webp + environment: + - PICTRS_OPENTELEMETRY_URL=http://otel:4137 + - PICTRS__API_KEY=JmT3cMDL252EJw + - RUST_LOG=debug + - RUST_BACKTRACE=full + - PICTRS__MEDIA__VIDEO_CODEC=vp9 + - PICTRS__MEDIA__GIF__MAX_WIDTH=256 + - PICTRS__MEDIA__GIF__MAX_HEIGHT=256 + - PICTRS__MEDIA__GIF__MAX_AREA=65536 + - PICTRS__MEDIA__GIF__MAX_FRAME_COUNT=400 + user: 991:991 + volumes: + - ./volumes/pictrs:/mnt:Z + restart: always + logging: *default-logging + deploy: + resources: + limits: + memory: 690m + networks: + - lemmy-internal + + postgres: + image: postgres:15-alpine + hostname: postgres + environment: + - POSTGRES_USER=lemmy + - POSTGRES_PASSWORD=JmT3cMDL252EJw + - POSTGRES_DB=lemmy + volumes: + - ./volumes/postgres:/var/lib/postgresql/data:Z + - ./customPostgresql.conf:/etc/postgresql.conf + restart: always + logging: *default-logging + networks: + - lemmy-internal + + postfix: + image: mwader/postfix-relay + environment: + - POSTFIX_myhostname=codecompost.nl + restart: "always" + logging: *default-logging + networks: + - lemmy-internal + +networks: + lemmy-internal: + infra: + external: true \ No newline at end of file diff --git a/containers/docker/multitenant/lemmy/lemmy.hjson b/containers/docker/multitenant/lemmy/lemmy.hjson new file mode 100644 index 0000000..a27c04e --- /dev/null +++ b/containers/docker/multitenant/lemmy/lemmy.hjson @@ -0,0 +1,19 @@ +{ + # for more info about the config, check out the documentation + # https://join-lemmy.org/docs/en/administration/configuration.html + + database: { + host: postgres + password: "JmT3cMDL252EJw" + } + hostname: "lemmy.codecompost.nl" + pictrs: { + url: "http://pictrs:8080/" + api_key: "JmT3cMDL252EJw" + } + email: { + smtp_server: "postfix:25" + smtp_from_address: "noreply@codecompost.nl" + tls_type: "none" + } +} diff --git a/containers/docker/multitenant/lemmy/nginx_internal.conf b/containers/docker/multitenant/lemmy/nginx_internal.conf new file mode 100644 index 0000000..cffc77b --- /dev/null +++ b/containers/docker/multitenant/lemmy/nginx_internal.conf @@ -0,0 +1,96 @@ +worker_processes auto; + +events { + worker_connections 1024; +} + +http { + # We construct a string consistent of the "request method" and "http accept header" + # and then apply soem ~simply regexp matches to that combination to decide on the + # HTTP upstream we should proxy the request to. + # + # Example strings: + # + # "GET:application/activity+json" + # "GET:text/html" + # "POST:application/activity+json" + # + # You can see some basic match tests in this regex101 matching this configuration + # https://regex101.com/r/vwMJNc/1 + # + # Learn more about nginx maps here http://nginx.org/en/docs/http/ngx_http_map_module.html + map "$request_method:$http_accept" $proxpass { + # If no explicit matches exists below, send traffic to lemmy-ui + default "http://lemmy-ui"; + + # GET/HEAD requests that accepts ActivityPub or Linked Data JSON should go to lemmy. + # + # These requests are used by Mastodon and other fediverse instances to look up profile information, + # discover site information and so on. + "~^(?:GET|HEAD):.*?application\/(?:activity|ld)\+json" "http://lemmy"; + + # All non-GET/HEAD requests should go to lemmy + # + # Rather than calling out POST, PUT, DELETE, PATCH, CONNECT and all the verbs manually + # we simply negate the GET|HEAD pattern from above and accept all possibly $http_accept values + "~^(?!(GET|HEAD)).*:" "http://lemmy"; + } + + upstream lemmy { + # this needs to map to the lemmy (server) docker service hostname + server "lemmy:8536"; + } + + upstream lemmy-ui { + # this needs to map to the lemmy-ui docker service hostname + server "lemmy-ui:1234"; + } + + server { + # this is the port inside docker, not the public one yet + listen 1236; + listen 8536; + + # change if needed, this is facing the public web + server_name localhost; + server_tokens off; + + gzip on; + gzip_types text/css application/javascript image/svg+xml; + gzip_vary on; + + # Upload limit, relevant for pictrs + client_max_body_size 20M; + + add_header X-Frame-Options SAMEORIGIN; + add_header X-Content-Type-Options nosniff; + add_header X-XSS-Protection "1; mode=block"; + + # frontend general requests + location / { + proxy_pass $proxpass; + + rewrite ^(.+)/+$ $1 permanent; + + # Send actual client IP upstream + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + # backend + location ~ ^/(api|pictrs|feeds|nodeinfo|.well-known) { + proxy_pass "http://lemmy"; + + # proxy common stuff + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + + # Send actual client IP upstream + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + } +} diff --git a/containers/docker/multitenant/mastodon/.env.production b/containers/docker/multitenant/mastodon/.env.production new file mode 100644 index 0000000..93a732c --- /dev/null +++ b/containers/docker/multitenant/mastodon/.env.production @@ -0,0 +1,28 @@ +# Generated with mastodon:setup on 2023-07-06 02:48:24 UTC + +# Some variables in this file will be interpreted differently whether you are +# using docker-compose or not. + +LOCAL_DOMAIN=mastodon.codecompost.nl +SINGLE_USER_MODE=true +SECRET_KEY_BASE=2f845c9336267ad5ddf79ca900d3940990c0a8010c7c3a5321d5cda8e5b9ac32ebcc75ea67396977bb65c7c970f71d123312cd180c6a1e7b12e608eee3d63e27 +OTP_SECRET=e8c4370e30704c85552fd48d766c859323ebd28aaaffa8a9943687b2ac925610eeba1bc9b3a472ae1b684862e7d02ea7d5b69a02624d395626b0cd9fef4aeb2c +VAPID_PRIVATE_KEY=fHCAaeeQ_HxQBKvw9jzVrTxO9mpoup46luhPmKZsRhI= +VAPID_PUBLIC_KEY=BKkmTVZwiL4hmqYt91AsWvB4DS38MnFygDumi9jCqjSw3IClXA5WhxCQnYSpGzOKvvrN-Lgy4Fm2Rx5CPhmelS0= +DB_HOST=moni-mastodon-db-1 +DB_PORT=5432 +DB_NAME=mastodon +DB_USER=mastodon +DB_PASS=mastodon +REDIS_HOST=moni-mastodon-redis-1 +REDIS_PORT=6379 +REDIS_PASSWORD= +SMTP_SERVER=smtp.mailgun.org +SMTP_PORT=587 +SMTP_LOGIN= +SMTP_PASSWORD= +SMTP_AUTH_METHOD=plain +SMTP_OPENSSL_VERIFY_MODE=none +SMTP_ENABLE_STARTTLS=auto +SMTP_FROM_ADDRESS=Mastodon +LOCAL_HTTPS=false diff --git a/containers/docker/multitenant/mastodon/docker-compose.yml b/containers/docker/multitenant/mastodon/docker-compose.yml new file mode 100644 index 0000000..a3916ba --- /dev/null +++ b/containers/docker/multitenant/mastodon/docker-compose.yml @@ -0,0 +1,137 @@ +version: '3' +services: + db: + restart: always + image: postgres:14-alpine + shm_size: 256mb + networks: + - internal_network + healthcheck: + test: ['CMD', 'pg_isready', '-U', 'postgres'] + volumes: + - postgres14:/var/lib/postgresql/data + environment: + - POSTGRES_USER=mastodon + - POSTGRES_PASSWORD=mastodon + + redis: + restart: always + image: redis:7-alpine + networks: + - internal_network + healthcheck: + test: ['CMD', 'redis-cli', 'ping'] + volumes: + - redis:/data + + # es: + # restart: always + # image: docker.elastic.co/elasticsearch/elasticsearch:7.17.4 + # environment: + # - "ES_JAVA_OPTS=-Xms512m -Xmx512m -Des.enforce.bootstrap.checks=true" + # - "xpack.license.self_generated.type=basic" + # - "xpack.security.enabled=false" + # - "xpack.watcher.enabled=false" + # - "xpack.graph.enabled=false" + # - "xpack.ml.enabled=false" + # - "bootstrap.memory_lock=true" + # - "cluster.name=es-mastodon" + # - "discovery.type=single-node" + # - "thread_pool.write.queue_size=1000" + # networks: + # - infra + # - internal_network + # healthcheck: + # test: ["CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1"] + # volumes: + # - ./elasticsearch:/usr/share/elasticsearch/data + # ulimits: + # memlock: + # soft: -1 + # hard: -1 + # nofile: + # soft: 65536 + # hard: 65536 + # ports: + # - '127.0.0.1:9200:9200' + + web: + image: ghcr.io/mastodon/mastodon + restart: always + env_file: .env.production + command: bash -c "rm -f /mastodon/tmp/pids/server.pid; bundle exec rails s -p 3000" + networks: + - infra + - internal_network + healthcheck: + # prettier-ignore + test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:3000/health || exit 1'] + # ports: + # - '127.0.0.1:3000:3000' + depends_on: + - db + - redis + # - es + volumes: + - public_system:/mastodon/public/system + + streaming: + image: ghcr.io/mastodon/mastodon + restart: always + env_file: .env.production + command: node ./streaming + networks: + - infra + - internal_network + healthcheck: + # prettier-ignore + test: ['CMD-SHELL', 'wget -q --spider --proxy=off localhost:4000/api/v1/streaming/health || exit 1'] + # ports: + # - '127.0.0.1:4000:4000' + depends_on: + - db + - redis + + sidekiq: + image: ghcr.io/mastodon/mastodon + restart: always + env_file: .env.production + command: bundle exec sidekiq + depends_on: + - db + - redis + networks: + - infra + - internal_network + volumes: + - public_system:/mastodon/public/system + healthcheck: + test: ['CMD-SHELL', "ps aux | grep '[s]idekiq\ 6' || false"] + + ## Uncomment to enable federation with tor instances along with adding the following ENV variables + ## http_proxy=http://privoxy:8118 + ## ALLOW_ACCESS_TO_HIDDEN_SERVICE=true + # tor: + # image: sirboops/tor + # networks: + # - infra + # - internal_network + # + # privoxy: + # image: sirboops/privoxy + # volumes: + # - ./priv-config:/opt/config + # networks: + # - infra + # - internal_network + +networks: + infra: + external: true + internal_network: + + +volumes: + postgres14: + redis: + public_system: diff --git a/containers/docker/multitenant/moni0_proxy_host.png b/containers/docker/multitenant/moni0_proxy_host.png new file mode 100644 index 0000000..94903a1 Binary files /dev/null and b/containers/docker/multitenant/moni0_proxy_host.png differ diff --git a/containers/docker/multitenant/moni1_proxy_host.png b/containers/docker/multitenant/moni1_proxy_host.png new file mode 100644 index 0000000..7b4e7fd Binary files /dev/null and b/containers/docker/multitenant/moni1_proxy_host.png differ diff --git a/containers/docker/multitenant/nextcloud/REAME.md b/containers/docker/multitenant/nextcloud/REAME.md new file mode 100644 index 0000000..0e87b2c --- /dev/null +++ b/containers/docker/multitenant/nextcloud/REAME.md @@ -0,0 +1,2 @@ +https://github.com/nextcloud/all-in-one + diff --git a/containers/docker/multitenant/nextcloud/docker-compose.yml b/containers/docker/multitenant/nextcloud/docker-compose.yml new file mode 100644 index 0000000..e54a64c --- /dev/null +++ b/containers/docker/multitenant/nextcloud/docker-compose.yml @@ -0,0 +1,17 @@ +services: + nextcloud-aio-mastercontainer: + image: nextcloud/all-in-one:latest + init: true + restart: always + container_name: nextcloud-aio-mastercontainer # This line is not allowed to be changed as otherwise AIO will not work correctly + volumes: + - nextcloud_aio_mastercontainer:/mnt/docker-aio-config # This line is not allowed to be changed as otherwise the built-in backup solution will not work + - /var/run/docker.sock:/var/run/docker.sock:ro # May be changed on macOS, Windows or docker rootless. See the applicable documentation. If adjusting, don't forget to also set 'WATCHTOWER_DOCKER_SOCKET_PATH'! + ports: + - 80:80 # Can be removed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md + - 8080:8080 + - 8443:8443 + +volumes: # If you want to store the data on a different drive, see https://github.com/nextcloud/all-in-one#how-to-store-the-filesinstallation-on-a-separate-drive + nextcloud_aio_mastercontainer: + name: nextcloud_aio_mastercontainer # This line is not allowed to be changed as otherwise the built-in backup solution will not work diff --git a/containers/docker/multitenant/sites/moni8080/docker-compose.yml b/containers/docker/multitenant/sites/moni8080/docker-compose.yml new file mode 100644 index 0000000..4ccf31d --- /dev/null +++ b/containers/docker/multitenant/sites/moni8080/docker-compose.yml @@ -0,0 +1,12 @@ +version: '2' +services: + moni8080: + image: httpd + networks: + - npm + volumes: + - /home/moni/sites/moni8080:/usr/local/apache2/htdocs/ + +networks: + npm: + external: true \ No newline at end of file diff --git a/containers/docker/multitenant/sites/moni8080/index.html b/containers/docker/multitenant/sites/moni8080/index.html new file mode 100644 index 0000000..c04ca89 --- /dev/null +++ b/containers/docker/multitenant/sites/moni8080/index.html @@ -0,0 +1,8 @@ + + + Moni 8080 + + + This is MONI 8080 + + \ No newline at end of file diff --git a/containers/docker/multitenant/sites/moni8081/docker-compose.yml b/containers/docker/multitenant/sites/moni8081/docker-compose.yml new file mode 100644 index 0000000..4692c06 --- /dev/null +++ b/containers/docker/multitenant/sites/moni8081/docker-compose.yml @@ -0,0 +1,12 @@ +version: '2' +services: + moni8081: + image: httpd + networks: + - npm + volumes: + - /home/moni/sites/moni8081:/usr/local/apache2/htdocs/ + +networks: + npm: + external: true \ No newline at end of file diff --git a/containers/docker/multitenant/sites/moni8081/index.html b/containers/docker/multitenant/sites/moni8081/index.html new file mode 100644 index 0000000..aa79650 --- /dev/null +++ b/containers/docker/multitenant/sites/moni8081/index.html @@ -0,0 +1,8 @@ + + + Moni 8081 + + + This is MONI 8081 + + \ No newline at end of file diff --git a/containers/docker/multitenant/sites/moni8082/index.html b/containers/docker/multitenant/sites/moni8082/index.html new file mode 100644 index 0000000..7efe804 --- /dev/null +++ b/containers/docker/multitenant/sites/moni8082/index.html @@ -0,0 +1,8 @@ + + + Moni 8082 + + + This is MONI 8082 + + \ No newline at end of file diff --git a/containers/docker/multitenant/wordpress/Dockerfile b/containers/docker/multitenant/wordpress/Dockerfile new file mode 100644 index 0000000..3fe8b2d --- /dev/null +++ b/containers/docker/multitenant/wordpress/Dockerfile @@ -0,0 +1,7 @@ +# Not the latest version to be able to test updates +FROM wordpress:6.0.0 +WORKDIR /usr/src/wordpress +RUN set -eux; \ + find /etc/apache2 -name '*.conf' -type f -exec sed -ri -e "s!/var/www/html!$PWD!g" -e "s!Directory /var/www/!Directory $PWD!g" '{}' +; \ + cp -s wp-config-docker.php wp-config.php +RUN echo "define('FS_METHOD','direct');" >> wp-config.php \ No newline at end of file diff --git a/containers/docker/multitenant/wordpress/docker-compose.yml b/containers/docker/multitenant/wordpress/docker-compose.yml new file mode 100644 index 0000000..ab9c4fe --- /dev/null +++ b/containers/docker/multitenant/wordpress/docker-compose.yml @@ -0,0 +1,43 @@ +version: '3.1' + +services: + + wordpress: + image: wordpress + restart: always + # ports: + # - 8080:80 + depends_on: + - db + environment: + WORDPRESS_DB_HOST: db + WORDPRESS_DB_USER: exampleuser + WORDPRESS_DB_PASSWORD: examplepass + WORDPRESS_DB_NAME: exampledb + volumes: + - wordpress:/var/www/html + networks: + - infra + - internal_network + + db: + image: mysql:5.7 + restart: always + environment: + MYSQL_DATABASE: exampledb + MYSQL_USER: exampleuser + MYSQL_PASSWORD: examplepass + MYSQL_RANDOM_ROOT_PASSWORD: '1' + volumes: + - db:/var/lib/mysql + networks: + - internal_network + +volumes: + wordpress: + db: + +networks: + infra: + external: true + internal_network: diff --git a/containers/docker/nextcloud/README.md b/containers/docker/nextcloud/README.md new file mode 100644 index 0000000..83c4509 --- /dev/null +++ b/containers/docker/nextcloud/README.md @@ -0,0 +1,40 @@ +# Disabling SSL + +```sh +docker exec -it nextcloud-aio-mastercontainer bash +``` + +in the container: + +```sh +vi /etc/apache2/sites-available/mastercontainer.conf +``` + +Change the line to disable SSL: + +``` +SSLEngine off +``` + +Restart https *within the container*: + +```sh +killall httpd +/usr/sbin/httpd +``` + +You can exit after that. + +# Run OCC command + +```sh +docker exec -it --user www-data nextcloud-aio-nextcloud /var/www/html/occ +``` + +# Brute force protection + +To add the Caddy Jails container that is running on `192.168.1.200` to the trusted proxies list: + +```sh +docker exec --user www-data -it nextcloud-aio-nextcloud php occ config:system:set trusted_proxies 2 --value="192.168.1.200" +``` diff --git a/containers/docker/nextcloud/compose.yaml b/containers/docker/nextcloud/compose.yaml new file mode 100644 index 0000000..f730270 --- /dev/null +++ b/containers/docker/nextcloud/compose.yaml @@ -0,0 +1,67 @@ +services: + nextcloud-aio-mastercontainer: + image: nextcloud/all-in-one:latest + init: true + restart: always + container_name: nextcloud-aio-mastercontainer # This line is not allowed to be changed as otherwise AIO will not work correctly + volumes: + - nextcloud_aio_mastercontainer:/mnt/docker-aio-config # This line is not allowed to be changed as otherwise the built-in backup solution will not work + - /var/run/docker.sock:/var/run/docker.sock:ro # May be changed on macOS, Windows or docker rootless. See the applicable documentation. If adjusting, don't forget to also set 'WATCHTOWER_DOCKER_SOCKET_PATH'! + ports: + # - 80:80 # Can be removed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md + - 8080:8080 + # - 8443:8443 # Can be removed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md + environment: # Is needed when using any of the options below + # AIO_DISABLE_BACKUP_SECTION: false # Setting this to true allows to hide the backup section in the AIO interface. See https://github.com/nextcloud/all-in-one#how-to-disable-the-backup-section + APACHE_PORT: 11000 # Is needed when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else). See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md + APACHE_IP_BINDING: 0.0.0.0 # Should be set when running behind a web server or reverse proxy (like Apache, Nginx, Cloudflare Tunnel and else) that is running on the same host. See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md + SKIP_DOMAIN_VALIDATION: true + ALLOW_INSECURE_ACCESS: true + # BORG_RETENTION_POLICY: --keep-within=7d --keep-weekly=4 --keep-monthly=6 # Allows to adjust borgs retention policy. See https://github.com/nextcloud/all-in-one#how-to-adjust-borgs-retention-policy + # COLLABORA_SECCOMP_DISABLED: false # Setting this to true allows to disable Collabora's Seccomp feature. See https://github.com/nextcloud/all-in-one#how-to-disable-collaboras-seccomp-feature + NEXTCLOUD_DATADIR: /home/nextcloud/nextcloud-data # Allows to set the host directory for Nextcloud's datadir. ⚠️⚠️⚠️ Warning: do not set or adjust this value after the initial Nextcloud installation is done! See https://github.com/nextcloud/all-in-one#how-to-change-the-default-location-of-nextclouds-datadir + # NEXTCLOUD_MOUNT: /mnt/ # Allows the Nextcloud container to access the chosen directory on the host. See https://github.com/nextcloud/all-in-one#how-to-allow-the-nextcloud-container-to-access-directories-on-the-host + # NEXTCLOUD_UPLOAD_LIMIT: 10G # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-upload-limit-for-nextcloud + # NEXTCLOUD_MAX_TIME: 3600 # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-max-execution-time-for-nextcloud + # NEXTCLOUD_MEMORY_LIMIT: 512M # Can be adjusted if you need more. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-php-memory-limit-for-nextcloud + # NEXTCLOUD_TRUSTED_CACERTS_DIR: /path/to/my/cacerts # CA certificates in this directory will be trusted by the OS of the nexcloud container (Useful e.g. for LDAPS) See See https://github.com/nextcloud/all-in-one#how-to-trust-user-defined-certification-authorities-ca + # NEXTCLOUD_STARTUP_APPS: deck twofactor_totp tasks calendar contacts notes # Allows to modify the Nextcloud apps that are installed on starting AIO the first time. See https://github.com/nextcloud/all-in-one#how-to-change-the-nextcloud-apps-that-are-installed-on-the-first-startup + # NEXTCLOUD_ADDITIONAL_APKS: imagemagick # This allows to add additional packages to the Nextcloud container permanently. Default is imagemagick but can be overwritten by modifying this value. See https://github.com/nextcloud/all-in-one#how-to-add-os-packages-permanently-to-the-nextcloud-container + # NEXTCLOUD_ADDITIONAL_PHP_EXTENSIONS: imagick # This allows to add additional php extensions to the Nextcloud container permanently. Default is imagick but can be overwritten by modifying this value. See https://github.com/nextcloud/all-in-one#how-to-add-php-extensions-permanently-to-the-nextcloud-container + NEXTCLOUD_ENABLE_DRI_DEVICE: true # This allows to enable the /dev/dri device in the Nextcloud container. ⚠️⚠️⚠️ Warning: this only works if the '/dev/dri' device is present on the host! If it should not exist on your host, don't set this to true as otherwise the Nextcloud container will fail to start! See https://github.com/nextcloud/all-in-one#how-to-enable-hardware-transcoding-for-nextcloud + # NEXTCLOUD_KEEP_DISABLED_APPS: false # Setting this to true will keep Nextcloud apps that are disabled in the AIO interface and not uninstall them if they should be installed. See https://github.com/nextcloud/all-in-one#how-to-keep-disabled-apps + # TALK_PORT: 3478 # This allows to adjust the port that the talk container is using. See https://github.com/nextcloud/all-in-one#how-to-adjust-the-talk-port + # WATCHTOWER_DOCKER_SOCKET_PATH: /var/run/docker.sock # Needs to be specified if the docker socket on the host is not located in the default '/var/run/docker.sock'. Otherwise mastercontainer updates will fail. For macos it needs to be '/var/run/docker.sock' + # networks: # Is needed when you want to create the nextcloud-aio network with ipv6-support using this file, see the network config at the bottom of the file + # - nextcloud-aio # Is needed when you want to create the nextcloud-aio network with ipv6-support using this file, see the network config at the bottom of the file + # security_opt: ["label:disable"] # Is needed when using SELinux + + # # Optional: Caddy reverse proxy. See https://github.com/nextcloud/all-in-one/blob/main/reverse-proxy.md + # # You can find further examples here: https://github.com/nextcloud/all-in-one/discussions/588 + # caddy: + # image: caddy:alpine + # restart: always + # container_name: caddy + # volumes: + # - ./Caddyfile:/etc/caddy/Caddyfile + # - ./certs:/certs + # - ./config:/config + # - ./data:/data + # - ./sites:/srv + # network_mode: "host" + +volumes: # If you want to store the data on a different drive, see https://github.com/nextcloud/all-in-one#how-to-store-the-filesinstallation-on-a-separate-drive + nextcloud_aio_mastercontainer: + name: nextcloud_aio_mastercontainer # This line is not allowed to be changed as otherwise the built-in backup solution will not work + +# # Optional: If you need ipv6, follow step 1 and 2 of https://github.com/nextcloud/all-in-one/blob/main/docker-ipv6-support.md first and then uncomment the below config in order to activate ipv6 for the internal nextcloud-aio network. +# # Please make sure to uncomment also the networking lines of the mastercontainer above in order to actually create the network with docker-compose +# networks: +# nextcloud-aio: +# name: nextcloud-aio # This line is not allowed to be changed as otherwise the created network will not be used by the other containers of AIO +# driver: bridge +# enable_ipv6: true +# ipam: +# driver: default +# config: +# - subnet: fd12:3456:789a:2::/64 # IPv6 subnet to use diff --git a/containers/docker/nextcloud/restart.sh b/containers/docker/nextcloud/restart.sh new file mode 100755 index 0000000..356135d --- /dev/null +++ b/containers/docker/nextcloud/restart.sh @@ -0,0 +1,13 @@ +docker stop nextcloud-aio-apache && docker start nextcloud-aio-apache +docker stop nextcloud-aio-notify-push && docker start nextcloud-aio-notify-push +docker stop nextcloud-aio-nextcloud && docker start nextcloud-aio-nextcloud +# docker stop nextcloud-aio-docker-socket-proxy && docker start nextcloud-aio-docker-socket-proxy +docker stop nextcloud-aio-imaginary && docker start nextcloud-aio-imaginary +# docker stop nextcloud-aio-fulltextsearch && docker start nextcloud-aio-fulltextsearch +# docker stop nextcloud-aio-clamav && docker start nextcloud-aio-clamav +docker stop nextcloud-aio-redis && docker start nextcloud-aio-redis +docker stop nextcloud-aio-database && docker start nextcloud-aio-database +docker stop nextcloud-aio-talk && docker start nextcloud-aio-talk +docker stop nextcloud-aio-collabora && docker start nextcloud-aio-collabora +# docker stop nextcloud-aio-domaincheck # && docker start nextcloud-aio-domaincheck +# docker stop nextcloud-aio-mastercontainer && docker start nextcloud-aio-mastercontainer diff --git a/containers/docker/nextcloud/stop.sh b/containers/docker/nextcloud/stop.sh new file mode 100755 index 0000000..a297383 --- /dev/null +++ b/containers/docker/nextcloud/stop.sh @@ -0,0 +1,13 @@ +docker stop nextcloud-aio-apache +docker stop nextcloud-aio-notify-push +docker stop nextcloud-aio-nextcloud +# docker stop nextcloud-aio-docker-socket-proxy +docker stop nextcloud-aio-imaginary +# docker stop nextcloud-aio-fulltextsearch +# docker stop nextcloud-aio-clamav +docker stop nextcloud-aio-redis +docker stop nextcloud-aio-database +docker stop nextcloud-aio-talk +docker stop nextcloud-aio-collabora +# docker stop nextcloud-aio-domaincheck +# docker stop nextcloud-aio-mastercontainer diff --git a/containers/docker/photoprism/README.md b/containers/docker/photoprism/README.md new file mode 100644 index 0000000..adcee06 --- /dev/null +++ b/containers/docker/photoprism/README.md @@ -0,0 +1,3 @@ +```sh +docker compose exec photoprism photoprism --help +``` diff --git a/containers/docker/photoprism/docker-compose.yml b/containers/docker/photoprism/docker-compose.yml new file mode 100644 index 0000000..68c42ba --- /dev/null +++ b/containers/docker/photoprism/docker-compose.yml @@ -0,0 +1,152 @@ +# Example Docker Compose config file for PhotoPrism (Linux / AMD64) +# +# Note: +# - Running PhotoPrism on a server with less than 4 GB of swap space or setting a memory/swap limit can cause unexpected +# restarts ("crashes"), for example, when the indexer temporarily needs more memory to process large files. +# - If you install PhotoPrism on a public server outside your home network, please always run it behind a secure +# HTTPS reverse proxy such as Traefik or Caddy. Your files and passwords will otherwise be transmitted +# in clear text and can be intercepted by anyone, including your provider, hackers, and governments: +# https://docs.photoprism.app/getting-started/proxies/traefik/ +# +# Setup Guides: +# - https://docs.photoprism.app/getting-started/docker-compose/ +# - https://docs.photoprism.app/getting-started/raspberry-pi/ +# - https://www.photoprism.app/kb/activation +# +# Troubleshooting Checklists: +# - https://docs.photoprism.app/getting-started/troubleshooting/ +# - https://docs.photoprism.app/getting-started/troubleshooting/docker/ +# - https://docs.photoprism.app/getting-started/troubleshooting/mariadb/ +# +# CLI Commands: +# - https://docs.photoprism.app/getting-started/docker-compose/#command-line-interface +# +# All commands may have to be prefixed with "sudo" when not running as root. +# This will point the home directory shortcut ~ to /root in volume mounts. + +services: + photoprism: + ## Use photoprism/photoprism:preview for testing preview builds: + image: photoprism/photoprism:latest + ## Don't enable automatic restarts until PhotoPrism has been properly configured and tested! + ## If the service gets stuck in a restart loop, this points to a memory, filesystem, network, or database issue: + ## https://docs.photoprism.app/getting-started/troubleshooting/#fatal-server-errors + # restart: unless-stopped + stop_grace_period: 10s + depends_on: + - mariadb + security_opt: + - seccomp:unconfined + - apparmor:unconfined + ## Server port mapping in the format "Host:Container". To use a different port, change the host port on + ## the left-hand side and keep the container port, e.g. "80:2342" (for HTTP) or "443:2342 (for HTTPS): + ports: + - "2342:2342" + ## Before you start the service, please check the following config options (and change them as needed): + ## https://docs.photoprism.app/getting-started/config-options/ + environment: + PHOTOPRISM_ADMIN_USER: "admin" # admin login username + PHOTOPRISM_ADMIN_PASSWORD: "5bp3ptdBGM173t" # initial admin password (8-72 characters) + PHOTOPRISM_AUTH_MODE: "password" # authentication mode (public, password) + PHOTOPRISM_SITE_URL: "http://localhost:2342/" # server URL in the format "http(s)://domain.name(:port)/(path)" + PHOTOPRISM_DISABLE_TLS: "false" # disables HTTPS/TLS even if the site URL starts with https:// and a certificate is available + PHOTOPRISM_DEFAULT_TLS: "true" # defaults to a self-signed HTTPS/TLS certificate if no other certificate is available + PHOTOPRISM_ORIGINALS_LIMIT: 5000 # file size limit for originals in MB (increase for high-res video) + PHOTOPRISM_HTTP_COMPRESSION: "gzip" # improves transfer speed and bandwidth utilization (none or gzip) + PHOTOPRISM_LOG_LEVEL: "info" # log level: trace, debug, info, warning, error, fatal, or panic + PHOTOPRISM_READONLY: "false" # do not modify originals directory (reduced functionality) + PHOTOPRISM_EXPERIMENTAL: "false" # enables experimental features + PHOTOPRISM_DISABLE_CHOWN: "false" # disables updating storage permissions via chmod and chown on startup + PHOTOPRISM_DISABLE_WEBDAV: "false" # disables built-in WebDAV server + PHOTOPRISM_DISABLE_SETTINGS: "false" # disables settings UI and API + PHOTOPRISM_DISABLE_TENSORFLOW: "false" # disables all features depending on TensorFlow + PHOTOPRISM_DISABLE_FACES: "false" # disables face detection and recognition (requires TensorFlow) + PHOTOPRISM_DISABLE_CLASSIFICATION: "false" # disables image classification (requires TensorFlow) + PHOTOPRISM_DISABLE_VECTORS: "false" # disables vector graphics support + PHOTOPRISM_DISABLE_RAW: "false" # disables indexing and conversion of RAW images + PHOTOPRISM_RAW_PRESETS: "false" # enables applying user presets when converting RAW images (reduces performance) + PHOTOPRISM_SIDECAR_YAML: "true" # creates YAML sidecar files to back up picture metadata + PHOTOPRISM_BACKUP_ALBUMS: "true" # creates YAML files to back up album metadata + PHOTOPRISM_BACKUP_DATABASE: "true" # creates regular backups based on the configured schedule + PHOTOPRISM_BACKUP_SCHEDULE: "daily" # backup SCHEDULE in cron format (e.g. "0 12 * * *" for daily at noon) or at a random time (daily, weekly) + PHOTOPRISM_INDEX_SCHEDULE: "" # indexing SCHEDULE in cron format (e.g. "@every 3h" for every 3 hours; "" to disable) + PHOTOPRISM_AUTO_INDEX: 300 # delay before automatically indexing files in SECONDS when uploading via WebDAV (-1 to disable) + PHOTOPRISM_AUTO_IMPORT: -1 # delay before automatically importing files in SECONDS when uploading via WebDAV (-1 to disable) + PHOTOPRISM_DETECT_NSFW: "false" # automatically flags photos as private that MAY be offensive (requires TensorFlow) + PHOTOPRISM_UPLOAD_NSFW: "true" # allows uploads that MAY be offensive (no effect without TensorFlow) + # PHOTOPRISM_DATABASE_DRIVER: "sqlite" # SQLite is an embedded database that does not require a separate database server + PHOTOPRISM_DATABASE_DRIVER: "mysql" # MariaDB 10.5.12+ (MySQL successor) offers significantly better performance compared to SQLite + PHOTOPRISM_DATABASE_SERVER: "mariadb:3306" # MariaDB database server (hostname:port) + PHOTOPRISM_DATABASE_NAME: "photoprism" # MariaDB database schema name + PHOTOPRISM_DATABASE_USER: "photoprism" # MariaDB database user name + PHOTOPRISM_DATABASE_PASSWORD: "insecure" # MariaDB database user password + PHOTOPRISM_SITE_CAPTION: "AI-Powered Photos App" + PHOTOPRISM_SITE_DESCRIPTION: "" # meta site description + PHOTOPRISM_SITE_AUTHOR: "" # meta site author + ## Video Transcoding (https://docs.photoprism.app/getting-started/advanced/transcoding/): + PHOTOPRISM_FFMPEG_ENCODER: "intel" # H.264/AVC encoder (software, intel, nvidia, apple, raspberry, or vaapi) + # PHOTOPRISM_FFMPEG_SIZE: "1920" # video size limit in pixels (720-7680) (default: 3840) + # PHOTOPRISM_FFMPEG_BITRATE: "32" # video bitrate limit in Mbit/s (default: 50) + ## Run/install on first startup (options: update https gpu ffmpeg tensorflow davfs clitools clean): + # PHOTOPRISM_INIT: "https gpu tensorflow" + ## Run as a non-root user after initialization (supported: 0, 33, 50-99, 500-600, and 900-1200): + # PHOTOPRISM_UID: 1000 + # PHOTOPRISM_GID: 1000 + # PHOTOPRISM_UMASK: 0000 + ## Start as non-root user before initialization (supported: 0, 33, 50-99, 500-600, and 900-1200): + # user: "1000:1000" + ## Share hardware devices with FFmpeg and TensorFlow (optional): + devices: + - "/dev/dri:/dev/dri" # Intel QSV + # - "/dev/nvidia0:/dev/nvidia0" # Nvidia CUDA + # - "/dev/nvidiactl:/dev/nvidiactl" + # - "/dev/nvidia-modeset:/dev/nvidia-modeset" + # - "/dev/nvidia-nvswitchctl:/dev/nvidia-nvswitchctl" + # - "/dev/nvidia-uvm:/dev/nvidia-uvm" + # - "/dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools" + # - "/dev/video11:/dev/video11" # Video4Linux Video Encode Device (h264_v4l2m2m) + working_dir: "/photoprism" # do not change or remove + ## Storage Folders: "~" is a shortcut for your home directory, "." for the current directory + volumes: + # "/host/folder:/photoprism/folder" # Example + - "/home/photoprism/Pictures:/photoprism/originals" # Original media files (DO NOT REMOVE) + # - "/example/family:/photoprism/originals/family" # *Additional* media folders can be mounted like this + - "/home/photoprism/Import:/photoprism/import" # *Optional* base folder from which files can be imported to originals + - "/home/photoprism/storage:/photoprism/storage" # *Writable* storage folder for cache, database, and sidecar files (DO NOT REMOVE) + + ## MariaDB Database Server (recommended) + ## see https://docs.photoprism.app/getting-started/faq/#should-i-use-sqlite-mariadb-or-mysql + mariadb: + image: mariadb:11 + ## If MariaDB gets stuck in a restart loop, this points to a memory or filesystem issue: + ## https://docs.photoprism.app/getting-started/troubleshooting/#fatal-server-errors + restart: unless-stopped + stop_grace_period: 5s + security_opt: # see https://github.com/MariaDB/mariadb-docker/issues/434#issuecomment-1136151239 + - seccomp:unconfined + - apparmor:unconfined + command: --innodb-buffer-pool-size=512M --transaction-isolation=READ-COMMITTED --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci --max-connections=512 --innodb-rollback-on-timeout=OFF --innodb-lock-wait-timeout=120 + ## Never store database files on an unreliable device such as a USB flash drive, an SD card, or a shared network folder: + volumes: + - "/home/photoprism/database:/var/lib/mysql" # DO NOT REMOVE + environment: + MARIADB_AUTO_UPGRADE: "1" + MARIADB_INITDB_SKIP_TZINFO: "1" + MARIADB_DATABASE: "photoprism" + MARIADB_USER: "photoprism" + MARIADB_PASSWORD: "insecure" + MARIADB_ROOT_PASSWORD: "insecure" + + ## Watchtower upgrades services automatically (optional) + ## see https://docs.photoprism.app/getting-started/updates/#watchtower + ## activate via "COMPOSE_PROFILES=update docker compose up -d" + watchtower: + restart: unless-stopped + image: containrrr/watchtower + profiles: ["update"] + environment: + WATCHTOWER_CLEANUP: "true" + WATCHTOWER_POLL_INTERVAL: 7200 # checks for updates every two hours + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + - "~/.docker/config.json:/config.json" # optional, for authentication if you have a Docker Hub account diff --git a/containers/docker/pinepods/compose.yaml b/containers/docker/pinepods/compose.yaml new file mode 100644 index 0000000..e53d1d9 --- /dev/null +++ b/containers/docker/pinepods/compose.yaml @@ -0,0 +1,31 @@ +name: pinepods + +services: + db: + image: postgres:latest + env_file: '.env' + volumes: + - /home/pinepods/pinepods/pgdata:/var/lib/postgresql/data + # Exposing the postgres database port is dumb. + # ports: + # - "5432:5432" + restart: always + + valkey: + image: valkey/valkey:8-alpine + # Exposing a nosql database is expecially dumb. + # ports: + # - "6379:6379" + + pinepods: + image: madeofpendletonwool/pinepods:latest + ports: + - "8040:8040" + env_file: '.env' + volumes: + # Mount the download and backup locations on the server + - /home/pinepods/pinepods/downloads:/opt/pinepods/downloads + - /home/pinepods/pinepods/backups:/opt/pinepods/backups + depends_on: + - db + - valkey \ No newline at end of file diff --git a/containers/docker/qbittorrent/docker-compose.yml b/containers/docker/qbittorrent/docker-compose.yml new file mode 100644 index 0000000..8dfae1b --- /dev/null +++ b/containers/docker/qbittorrent/docker-compose.yml @@ -0,0 +1,42 @@ +# https://github.com/nickkjolsing/dockerMullvadVPN + +name: torrent + +services: + openvpn-client: + image: ghcr.io/wfg/openvpn-client # Image on Docker. Shoutout to ghcr.io + container_name: openvpn-client + cap_add: + - NET_ADMIN # Needs to be here + environment: + - KILL_SWITCH=on # Turns off internet access if the VPN connection drops + - SUBNETS=192.168.0.0/24,192.168.1.0/24 + devices: + - /dev/net/tun + volumes: + - /home/jellyfin/mullvad_config_linux_nl_ams:/data/vpn + ports: + - 8082:8082 + - 6881:6881 + - 6881:6881/udp + restart: unless-stopped + + qbittorrent: + image: lscr.io/linuxserver/qbittorrent:latest + container_name: qbittorrent + environment: + - PUID=1003 + - PGID=1003 + - TZ=Europe/Amsterdam + - WEBUI_PORT=8082 + - TORRENTING_PORT=6881 + volumes: + - /home/jellyfin/qbitorrent/appdata:/config + - /home/jellyfin/qbitorrent/downloads:/downloads #optional + - /home/jellyfin/jellyfin/media:/media + # ports: + # - 8082:8082 + # - 6881:6881 + # - 6881:6881/udp + network_mode: container:openvpn-client # This uses the port setting of the openvpn + restart: unless-stopped diff --git a/containers/docker/webtop/compose.yaml b/containers/docker/webtop/compose.yaml new file mode 100644 index 0000000..4236359 --- /dev/null +++ b/containers/docker/webtop/compose.yaml @@ -0,0 +1,24 @@ +services: + webtop: + image: lscr.io/linuxserver/webtop:fedora-xfce + container_name: webtop + security_opt: + - seccomp:unconfined #optional + environment: + - PUID=1000 + - PGID=1000 + - TZ=Europe/Amsterdam + - SUBFOLDER=/ #optional + - TITLE=Webtop #optional + - CUSTOM_USER=moni + - PASSWORD=Pd5oBZ3vN31wCkj8 + volumes: + - /home/moni/webtop/data:/config + - /var/run/docker.sock:/var/run/docker.sock #optional + ports: + - 3000:3000 + - 3001:3001 + devices: + - /dev/dri:/dev/dri #optional + shm_size: "1gb" #optional + restart: unless-stopped diff --git a/containers/docker/windows/compose.yaml b/containers/docker/windows/compose.yaml new file mode 100644 index 0000000..dea39a9 --- /dev/null +++ b/containers/docker/windows/compose.yaml @@ -0,0 +1,18 @@ +services: + windows: + image: dockurr/windows + container_name: windows + environment: + VERSION: "11" + devices: + - /dev/kvm + - /dev/net/tun + cap_add: + - NET_ADMIN + ports: + - 8006:8006 + - 3389:3389/tcp + - 3389:3389/udp + stop_grace_period: 2m + volumes: + - /var/win:/storage diff --git a/containers/docker/wordpress/docker-compose.yml b/containers/docker/wordpress/docker-compose.yml new file mode 100644 index 0000000..8254dc0 --- /dev/null +++ b/containers/docker/wordpress/docker-compose.yml @@ -0,0 +1,31 @@ +version: '3.1' + +services: + + wordpress: + image: wordpress + restart: always + ports: + - 8080:80 + environment: + WORDPRESS_DB_HOST: db + WORDPRESS_DB_USER: exampleuser + WORDPRESS_DB_PASSWORD: examplepass + WORDPRESS_DB_NAME: exampledb + volumes: + - wordpress:/var/www/html + + db: + image: mysql:8.0 + restart: always + environment: + MYSQL_DATABASE: exampledb + MYSQL_USER: exampleuser + MYSQL_PASSWORD: examplepass + MYSQL_RANDOM_ROOT_PASSWORD: '1' + volumes: + - db:/var/lib/mysql + +volumes: + wordpress: + db: \ No newline at end of file diff --git a/homeservers/Backup.md b/homeservers/Backup.md new file mode 100644 index 0000000..fdc93bd --- /dev/null +++ b/homeservers/Backup.md @@ -0,0 +1,86 @@ +# Syncthing + +```sh +sudo systemctl restart syncthing@photoprism.service +``` + +Admin interface: http://192.168.1.10:8384/ + +I have a user called `photoprism` and the password is in Bitwarden + +# Borg Backup to Hetzner Storage Box + +For backup I use [Borg](https://borgbackup.readthedocs.io/). I followed the steps described in this community article: + +* [Install and Configure BorgBackup](https://community.hetzner.com/tutorials/install-and-configure-borgbackup) + +We have two backups in the storage box: + +* `/./borgbackup/photoprism` +* `/./borgbackup/nextcloud` + +## Photoprism backup + +This is what I did for Photoprism + +The init script (which is only done once, be careful it will overwrite!): + +```sh +# (As root) +export BORG_RSH='ssh -i /root/.ssh/id_ed25519' +export BORG_PASSPHRASE="" +borg init --encryption=repokey ssh://u388089@u388089.your-storagebox.de:23/./borgbackup/photoprism +``` + +It outputs a key which I put in Bitwarden (you need it to decrypt the backup). + +To make a manual backup: + +```sh +export BORG_RSH='ssh -i /root/.ssh/id_ed25519' +export BORG_PASSPHRASE="" +borg create --stats ssh://u388089@u388089.your-storagebox.de:23/./borgbackup/photoprism::2024_11_24 /home/photoprism/Import/ /home/photoprism/Pictures/ +``` + +The above can be found in Bitwarden, look for "Hetzner Borg Backup Script for Photoprism" + +I also created a bash script in `/usr/local/bin/photoprism_backup.sh` (as mentioned in the article). + +You can find it here in this repo: + +* [photoprism_backup.sh](./scripts/photoprism_backup.sh) + +## Nextcloud backup + +Ok, this is confusing but Nextcloud uses Borgbackup internally. Go to the [aio interface](http://192.168.1.10:8080/) and you'll notice there are backups to: + +``` +/root/nextcloudbackup +``` + +So nextcloud keeps making backups to this directory. Not ideal (TODO: I gotta find a solution for this). + +But I can rclone the data: + +```sh +rclone sync -v /root/nextcloudbackup/ hetzner:/cloned_borgbackup/nextcloud +``` + +For this I also created a script and placed it in `/usr/local/bin` + +[nextcloud_backup.sh](./scripts/nextcloud_backup.sh) + +# Automatic backup + +* [cloud_backup.service](./scripts/cloud_backup.service) +* [cloud_backup.timer](./scripts/cloud_backup.timer) + +```sh +cp -v cloud_backup.service /etc/systemd/system/ +cp -v cloud_backup.timer /etc/systemd/system/ +``` + +```sh +systemctl enable cloud_backup.service +systemctl enable cloud_backup.timer +``` diff --git a/homeservers/Immich.md b/homeservers/Immich.md new file mode 100644 index 0000000..02b99ac --- /dev/null +++ b/homeservers/Immich.md @@ -0,0 +1,15 @@ +Compose file: + +[compose.yaml](../containers/docker/immich/compose.yaml) + +For immich I added a dedicated user: + +```sh +sudo useradd immich +``` + +This creates a `/home/immich` directory. We neet to run `cat /etc/passwd` to get the id of the user. + +Unfortunately, I have not been able to use the user id for the containers, so everything is written as root. I'm still using `/home/immich`, but all the files are written there as root. + +Eventually I might use podman but I don't know enough about it yet to get comfortable with it. diff --git a/homeservers/Jellyfin.md b/homeservers/Jellyfin.md new file mode 100644 index 0000000..4606095 --- /dev/null +++ b/homeservers/Jellyfin.md @@ -0,0 +1,21 @@ +# Jellyfin + +Compose file: + +* [compose.yaml](../containers/docker/jellyfin/compose.yaml) + +I made a user names `jellyfin` and put its uid:guid in the compose file. All the files are in the home directory of that user `/home/jellyfin`. + +The user also has the authorized_keys so I can do this: + +```sh +ssh jellyfin@192.168.1.10 +``` + +and proceed to add the directories for the media files: + +```sh +cd jellyfin/media/tvshows/ +mkdir "Show I Want To Watch (2020)" +mkdir "Season 01" +``` diff --git a/homeservers/Nextcloud.md b/homeservers/Nextcloud.md new file mode 100644 index 0000000..242ea7f --- /dev/null +++ b/homeservers/Nextcloud.md @@ -0,0 +1,22 @@ +# Nextcloud + +I have a dedicated user: + +```sh +sudo useradd nextcloud +``` + +I'm running the Nextcloud All-In-One container. In order to make it easy I have a [stop](../containers/docker/nextcloud/stop.sh) and [restart](../containers/docker/nextcloud/stop.sh) script. + +Nextcloud runs on + +* https://nextcloud.allisonandmoni.online/ + +When you first start it up, you need to first disable the SSL from within the container: + +* [Ugly hack README](../containers/docker/nextcloud/README.md) + +And then go to: + +* http://192.168.1.11:8080 + diff --git a/homeservers/PhotoPrism.md b/homeservers/PhotoPrism.md new file mode 100644 index 0000000..a5615bb --- /dev/null +++ b/homeservers/PhotoPrism.md @@ -0,0 +1,43 @@ +# Photoprism + +What we are really running on this machine is Photoprism using this [docker-compose](../containers/docker/photoprism/docker-compose.yml) file, like this: + +```sh +cd ~/projects/stuff/containers/docker/photoprism +docker compose up --detach +``` + +To stop it: + +```sh +docker compose down +``` + +To update it: + +```sh +docker compose pull +``` + +Photoprism is running on: https://photos.allisonandmoni.online/ + +I have set up a Systemd service and timer to automatically run the import once an hour. They can be found: + +* [photoprism_import.service](./scripts/photoprism_import.service) +* [photoprism_import_timer.service](./scripts/photoprism_import_timer.service) + +To install: + +```sh +cp -v photoprism_import.service /etc/systemd/system/ +cp -v photoprism_import.timer /etc/systemd/system/ +``` + +Enable: + +```sh +systemctl enable photoprism_import.service +systemctl enable photoprism_import.timer +``` + +In the `compose.yaml` file you'll notice I have the files stored in `/home/photoprism`. That's because I thought I could run it with podman as a dedicated user. I abandoned that idea and am now running it in Docker instead. The directories `/home/photoprism/Pictures` and `/home/photoprism/Import` are all owned by `root` diff --git a/homeservers/README.md b/homeservers/README.md new file mode 100644 index 0000000..d61417b --- /dev/null +++ b/homeservers/README.md @@ -0,0 +1,43 @@ +# General + +This file describes the setup of the servers I have running at home, with some instructions. + +At the moment I'm running: + +* Raspberry PI4 8GB: `ssh moni@192.168.1.108` +* Lenovo Thinkcentre M900, i5-6500T: `ssh moni@192.168.1.10`, 8GB RAM, 500G SSD +* Lenovo Thinkcentre M900, i5-6500T: `ssh moni@192.168.1.11`, 16GB RAM, 126G NVME + 1TB SSD + +For Raspberry PI, see [RPI](./RPI.md). That is where the routing happens. +For Lenovo Thinkcenter, see below. That is where all the action happens. + +# Lenovo Thinkcentre M900, i5-6500T + +I have two Lenovo Thinkcentres, one with 8GB of ram and 500GB. The other with 16GB of ram and an NVME of 128GB and an SSD of 1GB. + +The idea is to have one in production for all my servers running on `allisonandmoni.online` domain and the other is to play with. + +Right now my OS of choice is AlmaLinux, but that can change with my mood. + +On my production machine I am running Docker. + +You don't need to be root to use it: + +```sh +docker ps -a +``` + +Right now I'm running the following containers: + +* [PhotoPrism](./PhotoPrism.md), reachable by https://photos.allisonandmoni.online +* [JellyFin](./Jellyfin.md), reachable by https://jellyfin.allisonandmoni.online/ +* [Nextcloud](./Nextcloud.md), reachable by https://nextcloud.allisonandmoni.online/ +* [qBittorrent](./qBittorrent.md), reachable by https://qbittorrent.allisonandmoni.online/ +* [Immich](./Immich.md), reachable by https://photos2.allisonandmoni.online + +# Backup and restore + +I have backup and restore scripts and instructions. See here: + +* [Backup](./Backup.md) +* [Restore](./Restore.md) \ No newline at end of file diff --git a/homeservers/RPI.md b/homeservers/RPI.md new file mode 100644 index 0000000..91b2523 --- /dev/null +++ b/homeservers/RPI.md @@ -0,0 +1,53 @@ +# Raspberry PI + +On the Raspberry PI I am running FreeBSD with Bastille which currently has 1 jail: + +```sh +sudo bastille list +``` + +``` +ID IP Address Hostname Path +1 192.168.1.200 caddy /usr/local/bastille/jails/caddy/root +``` + +The ip address 192.168.1.200 is chosen deliberately. On my router (192.168.1.1) I have the following port mappings: + +* 32222 to 192.168.1.108:22 (ssh) - Maps to the Raspberry PI 8 for external access +* 80 to 192.168.1.200:80 (http) - Maps to the Caddy jail +* 443 to 192.168.1.200:443 (https) - Maps to the Caddy jail +* 3478 to 192.168.1.10 (Nextcloud talk) - This is a direct connection to the Lenovo machine. + +To view the Caddy setup in the Caddy jail, run this: + +```sh +sudo -i +bastille console caddy +cat /usr/local/etc/caddy/Caddyfile +``` + +Result: + +``` +www.allisonandmoni.online { + reverse_proxy 192.168.1.10:8081 +} + +photos.allisonandmoni.online { + reverse_proxy 192.168.1.10:2342 +} + +nextcloud.allisonandmoni.online { + reverse_proxy 192.168.1.10:11000 +} + +jellyfin.allisonandmoni.online { + reverse_proxy 192.168.1.10:8096 +} +``` + +As you can see I have setup reverse proxies for www, photos and nextcloud for allisonandmoni.online. + +The instructions for the caddy setup on my RPI4 can be found in this file: + +* [Caddy on FreeBSD](../os/FreeBSD/Bastille.md#caddy) diff --git a/homeservers/Restore.md b/homeservers/Restore.md new file mode 100644 index 0000000..c665cdb --- /dev/null +++ b/homeservers/Restore.md @@ -0,0 +1,62 @@ +# Restore + +## Borg backup + +First we need to install Borg Backup: + +```sh +dnf install -y borgbackup +``` + +## Hetzner Storage Box + +So I have a Hetzner Storage Box which is reachable by: + +```sh +ssh -p23 u388089@u388089.your-storagebox.de +``` + +There are two subdirectories: + +```sh +/borgbackup # This is an actual borg backup of PhotoPrism with history and everything +/cloned_borgbackup # This is a rclone of a borg backup of nextcloud that happens on my local machine. +``` + +First, we're going to talk about restoring PhotoPrism + +## Restore Photoprism + +List: + +```sh +export BORG_PASSPHRASE='' +borg list ssh://u388089@u388089.your-storagebox.de:23/./borgbackup/photoprism +``` + +(Optional, to see what you have) Mount a snapshot: + +```sh +borg mount ssh://u388089@u388089.your-storagebox.de:23/./borgbackup/photoprism::2025-01-14_04:00 /home/moni/borg_restore/ +``` + +Unmount it: + +```sh +borg umount /home/moni/borg_restore/ +``` + +Restore a backup + +You might want to tmux first: + +```sh +tmux +``` + +```sh +borg --progress --verbose extract ssh://u388089@u388089.your-storagebox.de:23/./borgbackup/photoprism::2025-01-14_04:00 /home/photoprism/Pictures +``` + +Giving a local target directory is not supported. The restore will be in a subdirectory. So if you're in `/home/moni` it will restore to `/home/moni/home/photoprism/Pictures`. You can't change this behavior. + diff --git a/homeservers/qBittorrent.md b/homeservers/qBittorrent.md new file mode 100644 index 0000000..a61d5c8 --- /dev/null +++ b/homeservers/qBittorrent.md @@ -0,0 +1,11 @@ +# qBittorrent + +Compose file: + +* [compose.yaml](../containers/docker/qbittorrent/docker-compose.yml) + +qBittorrent uses the same user as jellyfin which writes everything to `/home/jellyfin` + +I also put the `jellyfin` uid:guid into the qbitorrent container. The files are downloaded to the `bittorrent/downloads` subdirtory of `jellyfin` home. + +When I want to watch something I can copy it from the downloads directory to the media directory of jellyfin. diff --git a/homeservers/scripts/cloud_backup.service b/homeservers/scripts/cloud_backup.service new file mode 100644 index 0000000..674c6c1 --- /dev/null +++ b/homeservers/scripts/cloud_backup.service @@ -0,0 +1,8 @@ +[Unit] +Description=Run Cloud Backup + +[Service] +ExecStart=/bin/bash /usr/local/bin/cloud_backup.sh + +[Install] +WantedBy=multi-user.target diff --git a/homeservers/scripts/cloud_backup.sh b/homeservers/scripts/cloud_backup.sh new file mode 100644 index 0000000..a7544ed --- /dev/null +++ b/homeservers/scripts/cloud_backup.sh @@ -0,0 +1,3 @@ +#!/bin/bash +/bin/bash /usr/local/bin/photoprism_backup.sh +/bin/bash /usr/local/bin/nextcloud_backup.sh diff --git a/homeservers/scripts/cloud_backup.timer b/homeservers/scripts/cloud_backup.timer new file mode 100644 index 0000000..07bf5b3 --- /dev/null +++ b/homeservers/scripts/cloud_backup.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Run PCloud Backup timer + +[Timer] +OnCalendar=0/4:00:00 +Unit=cloud_backup.service + +[Install] +WantedBy=timers.target diff --git a/homeservers/scripts/nextcloud_backup.sh b/homeservers/scripts/nextcloud_backup.sh new file mode 100644 index 0000000..6f3c01b --- /dev/null +++ b/homeservers/scripts/nextcloud_backup.sh @@ -0,0 +1 @@ +rclone sync /root/nextcloudbackup/ hetzner:/cloned_borgbackup/nextcloud --log-file /var/log/nextcloud_backup.log --log-level INFO \ No newline at end of file diff --git a/homeservers/scripts/photoprism_backup.sh b/homeservers/scripts/photoprism_backup.sh new file mode 100644 index 0000000..e282287 --- /dev/null +++ b/homeservers/scripts/photoprism_backup.sh @@ -0,0 +1,59 @@ +#!/usr/bin/env bash + +## +## Set environment variables +## + +## if you don't use the standard SSH key, +## you have to specify the path to the key like this +export BORG_RSH='ssh -i /root/.ssh/id_ed25519' + +## You can save your borg passphrase in an environment +## variable, so you don't need to type it in when using borg +export BORG_PASSPHRASE='' + +## +## Set some variables +## + +LOG='/var/log/photoprism_backup.log' +export BACKUP_USER='u388089' +export REPOSITORY_DIR='photoprism' + +## Tip: If using with a Backup Space you have to use +## 'your-storagebox.de' instead of 'your-backup.de' + +export REPOSITORY="ssh://${BACKUP_USER}@${BACKUP_USER}.your-storagebox.de:23/./borgbackup/${REPOSITORY_DIR}" + +## +## Output to a logfile +## + +exec > >(tee -i ${LOG}) +exec 2>&1 + +echo "###### Backup started: $(date) ######" + +## +## At this place you could perform different tasks +## that will take place before the backup, e.g. +## +## - Create a list of installed software +## - Create a database dump +## + +## +## Transfer the files into the repository. +## In this example the folders root, etc, +## var/www and home will be saved. +## In addition you find a list of excludes that should not +## be in a backup and are excluded by default. +## + +echo "Transfer files ..." +borg create -v --stats \ + $REPOSITORY::'{now:%Y-%m-%d_%H:%M}' \ + /home/photoprism/Import/ \ + /home/photoprism/Pictures/ + +echo "###### Backup ended: $(date) ######" diff --git a/homeservers/scripts/photoprism_import.service b/homeservers/scripts/photoprism_import.service new file mode 100644 index 0000000..567702e --- /dev/null +++ b/homeservers/scripts/photoprism_import.service @@ -0,0 +1,8 @@ +[Unit] +Description=Run Photoprism Import + +[Service] +ExecStart=docker exec photoprism-photoprism-1 photoprism import + +[Install] +WantedBy=multi-user.target diff --git a/homeservers/scripts/photoprism_import.timer b/homeservers/scripts/photoprism_import.timer new file mode 100644 index 0000000..c5237c1 --- /dev/null +++ b/homeservers/scripts/photoprism_import.timer @@ -0,0 +1,9 @@ +[Unit] +Description=Run Photoprism Import script hourly + +[Timer] +OnCalendar=hourly +Unit=photoprism_import.service + +[Install] +WantedBy=timers.target diff --git a/laptops/Clevo_Laptop.md b/laptops/Clevo_Laptop.md new file mode 100644 index 0000000..f3a8e5f --- /dev/null +++ b/laptops/Clevo_Laptop.md @@ -0,0 +1,179 @@ +Clevo laptop which is sold by Tuxedo computers. + +# General + +Set the hostname: + +```sh +hostnamectl set-hostname moni-fedora # Fedora +hostnamectl set-hostname moni-opensuse # openSUSE +``` + +Install my favorite packages + +```sh +zypper install tmux htop neovim git ncdu podman # openSUSE +dnf install tmux htop neovim git ncdu podman # Fedora +``` + +# Suspend when laptop lid closed + +On openSUSE: + +On Fedora: + +```sh +nvim /usr/lib/systemd/logind.conf # Fedora & openSUSE +nvim /etc/systemd/logind.conf # Ubuntu +``` + +Uncomment the lines: + +```conf +HandleLidSwitch=suspend +HandleLidSwitchExternalPower=suspend +HandleLidSwitchDocked=ignore +LidSwitchIgnoreInhibited=yes +``` + +You need to reboot before it takes effect. + +# Wake on suspend + +There is a bug in Linux kernel 6. This article explains this: + +https://bugzilla.redhat.com/show_bug.cgi?id=2162013 + +Somehow the touchpad keeps waking up the laptop. + +```sh +cat /proc/acpi/wakeup +``` + +Should return: + +``` +Device S-state Status Sysfs node +GPP0 S0 *disabled +GPP1 S0 *disabled +GP17 S0 *enabled pci:0000:00:08.1 +``` + +## Temporarily disable + +To temporarily disable it do this: + +```sh +echo disabled > /sys/bus/i2c/devices/i2c-FTCS1000:00/power/wakeup +``` + +## Persistent settings + +As root: + +```sh +nvim /etc/systemd/system/disable-wakeup.service +``` + +Contents: + +``` +[Unit] +Description=Disable wakeup triggers + +[Service] +Type=oneshot +ExecStart=/bin/sh -c "echo disabled > /sys/bus/i2c/devices/i2c-FTCS1000\:00/power/wakeup ; echo GP17 > /proc/acpi/wakeup" +ExecStop=/bin/sh -c "echo disabled > /sys/bus/i2c/devices/i2c-FTCS1000\:00/power/wakeup ; echo GP17 > /proc/acpi/wakeup" +RemainAfterExit=yes + +[Install] +WantedBy=multi-user.target +``` + +Then simply enable and start it: + +```sh +systemctl enable disable-wakeup.service +systemctl start disable-wakeup.service +``` + +Reboot the laptop and check to see if the systemd unit works: + +```sh +systemctl status disable-wakeup.service +``` + +```sh +cat /proc/acpi/wakeup +cat /sys/bus/i2c/devices/i2c-FTCS1000\:00/power/wakeup +``` + +Test it by suspending the laptop. You can also use: + +```sh +systemctl suspend -i +``` + +# Tuxedo control center + +Instructions: https://www.tuxedocomputers.com/en/Add-TUXEDO-software-package-sources.tuxedo + +## On openSUSE + +See instructions on page and then: + +```sh +zypper refresh && zypper install tuxedo-control-center +``` + + +## On Fedora + +```sh +nvim /etc/yum.repos.d/tuxedo.repo +``` + +Contents: + +``` +[tuxedo] +name=tuxedo +baseurl=https://rpm.tuxedocomputers.com/fedora/40/x86_64/base +enabled=1 +gpgcheck=1 +gpgkey=https://rpm.tuxedocomputers.com/fedora/40/0x54840598.pub.asc +skip_if_unavailable=False +``` + +Get the key: + +```sh +wget https://rpm.tuxedocomputers.com/fedora/40/0x54840598.pub.asc +``` + +And install it: + +```sh +rpm --import ./0x54840598.pub.asc +``` + +Now install the control center: + +```sh +dnf update +dnf install tuxedo-control-center +``` + +You need to reboot before it takes effect. + +# Virtualization + +```sh +dnf install @virtualization +``` + +```sh +systemctl enable libvirtd +systemctl start libvirtd +``` diff --git a/laptops/Ideapad_510.md b/laptops/Ideapad_510.md new file mode 100644 index 0000000..ab4c295 --- /dev/null +++ b/laptops/Ideapad_510.md @@ -0,0 +1,88 @@ +# Lenovo ideapad 510 + +## Prevent suspend when lid closed + +Add a new file: + +```sh +nvim /etc/systemd/logind.conf.d/no-suspend-on-lid.conf +``` + +Add this: + +``` +[Login] +HandleLidSwitch=ignore +HandleLidSwitchExternalPower=ignore +HandleLidSwitchDocked=ignore +``` + +```sh +systemctl restart systemd-logind +``` + +## Wake-on-lan + +See my network interfaces: + +```sh +ip link show +``` + +``` +1: lo: mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 + link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 +2: enp1s0: mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 + link/ether 54:e1:ad:9d:a8:74 brd ff:ff:ff:ff:ff:ff +3: wlp2s0: mtu 1500 qdisc noqueue state DOWN mode DORMANT group default qlen 1000 + link/ether 52:37:c4:2c:79:38 brd ff:ff:ff:ff:ff:ff permaddr 3c:f8:62:b3:7f:81 +``` + +Enable for the ethernet + +```sh +ethtool -s enp1s0 wol g +``` + +Make it pemanent. Create a systemd unit: + +```sh +nvim /etc/systemd/system/wol.service +``` + +``` +[Unit] +Description=Wake-on-LAN +Requires=network.target +After=network.target + +[Service] +ExecStart=/usr/sbin/ethtool -s enp1s0 wol g +Type=oneshot + +[Install] +WantedBy=multi-user.target +``` + +```sh +systemctl enable wol.service +``` + +Check it: + +```sh +systemctl start wol.service +systemctl status wol.service +``` + +Suspend the laptop: + +```sh +systemctl suspend +``` + +Wake it up again from another machine: + +```sh +wakeonlan 54:e1:ad:9d:a8:74 +``` \ No newline at end of file diff --git a/laptops/Laptops.md b/laptops/Laptops.md new file mode 100644 index 0000000..b487837 --- /dev/null +++ b/laptops/Laptops.md @@ -0,0 +1,2 @@ +* [Clevo Laptop](Clevo_Laptop.md) +* [Lenovo ideapad 510](Ideapad_510.md) \ No newline at end of file diff --git a/os/AlmaLinux/AlmaLinux.md b/os/AlmaLinux/AlmaLinux.md new file mode 100644 index 0000000..181a631 --- /dev/null +++ b/os/AlmaLinux/AlmaLinux.md @@ -0,0 +1,90 @@ +# General + +Remove the web console and all the other stuff around it: + +```sh +dnf -y remove cockpit* +firewall-cmd --permanent --remove-service=cockpit +firewall-cmd --reload +firewall-cmd --list-all +``` + +Update + +```sh +dnf update +``` + +Set hostname + +```sh +hostnamectl set-hostname moni-alma +``` + +Set up EPEL, follow the instructions: + +* https://docs.fedoraproject.org/en-US/epel/getting-started/ + +And then install my favorites: + +```sh +dnf install -y tmux htop ncdu neovim git +``` + +Install docker: + +```sh +dnf -y install dnf-plugins-core +dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo +dnf install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin +systemctl enable --now docker +``` + +Add the `moni` to the docker group: + +```sh +usermod -aG docker moni +``` + +You need to log out and log back in and then test it: + +```sh +# run without sudo +docker run -it --rm -p 8080:80 httpd:2.4 +``` + +It will run in the foreground because we didn't pass `-d`. + +Open your browser to: + +* http://192.168.1.11:8080 +* or http://192.168.1.10:8080 for the 8GB server + +You can stop the container with CTRL+C. It should clean itself up (`--rm`). + +Cleanup: + +```sh +docker image prune --all --force +``` + +# SSH + +```sh +nvim /etc/ssh/sshd_config +``` + +Uncomment/change these settings: + +```conf +PermitRootLogin no +# PubkeyAuthentication yes <-- This is the detault, so you don't need to change this +PasswordAuthentication no +KbdInteractiveAuthentication no +``` + +Reload: + +```sh +sudo systemctl reload sshd +``` diff --git a/os/FreeBSD/FreeBSD_on_Clevo_Laptop.md b/os/FreeBSD/FreeBSD_on_Clevo_Laptop.md new file mode 100644 index 0000000..d644db9 --- /dev/null +++ b/os/FreeBSD/FreeBSD_on_Clevo_Laptop.md @@ -0,0 +1,280 @@ +# Setup + +Install my favorite packages + +```sh +pkg install bash sudo tmux htop neovim git bastille +``` + +Add "wheel" to the suoers file: + +```sh +visudo +``` + +Change shell + +```sh +chsh -s /usr/local/bin/bash +``` + +Do a system update: + +```sh +freebsd-update fetch install +``` + +# Wifi + +Find out what network cards we have: + +```sh +pciconf -lv | grep -A1 -B3 network +``` + +On my Clevo laptop it looks like this: + +``` +re0@pci0:2:0:0: class=0x020000 rev=0x15 hdr=0x00 vendor=0x10ec device=0x8168 subvendor=0x1558 subdevice=0xa600 + vendor = 'Realtek Semiconductor Co., Ltd.' + device = 'RTL8111/8168/8211/8411 PCI Express Gigabit Ethernet Controller' + class = network + subclass = ethernet +iwlwifi0@pci0:3:0:0: class=0x028000 rev=0x1a hdr=0x00 vendor=0x8086 device=0x2723 subvendor=0x8086 subdevice=0x0084 + vendor = 'Intel Corporation' + device = 'Wi-Fi 6 AX200' + class = network +nvme0@pci0:4:0:0: class=0x010802 rev=0x00 hdr=0x00 vendor=0x144d device=0xa809 subvendor=0x144d subdevice=0xa801 +``` + +So we have an Intel Wifi. + +We're going to configure the wireless card iwlwifi0 to the interface wlan0: + +```sh +ifconfig wlan0 create wlandev iwlwifi0 +``` + +To make the change persist across reboots: + +```sh +sysrc wlans_iwlwifi0="wlan0" +``` + +We need to set the regulatory domain: + +```sh +ifconfig wlan0 regdomain ETSI country NL +``` + +To scan the networks. I had to run the command twice to see the list: + +```sh +ifconfig wlan0 up list scan +``` + +I see my networks: + +``` +SSID/MESH ID BSSID CHAN RATE S:N INT CAPS +TMNL-3EF981_24G d8:0d:17:b9:b2:f0 11 54M -37:-96 100 EPS HTCAP WME ATH RSN WPS +TMNL-3EF981 98:0d:67:3e:f9:81 11 54M -72:-96 100 EP APCHANREP RSN WPS BSSLOAD HTCAP VHTCAP VHTOPMODE WME +TMNL-3EF981_5G d8:0d:17:b9:b2:f1 64 54M -42:-96 100 EP HTCAP VHTCAP VHTOPMODE VHTPWRENV WME ATH RSN WPS +``` + +I want to connect to `TMNL-3EF981_5G`. We need to edit the `/etc/wpa_supplicant.conf` file: + +```sh +nvim /etc/wpa_supplicant.conf +``` + +The contents. The password need to be set in psk. + +``` +country=NL +network={ + ssid="TMNL-3EF981_5G" + psk="3J6YJHNRG8W7KMMF" + priority=5 +} +``` + +To set it to use DHCP: + +```sh +sysrc ifconfig_wlan0="WPA SYNCDHCP" +``` + +For some reason, we need to add the country code in the rc.conf: + +```sh +sysrc create_args_wlan0="country NL" +``` + +Now bring it up! + +```sh +service netif restart +``` + +Restart the laptop to see if it persists. + +For some reason, it won't work (no suprise, wifi is awful in FreeBSD). + +This worked for me after boot + +```sh +ifconfig wlan0 down +ifconfig wlan0 ssid "TMNL-3EF981_5G" +ifconfig wlan0 regdomain etsi2 country NL +service netif restart +``` + +# X11 + +https://docs.freebsd.org/en/books/handbook/x11/ + +Don't forget to start `tmux`: + +```sh +tmux +``` + +Add `moni` to the `video` group: + +```sh +pw groupmod video -m moni +``` + +And then install, but don't forget to read the messages when the install is complete! Scroll up with tmux + +```sh +pkg install xorg +``` + +This will improve mnuse and touchscreen support: + +```sh +sysctl kern.evdev.rcpt_mask=6 +``` + +And add this to `/etc/sysctl.conf` to persist it: + +```sh +kern.evdev.rcpt_mask=6 +``` + +# Amd + +```sh +pkg install drm-kmod +``` + +```sh +sysrc kld_list+=amdgpu +``` + +# Kde + +```sh +pkg install kde5 +``` + +```sh +sysrc dbus_enable="YES" +``` + +```sh +sysctl net.local.stream.recvspace=65536 +sysctl net.local.stream.sendspace=65536 +``` + +```sh +pkg install sddm +sysrc sddm_enable="YES" +``` + +# Fonts + +```sh +pkg install urwfonts +``` + +But you're not done yet, you need to add a conf file: + +```sh +nvim /usr/local/etc/X11/xorg.conf.d/90-fonts.conf +``` + +With the following: + +``` +Section "Files" + FontPath "/usr/local/share/fonts/urwfonts/" +EndSection +``` + +# CPU + +Too see your CPU 0 + +```sh +sysctl dev.cpu.0 +``` + +If you don't see a temperature: + +```sh +kldload amdtemp +``` + +Add it to startup: + +```sh +sysrc kld_list+=amdtemp +``` + +# Linux compatibility + +```sh +sysrc linux_enable="YES" +``` + +```sh +service linux start +``` + +# Final configs + +My `/etc/rc.conf` + +``` +hostname="moni-freebsd" +ifconfig_re0="DHCP" +sshd_enable="YES" +moused_enable="YES" +# Set dumpdev to "AUTO" to enable crash dumps, "NO" to disable +dumpdev="AUTO" +kld_list="amdgpu amdtemp" +dbus_enable="YES" +sddm_enable="YES" +linux_enable="YES" +create_args_wlan0="country NL" +wlans_iwlwifi0="wlan0" +ifconfig_wlan0="WPA SYNCDHCP" +``` + +My `/etc/sysctl.conf`: + +``` +# +# This file is read when going to multi-user and its contents piped thru +# ``sysctl'' to adjust kernel values. ``man 5 sysctl.conf'' for details. +# + +# Uncomment this to prevent users from seeing information about processes that +# are being run under another UID. +#security.bsd.see_other_uids=0 + +kern.evdev.rcpt_mask=6 +``` diff --git a/os/FreeBSD/FreeBSD_on_Lenovo_Thinkcentre.md b/os/FreeBSD/FreeBSD_on_Lenovo_Thinkcentre.md new file mode 100644 index 0000000..b63c33d --- /dev/null +++ b/os/FreeBSD/FreeBSD_on_Lenovo_Thinkcentre.md @@ -0,0 +1,111 @@ +# Setup + +First time: + +```sh +su - +``` + +Do a system update: + +```sh +freebsd-update fetch install +``` + +Update + +```sh +pkg update +``` + +Install my favorite packages + +```sh +pkg install -y bash sudo tmux htop neovim git ncdu bastille tailscale aria2 +``` + +Add "wheel" to the suoers file: + +```sh +visudo +``` + +Change shell + +```sh +chsh -s /usr/local/bin/bash +``` + +Tailscale + +```sh +service tailscaled enable +service tailscaled start +tailscale up +``` + +# SSH + +```sh +nvim /etc/ssh/sshd_config +``` + +Change this setting: + +``` +KbdInteractiveAuthentication no +``` + +That should be it. The config file should have these settings, including the commented lines shown as below: + +``` +#PermitRootLogin no +#PubkeyAuthentication yes +#PasswordAuthentication no +KbdInteractiveAuthentication no +#UsePAM yes +``` + +Test the setting + +```sh +sshd -t +``` + +Reload: + +```sh +service sshd reload +``` + +# PF + +Note, if you're using Bastille, the `/etc/pf.conf` file is going to look different. See [Bastille](../../containers/Bastille/Bastille.md). + +Now we need to get the filewall going. + +```sh +nvim /etc/pf.conf +``` + +Contents: + +``` +ext_if="em0" +block in all +pass in on $ext_if proto tcp to ($ext_if) port ssh +pass in on $ext_if proto tcp to ($ext_if) port 80 +pass in on $ext_if proto tcp to ($ext_if) port 443 +pass out all keep state +``` + +```sh +sysrc pf_enable=yes +service pf start +``` + +If you get the error 'no host key files found` then + +```sh +ssh-keygen -A +``` diff --git a/os/FreeBSD/FreeBSD_on_RPI.md b/os/FreeBSD/FreeBSD_on_RPI.md new file mode 100644 index 0000000..19f11b5 --- /dev/null +++ b/os/FreeBSD/FreeBSD_on_RPI.md @@ -0,0 +1,94 @@ +# General + +Default username passwords are: + +``` +freebsd +freebsd +``` + +and + +``` +root +root +``` + +```sh +ssh freebsd@192.168.1.108 +``` + +Setup ntpd + +You need to make sure that your date is close to the real time + +```sh +date 202406211441 +``` + +Set the timezone + +```sh +tzsetup +``` + +```sh +sysrc ntpd_enable=YES +``` + +Set the time: + +```sh +ntpdate -v -b in.pool.ntp.org +``` + +Start the service + +```sh +service ntpd start +``` + +Update the system + +```sh +pkg update +``` + +Install my favorite packages + +```sh +pkg install bash sudo tmux htop neovim git bastille +``` + +Add "wheel" to the suoers file: + +```sh +visudo +``` + +Change shell + +```sh +chsh -s /usr/local/bin/bash +``` + +Add a user + +```sh +adduser +``` + +Change the hostname + +```sh +sysrc hostname="rp4-8" +``` + +Delete the freebsd user that comes with the standard installation: + +```sh +rmuser freebsd +``` + +* [SSH instructions](FreeBSD_on_Lenovo_Thinkcentre.md#ssh) +* [PF instructions](FreeBSD_on_Lenovo_Thinkcentre.md#pf). Be careful, the network interface on the PI is called `genet0` not `em0`. diff --git a/os/FreeBSD/Storage.md b/os/FreeBSD/Storage.md new file mode 100644 index 0000000..d12fba1 --- /dev/null +++ b/os/FreeBSD/Storage.md @@ -0,0 +1,53 @@ +# Storage + +First we need to know what drives we have: + +```sh +geom disk list +``` + +Show the partitions: + +```sh +gpart show +``` + +In FreeBSD the partitions are named with suffix `pX`, for example `p1`, `p2`, etc. + +To mount the first partition of the external harddrive: + +```sh +# directory needs to exist +mkdir /mnt/usb + +# mount the first partition p1 +mount -t /dev/da0p1 /mnt/usb +``` + +# ZFS + +The handbook is actually quite comprehensive: + +* https://docs.freebsd.org/en/books/handbook/zfs/ + +In order for ZFS to work, we need to enable it. On the Raspberry PI it is not enabled by default. + +```sh +service zfs enable +service zfs start +``` + +You need empty space, either an empty partition or drive. + +# Mounting different filesystems (for example, a USB SDD) + +For ext4, see: https://docs.freebsd.org/en/books/handbook/filesystems/index.html#filesystems-linux + +For NTFS, see: https://docs.freebsd.org/en/books/handbook/disks/#using-ntfs + +Take into account that NTFS uses "Slices", not "Partitions" so mounting the external NTFS harddrive on the Raspberry PI looks like this: + +```sh +ntfs-3g /dev/da0s1 /mnt/usb +``` + diff --git a/ssh.md b/ssh.md new file mode 100644 index 0000000..b7aeb21 --- /dev/null +++ b/ssh.md @@ -0,0 +1,4 @@ +```sh +eval `ssh-agent -s` && ssh-add -k +ssh -t -A moni@143.179.250.91 -p 32222 ssh moni@192.168.1.10 +```