Alpine Linux Musl += (btrfs + gummiboot) >> Eventually

Installation:
{
    # setup-alpine: >> Will be replaced eventually with manual install with btrfs and gummiboot, instead of default ext4 and grub.
    {
        \
    }
    # reboot
    $ doas vim /etc/apk/repositories:
    {
        > {v3.15/main}
        > {v3.15/community}
        > {edge/main}
        > {edge/community}
        > {edge/testing}
    }
}
Post install:
{
    # apk add git
    # git clone https://git.bijl.us/luc/alpine-server.git

    ups(client):
    {
        # apk add nut build-base
        # gcc alpine-server/config-files/ups.c -o /bin/ups
        # gcc alpine-server/config-files/exec-ups.c -o /bin/exec-ups
        # vim /etc/init.d/ups:
        {
            > #!/sbin/openrc-run
            > name="ups"
            > command="/bin/exec-ups"
        }
        # rc-update add ups
        # rc-service ups start
    }
    acf:
    {
        # apk add acf
        $ setup-acf
        # vim /etc/mini_httpd/mini_httpd.conf:
        {
            > port=444
        }
    }
    rsnapshot: << May be substituted with duplicati!
    {
        # apk add rsnapshot
        # cp /etc/rsnapshot.conf.default /etc/rsnapshot.conf
        # vim /etc/rsnapshot.conf:
        {
            > snapshot_root /media/data/backup

            > retain daily 7
            > retain weekly 4
            > retain monthly 12

            > backup /home/ localhost/
            > backup /etc/ localhost/
            > backup /usr/local/ /localhost 
            > backup /opt/ /localhost 
            > backup /var/lib/docker/ /localhost 
        }
        # vim /etc/periodic/{*}/rsnapshot: 
        {
            > #!/bin/sh
            > exec /usr/bin/rsnapshot {*}
        }
        # chmod +x /etc/periodic/{*}/rsnapshot
        # rc-update add crond
        # rc-service crond start
    }
    apk-autoupdate : << Does not work possibly.
    {
        # apk add apk-autoupdate
        # vim /etc/periodic/weekly/apk-autoupdate:
        {
            > #!/bin/sh
            > exec /usr/sbin/apk-autoupdate
        }
    }
    Samba:
    {
        # apk add samba
        # vim /etc/samba/samba.conf:
        {
            > [global]
            > allow insecure wide links = yes
            > dos charset = cp866
            > unix charset = utf-8
            > workgroup = WORKGROUP
            > server string = Samba Server

            > [home{user}]
            > comment = homedir{user}
            > valid_users = {user}
            > path = /home/{user}
            > browseable = yes
            > writable = yes
        }
        # rc-update add samba
        # rc-service samba start
    }
    ssh:
    {  
        # apk add openssh fail2ban
        # rc-update add sshd
        # rc-service sshd start
        # rc-update add fail2ban
        # rc-service fail2ban start
    }
    Docker:
    {
        # apk add docker docker-compose
        # addgroup <user> docker
        # rc-update add docker boot
        # service docker start

        portainer:
        {
            # cp alpine-server/config-files/portainer.yml /opt/docker-compose.yml
            $ cd /opt/
            $ docker-compose up -d 
        }
        traefik:
        {
            + Add stack << traefik.yml
        }

        watchtower:
        {
            Image: containerrr/watchtower:latest
            Volumes:
            {
                /etc/localtime:/etc/localtime:ro
                /var/run/docker.sock:/var/run/docker.sock
            }
            Network: bridge
            Environment:
            {
                WATCHTOWER_NOTIFICATION_EMAIL_FROM = info@{domain}
                WATCHTOWER_NOTIFICATION_EMAIL_TO=user@{domain}
                WATCHTOWER_NOTIFICATION_EMAIL_SERVER=mail.{domain}
                WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PORT=465
                WATCHTOWER_NOTIFICATION_EMAIL_SERVER_USER=info
                WATCHTOWER_NOTIFICATION_EMAIL_SERVER_PASSWORD={passwd}
                WATCHTOWER_NOTIFICATION_EMAIL_DELAY=2
                WATCHTOWER_NOTIFICATIONS=email
                WATCHTOWER_SCHEDULE=0 0 0 * * 6
                WATCHTOWER_CLEANUP=true
                WATCHTOWER_DEBUG=true
            }
            Restart: Unless-stopped
        }

        duplicati:
        {
            Image: ghcr.io/linuxserver/duplicati:latest
            Ports: 8200:8200/tcp
            Volumes:
            {
                /backups:/var/backups
                /source:duplicati-source - local
                /config:/opt/duplicati
                /source/host_home:/home:ro
                /source/host_etc:/etc:ro
                /source/host_opt:/opt:ro
                /source/host_usr_local:/usr/local:ro
            }
            Network: bridge
            Environment:
            {
                PIUD=0
                PGID=0
                TZ=Europe/Amsterdam
            }
            Restart: Unless-stopped
        }

        webserver:
        {
            Image: httpd:latest
            Volumes:
            {
                /usr/local/apache2/htdocs
                /opt/{webserver}/html
            }
            Network: proxy
            Labels: << traefik.labels
            Restart: Unless-stopped
        }

        postgres:
        {
            Image: postgres:latest
            Volumes:
            {
                /backup:/opt/postgres
                /etc/localtime:/etc/localtime:ro
                /var/lib/postgresql/data:postgres - local
            }
            Network: proxy
            Environment: 
            {
                POSTGRES_PASSWORD={passwd}
                PGDATA=/var/lib/postgresql/data
            }
            Labels: com.centurylinklabs.watchtower.monitor-only: "true"
            Restart: Unless-stopped

            Manual backup database:
            {
                $ docker exec -it postgres sh -c "pg_dump -U postgres -d {database} |gzip /backup/{database}.gz"
            }
            Manual reload database:
            {
                $ # docker exec -it postgres sh -c "gunzip -c {dbname.gz} | psql -U postgres -d {dbname}"
            }
        }

        postgresbackup:
        {
            Image: prodrigestivill/postgres-backup-local:latest
            Volumes:
            {
                /backups:/opt/postgresbackup
                /var/lib/postgresql/data:postgresbackup - local
                /etc/localtime:/etc/localtime:ro
            }
            Network: proxy
            Environment:
            {
                POSTGRES_HOST=postgres
                POSTGRES_DB={db0,db1,...,db{n}}
                POSTGRES_USER=postgres
                SCHEDULE=@daily
                BACKUP_KEEP_DAYS=1
                BACKUP_KEEP_WEEKS=1
                BACKUP_KEEP_MONTHS=1
                BACKUP_DIR=/backups
            }
            Labels: com.centurylinklabs.watchtower.monitor-only: "true"
            Restart: Unless-stopped

            Reload database:
            {
                # mv /opt/postgresbackup/{dbname.sql.gz} /opt/postgres
                $ docker exec -it postgres sh -c "zcat /backup/{dbname.sql.gz} | psql -U postgres -d {dbname}"
            }
        }
        
        vaultwarden:
        {
            $ docker exec -it postgres /bin/bash
            # psql -U postgres:
            {
                > create database vaultwarden;
            }

            Image: vaultwarden/server:latest
            Volumes:
            {
                /data:/opt/vaultwarden/data
                /etc/localtime:/etc/localtime:ro
            }
            Network: proxy
            Environment:
            {
                ADMIN_TOKEN={admin_token} >> Remove to disable admin page.
                SIGNUPS_ALLOWED=true/false
                DATABASE_URL=postgresql://postgres:{passwd}@postgres/vaultwarden
            }
            Labels: << traefik.labels
            Restart: Unless-stopped
        }

        gitea:
        {
            $ docker exec -it postgres /bin/bash
            # psql -U postgres:
            {
                > create database gitea;
            }

            Image: gitea/gitea:latest
            Volumes:
            {
                /data:/opt/gitea
                /etc/localtime:/etc/localtime:ro
                /etc/timezone:/etc/timezone:ro
            }
            Network: proxy
            Environment:
            {
                USER_UID=1000
                USER_GID=1000
                GITEA__database__DB_TYPE=postgres
                GITEA__database__HOST=postgres
                GITEA__database__NAME=gitea
                GITEA__database__USER=postgres
                GITEA__database__PASSWD={passwd}
                USER=git
                GITEA_CUSTOM=/data/gitea
            }
            Labels: << traefik.labels
            Restart: Unless-stopped
        }
    }
    matrix:
    {
        synapse:
        {
            $ docker exec -it postgres /bin/bash
            # psql -U postgres:
            {
                > create database synapse with encoding='UTF8' lc_collate='C' lc_ctype='C' template=template0;
            }

            $ docker run -it --rm --mount type=volume,src=synapse-data,dst=/data -e SYNAPSE_SERVER_NAME=matrix.{domain} -e SYNAPSE_REPORT_STATS=no matrixdotorg/synapse:latest generate
            $ docker run -d --name synapse --mount type=volume,src=synapse-data,dst=/data matrixdotorg/synapse:latest
            >> May be improved!

            Network: proxy
            Labels: << traefik.labels
            Restart: Unless-stopped

            # vim /var/lib/docker/volumes/synapse-data/_data/homeserver.yaml:
            {
                > server_name: "matrix.{domain}"

                > database:
                >   name: psycopg2
                >   txn_limit: 10000
                >   allow_unsafe_locale: false
                >   args:
                >       user: postgres
                >       password: "{passwd}"
                >       database: synapse
                >       host: postgres
                >       cp_min: 5
                >       cp_max: 10

                > enable_registration: true/false
                > enable_registration_without_verification: true

                > app_server_config_files:
                >   - /data/mautrix/whatsapp/registration.yaml
                >   - /data/mautrix/signal/registration.yaml
            }
        }
        mautrix-whatsapp:
        {
            $ docker exec -it postgres /bin/bash
            # psql -U postgres:
            {
                > create database mautrixwhatsapp;
            }

            Image: dock.mau.dev/mautrix/whatsapp:latest
            Volumes:
            {
                /data:/var/lib/docker/volumes/synapse-data/_data/mautrix/whatsapp
                /etc/localtime:/etc/localtime:ro
            }
            Network: proxy
            Restart: Unless-stopped

            # vim /var/lib/docker/volumes/synapse-data/_data/mautrix/whatsapp/config.yaml:
            {
                > homeserver:
                >   address: http://synapse:8008
                >   domain: matrix.{domain}
                
                > appservice:
                >   address: http://mautrix-whatsapp:29318
                >   hostname: 0.0.0.0
                >   port: 29318
                >
                >   database:
                >       type: postgres
                >       uri: postgres://postgres:{passwd}@postgres/mautrixwhatsapp?sslmode=disable
                
                > bridge:
                >   private_chat_portal_meta: true
                >   encryption:
                >       allow: true
                >       default: true
                >
                >   permissions:
                >       "*": relay
                >       "matrix.{domain}": user
                >       "@admin:matrix.{domain}": admin
            }
            # vim /var/lib/docker/volumes/synapse-data/_data/mautrix/whatsapp/registration.yaml:
            {
                > url: http://mautrix-whatsapp:29318
                > regex: << matrix.{domain}
            }
        }
        mautrix-signal:
        {
            $ docker exec -it postgres /bin/bash
            # psql -U postgres:
            {
                > create database mautrixsignal;
            }

            Image: dock.mau.dev/mautrix/signal:latest
            Volumes:
            {
                /data:/var/lib/docker/volumes/synapse-data/_data/mautrix/signal
                /etc/localtime:/etc/localtime:ro
            }
            Network: proxy
            Restart: Unless-stopped

            # vim /var/lib/docker/volumes/synapse-data/_data/mautrix/whatsapp/config.yaml:
            {
                > homeserver:
                >   address: http://synapse:8008
                >   domain: matrix.{domain}
                
                > appservice:
                >   address: http://mautrix-signal:29328
                >   hostname: 0.0.0.0
                >   port: 29328
                >
                >   database: postgres://postgres:{passwd}@postgres/mautrixsignal

                > signal:
                >   socket_path: /data/signald/signald.sock
                
                > bridge:
                >   private_chat_portal_meta: true
                >   encryption:
                >       allow: true
                >       default: true
                >
                >   permissions:
                >       "*": relay
                >       "matrix.{domain}": user
                >       "@admin:matrix.{domain}: admin
            }
            # vim /var/lib/docker/volumes/synapse-data/_data/mautrix/whatsapp/registration.yaml:
            {
                > url: http://mautrix-signal:29328
                > regex: << matrix.{domain}
            }
        }
        signald:
        {
            >> postgres database not yet available! (sqlite database)

            Image:docker.io/signald/signald:latest
            Volumes:
            {
                /signald:/opt/matrix/mautrix-signal/signald
                /etc/localtime:/etc/localtime:ro
            }
            Network: proxy
            Restart: Unless-stopped
        }
        element:
        {
            Image: vectorim/element-web:latest
            Volumes:
            {
                /app/config.json:/opt/matrix/element/config.json
                /etc/localtime:/etc/localtime:ro
            }
            Network: proxy
            Labels: << traefik.labels
            Restart: Unless-stopped

            # vim /opt/matrix/element/config.json:
            {
                {
                    "default_server_config": {
                    "m.homeserver": {
                        "base_url": "https://matrix.{domain}",
                        "server_name": "matrix.{domain}"
                    },
                    "m.identity_server": {
                        "base_url": "https://vector.im"
                    }
                    },
                    "disable_custom_urls": true,  
                    "room_directory": {
                        "servers": ["matrix.org", "matrix.{domain}"]
                    },
                    "default_theme": "dark"
                }
            }
        }
    }
    homeassistant:
    {
        mosquitto:
        {
            Image: eclipse-mosquitto:latest
            Volumes:
            {
                /mosquitto/data:/opt/mosquitto/data
                /mosquitto/log:/opt/mosquitto/log
                /mosquitto/config:/opt/mosquitto/config
            }
            Network:
            {
                proxy
                ipv4: 172.21.0.12
            }
            Restart: Unless-stopped

            # vim /opt/mosquitto/config/password.txt:
            {
                > {username}:{passwd}
            }
            # vim /opt/mosquitto/config/mosquitto.conf:
            {
                > persistence true
                > persistence_location /mosquitto/data
                > log_dest file /mosquitto/log/mosquitto.log

                > listener 9001
                > listener 1883
                > connection_messages true

                > allow_anonymous false
                > password_file /mosquitto/config/password.txt
            }
        }
        ecowitt:
        {
            Image: bachya/ecowitt2mqtt:latest
            Ports: 8181:8181/tcp
            Network: proxy
            Environment:
            {
                COWITT2MQTT_MQTT_BROKER=mosquitto
                ECOWITT2MQTT_MQTT_USERNAME={username}
                ECOWITT2MQTT_MQTT_PASSWORD={passwd}
                ECOWITT2MQTT_PORT=8181
                ECOWITT2MQTT_HASS_DISCOVERY=true
                ECOWITT2MQTT_INPUT_UNIT_SYSTEM=imperial
                ECOWITT2MQTT_OUTPUT_UNIT_SYSTEM=metric
            }
            Restart: Unless-stopped
        }
        esphome:
        {
            Image: esphome/esphome:latest
            Ports: 6052:6052/tcp
            Volumes:
            {
                /config:/opt/esphome
                /etc/localtime:/etc/localtime:ro
            }
            Network: host
            Environment:
            {
                USERNAME={username}
                PASSWORD={passwd}
            }
            Restart: Unless-stopped
        }
        homeassistant:
        {
            $ docker exec -it postgres /bin/bash
            # psql -U postgres:
            {
                > create database homeassistant;
            }

            Image: homeassistant
            Volumes:
            {
                /config:/opt/homeassistant/config
                /etc/localtime:/etc/localtime:ro
            }
            Network: proxy
            Labels: << traefik.labels
            Restart: Unless-stopped

            # vim /opt/homeassistant/config/configuration.yaml:
            {
                > python_script:

                > shell_command:
                
                > http:
                >   use_x_forwarded_for: true
                >   trusted_proxies:
                >       - 172.21.0.80

                > panel_iframe:
                >   portainer:
                >       title: "Portainer"
                >       url: "http://{ip}:9000/#/containers"
                >       icon: mdi:docker
                >       require_admin: true
                >   esphome:
                >       title: "ESPHome"
                >       url: "http://{ip}:6052"
                >       icon: mdi:chip
                >       require_admin: true

                > recorder:
                >   db_url: postgresql://postgres:{passwd}@postgres/homeassistant
            }
        }
    }
}  