[{"content":"Introduction I have Dispatcharr setup and it is amazing. Some sources I have come across have internet radio streams, including Sirius XM. I wanted an easy way to listen to this on my computer, and I wanted to know what was playing.\nAs a continuation of my earlier post on coding with AI tools, I am breaking down the full process to create this app, from concept to ongoing support.\nConcept I started by looking at existing radio web players by popular services and concepts I found online. What did I like about them, what didn\u0026rsquo;t I like.\nI then drew sketches of what I wanted it to look like on my iPad. This is something I started doing on paper years ago for web design. Just a rough sketch of the general layout of what I\u0026rsquo;m making. Once I got an update they became digital and in color, but not any nicer looking.\nI started talking about this on the Dispatcharr Discord and got in touch with @jstevenscl. He created https://stellartunerlog.com/ , an API for Sirius XM data including information, pictures, now playing info, and more. It\u0026rsquo;s exactly what I needed for this project. I worked with him and looked through the documentation for it to see what all I would want to use.\nI have a rough idea of the layout of the app and I have a source for information. How do I make this data usable for Claude Code to actually build the app? Claude Design is perfect for this.\nI explained what I was making, the style I wanted for the app, and explained the sketch I created. After some back and forth we had an entire design system for Claude and myself to work off of.\nThis app was initially going to be called Pulsar but was changed due to conflicts with related projects.\nInitial App At this point time to actually start coding. I grabbed the handoff prompt from Claude Design and gave it to Claude Code. I gave the prompt to Opus , and had it create a detailed plan file to create what we planned.\nThen I cleared context and told Opus to read the plan file and design docs, then use sub agents to do each task one at a time. Using sub agents keeps context windows from overflowing.\nEach task gets its own context window and the main agent has an overview of the entire project. The main agent knows exactly what to tell the sub agent for each step because it knows what was done and what needs to happen. Sub agents also let us save some costs by using cheaper models, because this is gonna be a lot of code.\nImprovements Taking a look at our initial build, things are progressing well. It looks just like our plans, and if conditions are perfect, it plays a steram. We can improve.\nI added better stream handling so the app can recover from interuptions. The UI was tweaked and tuned so make things more readable and fix glitches. We also added a list view to channels so we can display now playing artist info.\nFixed logos and some more polish brought us to this: Logo If you noticed in the above screenshot, the app now has a logo! Claude Design also helped with that. In a new session I gave it the app\u0026rsquo;s colors and themeing/vibe I was looking for and it presented some concepts.\nOnce we finalized on one I downloaded it as SVG, and gave it to Claude Code. Since an SVG is a vector format, we can make a copy at any resolution.\nFeatures Once I got the app working, I asked myself, what else can we do? So I started adding in my favorite features from other apps I\u0026rsquo;ve used in the past.\nMusic Visualizer I have always thought music visualizers look so cool. I created a loopback device in the app to capture the audio from it and create a real visualizer that reacts to the actual audio.\nLast.FM Scrobbling Alerts You can follow Tracks and Artists, and get alerts in the app, and in your OS, when they are playing on any channel.\nEqualizer Discord Integration I wanted it to match the styles of other music apps that integrate with Disocrd so it doesn\u0026rsquo;t look out of place.\nFinal Notes There are plenty more steps after this but I did not want this post to be too long. I might expand in the future.\nGithub - https://github.com/slamanna212/Apogee ","date":"2026-07-26T12:53:08-04:00","image":"https://slamanna.com/p/desktop-iptv-radio-player/cover_hu_d6bf261cc6b735e.jpg","permalink":"https://slamanna.com/p/desktop-iptv-radio-player/","title":"Apogee - I Built A Desktop Radio Player for IPTV Streams"},{"content":"Introduction I follow a lot of racing series from all over the world. Watching them is a huge challenge. Different time zones, different broadcast rights, this week on this channel, next week on that one, etc. Sometimes, theres no way for me as an American to watch, Super Formula before 2026 for example.\nThere are Internet TV providers all over the internet. Some of them legal, some of them less so. They contain TV channels from all over the world, a huge variety of networks. With this setup a race not being broadcast in my country is no longer a problem. Alone these channels don\u0026rsquo;t solve my issues.\nI can not and will not help you find sources. Do not contact me asking for help with this.\nOne of the common issues with them is like other internet grey areas, they come and go all the time. A provider here today could vanish over night. Another issue is that depending on your ISP and popularity of the event, you can have huge issues streaming, with stutters and freezing.\nI use an amazing app called Dispatcharr to solve all of that, and get the best of everything.\nDisclaimer I help Dispatarr dev team in a small capacity but do not do any coding work on the project. All the same, it felt right to share my connection to the project. Opinions and thoughts shared here are mine and do not represent Dispatcharr.\nGetting Dispatcharr The best way to install Dispatcharr is in Docker. It runs as a single container on any Linux or Mac host. It does work on Windows docker but there are extra bugs and it just doesn\u0026rsquo;t work as well in my opinion.\nYou can also run it on Kubernetes, and this is how I run it, but that is a more advanced setup.\nI will defer to the Dispatcharr Docs here, they are amazing and kept up to date: https://dispatcharr.github.io/Dispatcharr-Docs/installation/\nSetting Up Accounts First thing, add your sources to Dispatcharr. I have 3 total sources, and a 4th I\u0026rsquo;ll go over later. You can setup your sources via 2 main methods, XC or M3U.\nXC stands for Xtream Codes and is the most popular. It is faster and supports more features than the other method M3u. M3u does not stand for anything, it is the file extension.\nWe have multiple sources so if one source is having issues, Dispatcharr will automatically switch to a different source. These sources have a lot of overlap and that is what we want. There is a checkbox to add EPG for each source you add. Add at least 2 or 3 of these. Just like channels, we can mix and match EPG from multiple sources. EPG is guide data, letting you know what\u0026rsquo;s on each channel.\nFor each account you add, you will presented with a list of groups. Don\u0026rsquo;t feel like you need to add all of them, look through them and add the ones you care about. It seems slow and tedious but its one time work, and it will make the day to day use of the app much faster.\nCreating The Channel List This is completely up to you. Your channel listing can be broken up into groups and as we continue through this, you will see the benefits of that type of setup. I have a default group for a standard cable line up, a dedicated racing group for all my motor racing channels, and groups for other sports.\nYou can add as many channels as you want but I personally recommend not going above 1000. Dispatcharr can handle it, but its just too unwieldy and too much stuff to look through trying to watch something. Its a bad user experience.\nI also have secondary ABC and Fox affiliates. They are both in higher quality than my local affiliate. Another benefit is, in weather events, I can use the other affiliate to watch whatever the event is.\nThe Interface Here is the main interface of Dispatcharr. Left half is your channel listing, and right half are all of the channels from your provider. Press the little Green button on the right side to create a channel on the left.\nGo through and setup your basic lineup, you can edit this at any time in the future so don\u0026rsquo;t feel pressured. Just setup a basic list, leaving gaps between sections. Don\u0026rsquo;t forget, you can also do .1 channels, so Channel 4, 4.1, 4.2, and 4.3 can all coexist.\nBackup Sources Once you have your initial lineup, it\u0026rsquo;s time to go back through and add backups. Yes this is manual work, but again, one time and will lead to a much better day to day experience.\nUsing the search at the top right, search for each channel, and add all to each channel. You do this by selecting your channel on the left side, and then clicking the blue button that lights up next to channels on the right.\nWhen you click a channel on the left, a drop down opens and you can see all your sources. This is where Dispatcharr becomes unbeatable.\nEvery source you find for a channel will be a different quality. I am talking about things like resolution, bitrate, etc. We are using multiple sources and can use the best channels from each source, with the others as backups. This is why we want multiple sources.\nThe above example is for BBC One. I have 4 sources for this channel and they are ranked. If you watch a source, Dispatcharr remembers the media info like resolution, framerate, bitrate, and more. We can use this info to rank each channel as you can see I\u0026rsquo;ve done here.\n1 4K source so of course thats at the top, then a different source, then a different stream from the first source, then a 3rd different source.\nThis part is optional but leads to the best experience in my opinion.\nExtras and Plugins At this point you have a channel list setup and channels have backups. This is a solid setup and works well. You can stop here, but all of the \u0026ldquo;extras\u0026rdquo; and other things we can do are so worth it.\nOptions below are only stracting the surface, and a huge community has formed around the app constantly creating new things. You can watch the plugins tab but joining the Dispatcharr Discord is the best way to see new plugins coming out.\nVPN Sending all of your Dispatcharr traffic through a VPN will help with reliability and speed. I use Mullivad VPN, Wireguard with Gluetin. Ask your source where they are and pick a VPN close to there if possible.\nAuto Sync Channels Sometimes you will find sources that have channels that change daily. Sorts channels, PPV events, etc. Dispatcharr can handle those automatically through a feature called Auto Channel Sync. In the M3U \u0026amp; EPG Manager tab in Dispatcharr, click the yellow edit button for an M3U account, and then groups.\nClick the checkbox for Auto Channel Sync. Set what number the channels should start at, and advanced options via the settings gear.\nUse this sparingly, not for every channel you have. Using this for non event channels will break things and lead to issues.\nPlugins There is a plugin\u0026rsquo;s tab in Dispatcharr. A lot of great plugins covering various things can be found here. I use the Prometheus Exporter, IPTV Checker, and Tickarr.\nThe Prometheus Exporter plugin can be used to create Grafana Dashboards:\nTunarr This is only vaguely Dispatcharr related but it is in a bunch of screenshots so I wanted to explain. Tunarr lets you create live TV channels from your Plex or Jellyfin library. I have channels setup that when someone tunes into them, Tunarr starts playback. I use it for when I just want to watch mindless sitcoms or endless The Simpsons reruns (the good seasons!).\nResources Docs - https://dispatcharr.github.io/Dispatcharr-Docs/ GitHub - https://github.com/dispatcharr/dispatcharr Discord - https://discord.gg/Sp45V5BcxU ","date":"2026-07-24T19:57:56Z","image":"https://slamanna.com/p/live-tv-of-the-future/cover_hu_68a48212e8234e79.png","permalink":"https://slamanna.com/p/live-tv-of-the-future/","title":"Live TV of the Future"},{"content":"Introduction I started to use Claude Code when Anthropic released Sonnet 4.0 and Claude Code was first released. I have used to to create some very cool things and they will all be getting a write up soon. From basic things like a Discord Birthday Bot or Notification Router to complex projects like a Video Game Tournamanet Manager or a AstroJS Based Recipe Website. It has been a blast to create software and apps to fill niche needs in my life.\nBelow are a collection of tips I have learned along the way. I hope to help others create unique and cool projects. These tips apply to all AI coding tools but uses of Claude Code will benefit the most, as that is what I use.\nLearn Git This is arguably the most important tip in this post. Git is a source control system. Any time you change or modify your code, you save it, or in Git terms, you Commit it. This creates a history and a back up of your code.\nSuddenly notice a bug and want to know how it got there? Use Git to see when last those relevant files were touched. Not liking how something looks and want to go back to how it was before? Look through Git commits and grab the files that have the old layout.\nUsing Git also acts like a basic documentation system. Every time you make a commit, you must enter a message detailing what you did. If every commit has a good message, you can track what everything does.\nThere are tons of good resources to learn Git, some are: Microsoft Intro to Git, The Official Git Website, Oh My Git (A Game!).\nDev Setup Where you code depends on what you are comfortable with. Tools like Claude Code or Cursor run on every OS so its up to you. I am going to provide info on how I set up my setup.\nMy Setup I personally use a Linux VM on my proxmox server. I can connect to it from anywhere, and gave it plenty of RAM and CPU cores. I mostly make apps that run on linux, and like it, so its what I use.\nI run claude code in a terminal session, or command prompt window. You can follow their documentation to install it on your system. I use VS Code to review the code and commit to git. Not to get too meta but that is how I\u0026rsquo;m writing this post. Claude is fixing my structured data layout while I write this post. (It controls how Google and other search engines see my blog posts).\nUsage Limits Once claude finishes its task, I review and commit to Git. If I am working on something not directly related to what I just did, I type /clear and hit enter. This clears the model\u0026rsquo;s context window.\nEvery character of text you send in messages to the AI, every character of every file it reads, all of the thinking it does, all cost tokens. The more text, the more tokens used. The more tokens used, the faster you hit your usage limits.\nIf using Claude Code, usage limits are strange. The first message with claude starts a 5 hour timer. You have a set amount of usage inside of that 5 hour block. There is no set metric used for this and it appears to change over time. You can track usage by typing /usage . You will also notice a weekly limit. Same concept, but over an entire week.\nDifferent models have different \u0026ldquo;costs\u0026rdquo;. For Claude Code, Opus is the most expensive/capable, Sonnet is for every day work/a bit cheaper than opus, Hiku is for quick and easy tasks/cheap to use. I personally never directly use the Hiku model. Sometimes Opus and Sonnet will launch Hiku subagents to look through the codebase. A sub agent is just another copy of the AI launched by the parent AI to help it.\nPersonally, I use Opus to plan a project, and then write a detailed plan to create it, divided into phases. I then save that file as the first file committed to the Git repo for that project. I then use Sonnet to execute the plan. Sonnet does most of the work, but we benefit from the increased knowledge of the pricer model.\nPlan Ahead This may sound obvious, but have a solid plan before you start coding. You should be able to answer the below questions, and more, before you start coding.\nWhat is the point of this project? What will it do? What will it look like visually? How will it store data Does it need a database? If Yes, what data will be stored, and in what table structure (The AI can help figure this out.) Will it need to connect to any external API\u0026rsquo;s or services? How will you test what you make? (The AI and Code Maintainability section can help.) First figure out where you want your project to run. Will it be a mobile only app, a website, a Windows desktop app, a linux terminal app, etc. I personally like web apps. Hosting is free on things like Cloudflare workers, when I update the code, everyone has the newest version right away, and it works on all devices. Once you know where your project will run, you can work with the AI to plan the technologies and programming languages you will use.\nOnce you know all of this, have your AI of choice generate a full plan to create your project. That is the first file you commit to Git. You and your AI will then work off of that file and create it.\nResearch Your Idea Again, this might sound obvious, but make sure what you are making doesn\u0026rsquo;t already exist. Do some quick internet searches, so you don\u0026rsquo;t reinvent the wheel. It will just be a waste of tokens and your sanity.\nCoding Workflow Now that everthing is setup, it\u0026rsquo;s time to actually create. For me, its broken down into 2 main phases.\nCreate a Plan For this, I use the claude website, claude.ai and the current biggest model. At time of writing, it is Opus 4.6.\nI explain what I want to make, what technologies and programming languages I want to use, Features I want it to have, how I want it to look and how I want it to work. Don\u0026rsquo;t know this info? Just ask the AI to help fill in the holes. When you are happy with the plan, tell the AI to write it to a markdown file, broken down into steps with checkboxes. Download this file\nExecuting The Plan Create a git repo for your project, upload the plan file we made with opus. Start Claude Code and select your preferred model, I use Sonnet for this. Tell Claude Code to read the plan , start executing it, and keep track of its progress with the checkboxes. All you do at that point is monitor what its doing and respond to the AI asking to use commands and tools.\nIf it wants to install a tool, take note of the tool it wants and then close claude code. You will see a line about resuming the session, copy that command. Install the tools then use that command to return to your existing session. Tell claude it now has the tools and to continue.\nCode Maintainability Ok, you\u0026rsquo;ve made your plan, you have started to code, and you can preview your creation and it is starting to look amazing. It\u0026rsquo;s time to make sure the code is good safe. There are a couple different methods we will discuss.\nIf you are using VS Code, you can make Tasks for these and make running them very easy. More info is available here, but you can also just ask your AI for help creating them.\nDependabot This is GitHub specific but a very useful feature. If your project uses dependencies like Python modules on NPM packages, dependabot will keep them up to date for you.\nWhen new versions release, it will create Pull Requests so you can easily update your project. If you have the below checks setup, they can also be run on these pull requests to verify they wont break things.\nLinting Most languages support linting. It analyzes the code to check for potential errors or illegal operations. It\u0026rsquo;s a way to check the AI\u0026rsquo;s work. It helps to ensure the code will run or build without errors.\nYou can ask your AI: \u0026ldquo;If possible, set up linting for this project\u0026rdquo;. It will create the necessary files and tell you how to use it. Every time you add a new feature or change a feature, run a lint check before you commit.\nBuild Checks If you want to go one step further than linting, you can do a test build of the app. It will depend on your language, but like linting, just ask the AI to help you setup build tests.\nUnit Tests You can ask your AI to help you create unit tests. I only recommend these for more complex projects, and only if you can read the language you are working in. AI coding is known for making unit tests that don\u0026rsquo;t actually test anything.\nAutomation Doing these tests manually is great, but having them happen automatically is even better. There are 2 main ways I do this.\nPre Commit Hooks In some of my projects, I have precommit hooks setup. On my recipe website, when I add a recipe, dominiate colors are pulled from the cover image to be used throughout the UI. For my MatchExec app, Lint, Build, and Unit tests run when I commit files.\nGithub Actions/CI GitHub actions can be used to do a lot of this testing for you, in the cloud. You can ask your AI to help write GitHub Action Workflows to have the above tests or other things happen on a schedule, or for other actions like opening a pull request or merging to specific branches.\nA lot of projects I make can be deployed as docker containers. I use GitHub actions to build these docker images so once I commit to main, the entire release is automated.\nThe ideal setup for your branches to best use these GitHub Actions would be:\nMain - This is your production, or main branch. This is the live app/code Dev - This is your Pre production, or testing branch. The code here is ready for release, it just needs final testing FeatureBranches - These are named whatever you are working on. NewPage , ScoringUpdate, WhateverYouWant. You create a feature branch, write your code, commit it. Once the feature is done, you create a pull request to merge it to Dev. Workflows you setup , run, to ensure the code lints and builds, and wont break anything.\nOnce they pass you commit to Dev. You have something running this dev version. You play with it, make sure it works well, then create a PR to merge from Dev to main. You could have even stricter workflows here to make sure the code is perfect, and then merge to main.\nOnce code is merged to the main branch, your project gets built and distributed. This could be uploading to an app store, deploying to web servers, or soemthing else.\nClaude Code Extras These features might exist in other AIs, but I\u0026rsquo;ve only used them in Claude Code.\nSkills You can create special instruction files for claude to follow, to do specific repeatable tasks. My MatchExec project has one to give me a summary of all of the changes made in a feature branch and helps me create pull request notes and a testing plan. I just type /feature-test and it gets to work. Documentation\nPlugins Plugins are a marketplace of slash commands, agents, MCP servers, and others. They extend the functionality of Claude. You can view the marketplace with /plugins.\nI use the frontend-desinger slash command from Anthropic to help design web UIs. I also greatly use the Playwright plugin to help diagnose web page issues and test functions. Info\nFinal Notes This post is only the start. Depending on what languages you are creating in, there could be more or less steps involved.\nThis is a rapidly evolving technology, even for the tech field. Stay up to date with your AI\u0026rsquo;s website and blog, and internet groups.\nIf you are a visual learner like me, I released a sort of part 2 walking through the entire process I used to build a desktop app, read more here.\n","date":"2026-02-11T22:06:23-05:00","image":"https://slamanna.com/p/ai-code-getting-started/cover_hu_179f313ec6f4fdc6.jpg","permalink":"https://slamanna.com/p/ai-code-getting-started/","title":"Coding with LLM based Artificial Intelligence"},{"content":"Introduction I recently encountered an issue with a niche application accessed with Citrix Workspace. The company who provides this solution has specific requirements for the version of Citrix Workspace you use to access the software. There were 40 computers with various versions, paths, and settings that needed fixing.\nDoing this by hand would not be realistic. Luckily, this environment uses Connectwise Automate so I can script all of this. This will work on other platforms, just with tweaks to platform specific terms. I would first need to uninstall any version of Citrix Workstation that was not 2404 LTSR, the specific version the host wanted. Then we would have to install the correct version with the specific settings required.\nUninstalling Citrix Workspace Surprisingly this was the hardest part of this entire process. Every version of Citrix Workspace has a unique name, the version number is included. This means unique file paths and program names for every version. Powershell does not handle wildcards very well and would say it uninstalled the program but would not actually uninstall it.\nI found a registry key that is the same for every version I tested of Citrix Workspace. This key lists the command to run when you click uninstall in Add/Remove Programs. In Automate, I use powershell to read that registry key and save it to a variable using this command:\n1 (Get-ItemProperty -Path HKLM:\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\CitrixOnlinePluginPackWeb -Name UninstallString).UninstallString Then I run a shell command with that variable, but with /silent added ot the end. This installs whatever version the computer has, and does it in the background. This prevents pop ups that could alarm end users.\nInstalling Citrix Workspace This part was very simple. Most options for Workspace can be set with flags. I downloaded the correct installer for Workspace and put it on the LabTech share so the script can pull it to workstations. The full command used is:\nCitrixWorkspaceLTSR2402.exe /silent /noreboot /AutoUpdateStream=LTSR /AutoUpdateCheck=disabled\n/silent Makes the install happen in the background /noreboot So the workstations do not reboot after the install /AutoUpdateStream=LTSR This makes sure the only updates the program will take are long term support releases, but this is just a backup. We will be disabling updates next. /AutoUpdateCheck=disabled The program needs to stay on this version, so update checks are disabled. Preventing Updates All of this work to install the correct version could be undone if it updates. Update checks were disabled when the program was installed, but more can be done. Per documentation, we can disable updates with a registry key.\nThis registry was deployed to all workstations with Group Policy, but anything can be used to do that. In every available way, updates were disabled. If something happens and a setting changes, updates will still not happen.\nFinal Notes You could also create dataviews to automate further. If Citrix Workspace is installed and it isn\u0026rsquo;t 2402, run the uninstaller script. Then , if no Citrix Workspace is installed, run the installer script.\nConnectWise Automate does not do any kind of download sharing over LAN. If you run the installer script against 40 computers in one location, all 40 download the file. This can and will fully saturate a locations WAN connection if you are not careful.\n","date":"2024-11-30T13:04:53-05:00","image":"https://slamanna.com/p/citrix-workspace-lifecycle/cover_hu_9a3760872455d627.webp","permalink":"https://slamanna.com/p/citrix-workspace-lifecycle/","title":"Automating the Lifecycle of Citrix Workspace"},{"content":"Introduction In part 1, we went over the architecture and layout of the servers that host websites for me. As the servers come and go as needs require, creating new websites can be challenging. It also becomes very time consuming as you add more servers or roles to the cluster.\nThe entire Github repo for this cluster is now public! You can view it or grab a copy here.\nRequirements An understanding of the cluster and its parts, available in Part 1 of this series, available Here. An understanding of PHP website hosting. The Playbook We will be going over the NewWordpressSite.yml playbook, available here.\nGetting Started 1 2 3 4 5 6 ######################################################### # Create New Wordpress Site ######################################################### --- - hosts: database_master[0]:wpadmin[0] become: true This section is really easy, it just tells Ansible that the playbook is going to use the first database master server and the first Wordpress admin server.1 The database syncs in real time, so as data is created on the master, the information will be on the other DB servers before the playbook finishes. The playbook will be placing system files and become makes that easier.\nCreate the Database 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 # DB Config - hosts: database_master[0] vars_prompt: - name: sqluser prompt: Please provide an SQL username private: no - name: sqlpass prompt: Please Provide an SQL Password - name: sqlname prompt: Please provide an SQL database name private: no tasks: - name: Create a new database for website\u0026#39; community.mysql.mysql_db: name: \u0026#34;{{ sqlname }}\u0026#34; state: present - name: Create database user and great access to database community.mysql.mysql_user: name: \u0026#34;{{ sqluser }}\u0026#34; password: \u0026#34;{{ sqlpass }}\u0026#34; priv: \u0026#39;{{ sqlname }}.*:ALL\u0026#39; host: 10.123.0.% state: present - name: \u0026#34;Add SQL info to dummy host for use later in this playbook\u0026#34; add_host: name: \u0026#34;SQLINFOHOLDER\u0026#34; sqluser: \u0026#34;{{ sqluser }}\u0026#34; sqlpass: \u0026#34;{{ sqlpass }}\u0026#34; sqlname: \u0026#34;{{ sqlname }}\u0026#34; All of these tasks will happen on the database master server. The playbook first asks for database information: Username, Password, and Database name. If you are using a non interactive session (AWX, Semaphore, cron) you can pass these with --extra-vars.2\nOnce the playbook has that information it creates the database and then grants the correct user permissions. The web server will need this information later but we run into an issue. Ansible does not persist variables between hosts in a playbook. I got around this by storing this information as an extra host, it will only exist while the playbook is running.\nWeb Server Configuration 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 # Nginx Config - hosts: wpadmin[0] vars_prompt: - name: domain prompt: What is the domain of the website private: no - name: domain2 prompt: Is there a second domain for the website, like www.domain.com | Leave blank if no private: no tasks: - name: Create site directory if missing become: yes become_user: root ansible.builtin.file: path: /mnt/Web/Websites/Wordpress/{{ domain }} state: directory - name: Add Nginx vhost for website become: yes become_user: root template: src=templates/wpnginxvhost dest=/mnt/Web/VHosts/{{ domain }} backup=no owner=www-data group=www-data mode=0644 - name: \u0026#34;Add domain info to dummy host for use later in this playbook\u0026#34; add_host: name: \u0026#34;WEBINFOHOLDER\u0026#34; domain: \u0026#34;{{ domain }}\u0026#34; For a standard \u0026ldquo;normal\u0026rdquo; website, 2 subdomains point to the website, WWW and @ or blank. The playbook asks for 2 domains to account for this.\nIf this is the case you put domain.com for the first question, and www.domain.com for the second question. If the website exists on a subdomain, like blog, you answer the first question with blog.domain.com and leave domain 2 blank. I always have WWW set as a CNAME of @ at the DNS level, but leave this as a backup for flexibility.\nThe playbook is configuring the web servers , but uses the Wordpress Admin server to do it. This ensures that the public facing web nodes ONLY SERVE WEBSITES. The domain is used as the folder name in our web directory and Nginx virtual host name. The Nginx virtual host uses a template file for domain information.\nRemember that this is our shared storage so its already available for all of the web servers to use. We use the domain as that makes maintenance and updates easier(More info in a future blog post).\nJust like the Database step, the playbook adds more info to the \u0026ldquo;dummy\u0026rdquo; host to use later.\nWordpress Install and Configuration 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 # Wordpress Config - name: Download and extract wordpress files become: yes become_user: root ansible.builtin.unarchive: src: https://wordpress.org/latest.tar.gz dest: /mnt/Web/Websites/Wordpress/{{ domain }}/ remote_src: yes - name: Move wordpress files to public directory become: yes become_user: root command: mv /mnt/Web/Websites/Wordpress/{{ domain }}/wordpress /mnt/Web/Websites/Wordpress/{{ domain }}/public_html - name: Add custom WP-Config become: yes become_user: root template: src=templates/wp-config.php dest=/mnt/Web/Websites/Wordpress/{{ domain }}/public_html/wp-config.php backup=no - name: Add HyperDB DB file to wp-content become: yes become_user: root copy: src: files/wordpress/db.php dest: /mnt/Web/Websites/Wordpress/{{ domain }}/public_html/wp-content/db.php remote_src: no - name: Add HyperDB config to public directory become: yes become_user: root template: src=templates/db-config.php dest=/mnt/Web/Websites/Wordpress/{{ domain }}/public_html/db-config.php backup=no - name: Create robots.txt file become: yes become_user: root template: src=templates/robots.txt dest=/mnt/Web/Websites/Wordpress/{{ domain }}/public_html/robots.txt backup=no This section will use all of the information that was added to the extra host. The playbook downloads the latest version of Wordpress and places it in the websites web root using the domain variable.\nA site specific WP-Config file is generated and placed in the correct location. Wordpress sites need site specific specific Auth Keys and Salts for security. The template generates those as the file is created.\nThe wordpress sites use Hyper-DB to fully use the highly available database set. The playbook places a db.php file , which is Hyper DB. Then a db-config.php file is placed, containing connection info for the second database. Username, Password, and Name information is the same as the master db host, so we reference that in this file.\nNext a Wordpress specific robots.txt file is generated and placed at the web root.\nCleanup 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 # Cleanup - name: Set permissions on web directory become: yes become_user: root ansible.builtin.file: path: /mnt/Web/Websites/Wordpress/{{ domain }} state: directory owner: www-data group: www-data recurse: yes #Have to generate a random number to be used for cron to prevent them all happening at once - name: Genrate Random Cron Time 1 set_fact: num1: \u0026#34;{{30 | random(start=1) }}\u0026#34; - name: Genrate Random Cron Time 1 set_fact: num2: \u0026#34;{{59 | random(start=31) }}\u0026#34; - name: Add cron entry for new Website become: true ansible.builtin.lineinfile: path=/mnt/Web/Ansible/wpcron state=present insertafter=\u0026#34;\\# * \\#\u0026#34; line=\u0026#34;{{num1}},{{num2}} * * * * www-data wget https://{{ domain }}/wp-cron.php?doing_cron \u0026amp;\u0026gt; /dev/null\u0026#34; Now that all the files are in place, the playbook sets permissions on all of them to ensure they are correct. Or you could have issues.\nNext a wordpress cron entry is created. Triggering it manually is much faster than having Wordpress check on every page load. To do that a random number is generated, this will be the minute the cron runs every hour.\nSpreading the entries out prevents them all happening at once on the WP-Admin server. An entry is created in a master cron file on the shared storage. This file is used by the Wordpress Admin server to keep its cron list up to date.\nFinishing up the Web Servers 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 - hosts: web become: true tasks: - name: Create cache directory for new site become: yes become_user: root ansible.builtin.file: path: /opt/Cache/{{ hostvars[\u0026#39;WEBINFOHOLDER\u0026#39;][\u0026#39;domain\u0026#39;] }} state: directory - name: Set permissions on cache directory become: yes become_user: root ansible.builtin.file: path: /opt/Cache/{{ hostvars[\u0026#39;WEBINFOHOLDER\u0026#39;][\u0026#39;domain\u0026#39;] }} state: directory owner: www-data group: www-data recurse: yes - name: Reload Nginx to pick up the new website ansible.builtin.systemd: name: nginx state: reloaded Every Wordpress site on the cluster uses a FastCGI based cache to speed up page loads considerably. A directory is needed for this cache. Putting it on the local NVME storage of the web nodes maximizes its speed. This also reduces strain on the shared storage, keeping it fast. The playbook creates that needed directory and sets correct permissions.\nNginx does not actively watch config directories for files. It checks when it is Started, Restarted, or Reloaded. The playbook created all of the needed files but the web servers do not see them yet, and they are not being used. The playbook reloads Nginx so it picks up the new website without dropping existing traffic.\nFinishing up the Wordpress Admin Servers 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 - hosts: wpadmin[0] become: true tasks: - name: Update cron file for new website become: yes become_user: root copy: src: /mnt/Web/Ansible/wpcron dest: /etc/cron.d/wpcron mode: \u0026#39;0644\u0026#39; backup: no - name: Reload Nginx to pick up the new website ansible.builtin.systemd: name: nginx state: reloaded Caching is disabled for any page the Wordpress Admin servers would serve, so creating a cache directory is not needed. The cron file the playbook added to is pushed into the Wordpress Admin server\u0026rsquo;s cron list. Like the Web servers, Nginx has to be reloaded to see the new website.\nNext Steps Once the playbook finishes, open the primary domain in your browser of choice. The domain was already pointed at the cluster\u0026rsquo;s floating IP, so the Wordpress install page loads. Follow the prompts and log into /wp-admin for your new site.\nFinal Notes When I just used a single Web node and single Database node, creating a new Wordpress site took 30 minutes to 1 hour. Remembering comments, switching back and forth, copy/pasting, it ate up my time.\nOn average this playbook takes 3 minutes to run and does a better job than I did manually, on a much more complex cluster. This single playbook alone has saved me over 80 hours, in 3 years.\nComputers start counting at 0\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nMore information here.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-10-25T21:01:30-05:00","image":"https://slamanna.com/p/web-cluster-2/cover_hu_2d9fa145c7aae332.webp","permalink":"https://slamanna.com/p/web-cluster-2/","title":"Ansible Powered Web Cluster Part 2: Creating Websites"},{"content":"Introduction I have created a highly-available web hosting cluster, run completely by Ansible. Servers are created and deleted as needed, scalability provided by running this on Digital Ocean\u0026rsquo;s cloud. Common problems get noticed, and fixed, all without user intervention. This infrastructure is highly specialized and complex, and this post will help explain it. It will be required to understand future posts on this system.\nThe Complete Picture This looks like a lot, but we will break it down below. Some things to note about the system as a whole:\nAll virtual servers are running Ubuntu Server 24.02 The only servers with public internet access are the load balancers and the command \u0026amp; control server. Everything else is done inside of a private LAN between the servers. The servers are divided into groups based on their function. This allows computing to be used efficiently as computing resources are scaled independently for each role. The following groups can scale horizontally by adding more servers: Web Servers, Wordpress Admin servers, and Database servers. All of the servers can scale vertically via Digital Ocean\u0026rsquo;s control panel or API. Almost all of the websites we are hosting are mostly static websites for businesses that do not need live updates. Network Layout As mentioned above, only the Load balancers and Command \u0026amp; Control server can be accessed over the internet. Digital Ocean lets you \u0026ldquo;tag\u0026rdquo; servers with info about them. Each server in this cluster is tagged with its role,backend or frontend, and a web_cluster tag. These tags do 3 big things:\nThey assign firewalls to the droplets based on the role tags the droplet has. This is done at the provider level so the server is protected from the moment it is created, before it even boots. backend tag means the server should not be accessible from the internet, and frontend is. web_cluster is used to create the private lan between all of the droplets in the cluster. This keeps other resources in the same Digital Ocean account from being able to access the cluster. Command and Control In the top left of the above diagram you\u0026rsquo;ll see a single server labeled Command and Control. This is the server that I access to actually run the ansible commands when needed. I can SSH into the server but Ansible Semaphore gives me a nice Web UI and a scheduler (More on this in a future post). It can access all of the servers in the cluster using the private LAN.\nAnsible Inventory An inventory is generated at run time of each playbook by using a Dynamic Inventory. Making the inventory dynamic lets me destroy and create servers at will, Ansible will always know how many servers are in the cluster.\nMonitoring In addition to running all of the Ansible Playbooks, this server also runs Zabbix. Zabbix lets me monitor all of the servers in the cluster and alerts from this system are one of the ways the cluster can grow, contract or heal. When new servers are created, they check in with Zabbix and based on server name, get assigned to monitoring groups in Zabbix.\nLoad Balancer Web traffic comes in from the internet to a Digital Ocean floating IP. It is an IPv4 address that I can point to whatever server I want to. If I want to switch from Load Balancer 1 to the hot spare, I just need to move the floating IP via the control panel or API.\nOnce it reaches the load balancer, the traffic is routed to 2 different backends by HAProxy. If the request is for a WordPress admin page, it is sent to the WP Admin servers, everything else gets sent to the regular web servers. More info on this splitting of traffic here.\nThanks to Cloudflare origin server SSL certificates, all SSL is terminated here. This was done to free as many resources as possible for the web servers, more CPU time for actually serving web pages.\nWeb Servers The web servers all run Nginx and PHP-FPM for serving web pages. The config files and actual website files for all of the websites hosted are stored on the File Server. Putting all of the website configs in a shared location speeds up adding a new web server, as configs do not need to be copied before nginx starts.\nCaching All WordPress sites on the cluster use a Fast-CGI proxy to speed up page loads. All of the PHP code for a page is run, and the results are saved as flat HTML files and served from cache for 1 hour before a new copy is generated. Doing this has many benefits:\nThe static pages are saved to each web server\u0026rsquo;s local NVME drive and served from there, making page loads very fast. File Server load is much lower as it is accessed considerably less often. Google Search rankings for every site went up as google ranked them higher due to much faster page loads If the cluster is under heavy load and additional web nodes are added, the new nodes get total access to the file server as existing web servers are already serving from their local cache. Clearing Web Server Cache Clearing a website\u0026rsquo;s FastCGI cache is a simple playbook:\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 --- - hosts: web become: true vars_prompt: - name: domain prompt: Please provide domain name of website cache to clear private: no tasks: - name: Deleting Cache Directory become: yes become_user: root ansible.builtin.file: path: \u0026#34;/opt/Cache/{{ domain }}/\u0026#34; state: absent - name: Recreating Cache Directory become: yes become_user: root ansible.builtin.file: path: \u0026#34;/opt/Cache/{{ domain }}/\u0026#34; state: directory - name: Set permissions on cache directory become: yes become_user: root ansible.builtin.file: path: \u0026#34;/opt/Cache/{{ domain }}/\u0026#34; state: directory owner: www-data group: www-data recurse: yes Web Server Performance With all of the optimizations , each web server can handle about 700 requests per second maximum. 500 per second is used as a maximum for decisions on adding more web servers.\nWP Admin Servers Why split WordPress admin tasks to its own server? A couple reasons. By default WordPress websites check if they need to do background tasks on every page load. This will slow down the site and is not optimal. You can disable this feature and handle the scheduled tasks manually. The first WP Admin server is always in charge of that. A list of WordPress websites is kept on the file server and the server will use that to trigger the scheduled tasks for all websites.\nWordpress Site Updates Another great reason is update management. Since all wp-admin URLs come to this server, all updates will happen on this server. This frees up the web servers to serve more web pages to guests. With that in mind, we use WP-CLI to automatically update all WordPress websites system files, themes, and plugins, every night. The speed of WP-CLI is also much faster than any other update management system tested.\nFinally, we can horizontally scale this server or servers when we want to do big admin tasks to to reduce time needed to complete them.\nDatabase Servers Both the Web servers and WP-Admin servers connect to the same Database set. 2 servers running MariaDB. It is currently 1 read/write server and 1 read only server. 3 nodes is optimal for high availability, but current load on the cluster is not high enough for that. The 2 database servers are not both read/write to prevent possible split brain issues if the nodes disagree on data.\nNightly backups are made of the main database server for faster recovery from possible disaster.\nSetting up Wordpress for multiple DB Servers Wordpress sites are made aware of the 2 database servers by using the HyperDB database plugin. Ansible also makes it very easy to generate new configuration files when database servers are added or deleted.\nFile Servers Shared file storage is provided by a single NFS server. Website data, Nginx configs, and Nginx snipets are stored here. This is the weakest point in terms of high availability but alternatives had major issues. GlusterFS and Ceph were trialed, but did not do well with the lots of small files data style that WordPress sites use.\nBackups of the shared data are created nightly, and uploaded to storage outside of Digital Ocean for additional disaster recovery.\nFinal Notes This cluster has been running flawlessly for 3 years now and uptime is extremely good. 1 10 minute downtime the entire previous year! I will be sharing more about this cluster soon, with more ansible playbooks.\n","date":"2024-09-10T01:09:50-04:00","image":"https://slamanna.com/p/web-cluster-1/cover_hu_f3fd149349175e09.webp","permalink":"https://slamanna.com/p/web-cluster-1/","title":"Ansible Powered Web Cluster Part 1: Information"},{"content":"Introduction Using various electronic parts, 3D printing, and some amazing software, I have created a DDU for racing video games. A DDU is basically a digital dashboard, replacing a classic gauge cluster. This one is powered by a program called SimHub, and a special display. SimHub comes with plenty of choices for dashboards, with more available online! Lovely Dashboard used in pics.\nDesign My initial screen arrived broken, but this allowed me plenty of time to perfect the design before a replacement screen arrived. This project was designed in Fusion 360, which I am a novice at. There are probably improvements I can make, and will make as more people create this design.\nYour browser doesn't support HTML5 video. Here is a link to the video instead. 3D Print Files 3D print files for this project are currently hosted on Printables, Available Here\nParts List 1x USB C Panel Mount Cable You can use others, but the shell was designed for this specific one 1x 5\u0026quot; Vocore Screen 6x M3x4x5 Threaded Inserts 4x M3x16mm Screws It\u0026rsquo;s hard to buy just a couple screws this small, this kit covers all needed screws 2x M3x10mm Screws 2x M3x8mm Screws DDU Screen Holder 3D Printed DDU Back Shell 3D Printed Wheel Base Mount 3D Printed 1 2 Build Instructions Always melt the inserts only 90% of the way in with the soldering iron and press them the rest of the length into the part with a tool. Hold them in the final position for a few seconds until the plastic has cooled back down and solidified.3\nTake the DDU Screen Holder and insert 4 threaded inserts, one in each corner. Insert the screen into the screen holder. The sides of the screen do not have the same size bezel, make sure you insert the screen the correct way.\nInsert 2 Threaded Inserts into the back of the Back Shell, and 4 on the inside at the corners.\nScrew in the USB C Header and wrap the cable as shown in the picture below. I found that tucking it under itself keeps it more managed. Carefully connect the screen to the usb C header and then screw the screen holder into the back shell with 4x M3x16mm Screws. Mount the DDU to your wheel base or frame. 2x M3x8mm Screws are used to screw the wheel base mount into the shell. If using the Moza R5 mount, use the 2x M3x10mm Screws to screw the mount into the wheel base. Software Setup Download and install SimHub. Getting a license is recommended as it increases the refresh rate and makes things easier. Setup any games you want to use with your DDU, instructions vary wildly game to game. Install the SimHub Vocore Driver, Available Here Plug in your screen Click Devices on the left side of the SimHub window Click Add new device, Scroll down the list on the left till you see Vocore and click it. Select Generic Vocore Screen on the right.\nYou should now see this on the right side of the window\nYou can adjust brightness at the top, if you click screen settings you can rotate the display if required. You can also set Dashboards per game here so they switch automatically. This is one of the features that requires a license\nIf your dashboards have actions (Like Lovely Dashboard), you need to click the Controls tab at the top to bind them. Lovely Dashboard uses at least Action A and Action B. You can also control Brightness with keys, if you change it often.\nRecommended Dashboard I have tried a lot of different dashboards, and even created my own for Forza Horizon 5. Lovely Dashboard is better than all of them in my opinion. It supports all the big games, works great, and looks beautiful. It is free, but there is a premium option available and is what I use. More Info on premium here.\nIf a mount for your wheel base does not exist, it will need to be created. The Printables listing includes a sketch of the dimensions of the holes needed to secure to the DDU shell. If you have trouble or need help, feel free to reach out to me!\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nDepending on your wheel base, you might not need the 8mm or 10mm screws.\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nTaken from here\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-08-15T13:34:02-04:00","image":"https://slamanna.com/p/3dp-simhub-ddu/cover_hu_b06f1cde63d14efc.webp","permalink":"https://slamanna.com/p/3dp-simhub-ddu/","title":"I Designed a 3D Printable Digital Dashboard for Sim Racing"},{"content":"The Problem I got my first 3D printer in December, an Elegoo Neptune 4. The learning curve was bigger than expected but I got it setup and calibrated. I say calibrated but I mean kind of Calibrated. The printer would do some very weird things, without explanation:\nThe Z Offset would change every time I turned the printer off. The number would stay but the printer would print very differently and would need it\u0026rsquo;s Z offset calibrated again. The printer would sometimes ignore its bed mesh, other times it would not. There was no pattern I could even observe for when this would happen, it was always a surprise. In addition to that, there were some other issues with the printer as well:\nThe OS on the embedded Raspberry PI was already End of Life when I received the printer The version of Klipper on the printer was very far out of date and not updatable. You had to wait on updates to flash from Elegoo The Web UI would sometimes just not work and you would have to restart the printer All of these issues are related! Elegoo did not use standard Klipper in the Neptune 4 line of printers, they modified it and changed things. Their changes lead to the issues above. Our fix will remove their modified Klipper and replace it with a more standard version of Klipper.\nThe Fix The fix is OpenNept4une! This is a project created by the Elegoo community, mainly Phillip Thelen, barrenechea, SQUIRRELYMOOSE, DanDonut \u0026amp; Jaerax.1 They have removed Elegoo\u0026rsquo;s customizations and modernized things. The Pi gets a much more recent OS, and a much newer version of Klipper!\nTheir Installation Wiki has all the info you need to install this to your Elegoo printer. You will need a EMMC reader, and I personally recommend doing it on a new bigger EMMC chip. It is not required at all, but it\u0026rsquo;s so cheap, why not?\nThe Results All of the issues I listed earlier were fixed by this project. My prints are now much more consistent and higher quality. I can see more info in Fluidd and everything just works better!\nOpenNept4une Github\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-08-01T01:24:23-04:00","image":"https://slamanna.com/p/opennept4une-saved-my-printer/cover_hu_29b8a8f594c2e937.webp","permalink":"https://slamanna.com/p/opennept4une-saved-my-printer/","title":"OpenNept4une Saved my Elegoo 3D Printer"},{"content":"Introduction I had someone reach out with a request. They needed to move thousands of pictures and movies from a business Dropbox account to a Google Drive account. They thought they would have to do this manually, item by item, and asked if I had any faster solutions. I used Rclone in the past for my Plex server and knew it could easily accomplish this task.\nThe Plan All of the data we are working with is in the cloud, so we will use a cloud server for this. Utilizing its fast internet connection, we can move the data very quickly. I use Digital Ocean for all of my other cloud computing, so they were an easy choice for this. Their servers charge by the hour, so we will plan as much as possible in advance to keep costs low. Digital ocean\u0026rsquo;s \u0026ldquo;Premium CPU\u0026rdquo; droplets have a 10 Gbps connection, while the rest have 2, so we will be using one of them to maximize speed.\nSetting Up Rclone Configuring Rclone ahead of time will save us computing costs. Download Rclone and install it. This guide uses Ubuntu hosts but the same commands should work on WSL or Windows. After its installed run rclone config and connect your clouds. Rclone calls each of these connections a remote. Setup instructions vary wildly depending on cloud, the Rclone website is great for this..\nIn our example our remotes are called drop for Dropbox and drive for Google Drive. A normal command for Rclone is rclone COMMAND remote:path so for example rclone lsd drive:Pics. You will need to access the rclone.conf file located at ~/.config/rclone/rclone.conf, this file will be transferred to our cloud server.\nWhile here, check the size of the data you will be moving. We will be moving the Pics folder from our drop:/ remote, so my command to check size will be rclone size drop:/Pics. We will use this information to make sure we transferred everything.\nNote On Dropbox Work Boxes For Dropbox specifically, just remote: accesses your personal Dropbox. If you have a business one as well, you need to add a / as well. So for us to access the work Dropbox, we type drop:/.\nCreating the VM I used Ubuntu for this. Create your VM, I did Ubuntu Server 24.04 LTS, with 4 Premium AMD cores and 8GB of RAM. Premium AMD for the faster network speeds. Once its live, login and install rclone. wget the 64 bit .deb from the downloads page, and install with dpkg -i rclone_package_name, tab is your friend. Once its installed, copy your rclone.conf file from earlier to ~/.config/rclone/rclone.conf.\nTransferring Data I recommend doing this in a screen session so you don\u0026rsquo;t have to leave the terminal open for the entire transfer. For my specific use, the Rclone command I used was:\nrclone copy drop:/Pics drive:Pics --progress --transfers 10 --checkers 20 --buffer-size 32Mi.\nWe included the / in the Dropbox remote to ensure we are using the Work Box --progress to show us progress during the transfer --transfers 10 increases the number of simultaneous transfers to better utilize the fast hardware we are running on --checkers 20 works with the above flag, does best when it is 2x whatever transfers is --buffer-size 32Mi I am unsure if this did much, but the server had a lot of RAM so I wanted to make sure Rclone used as much as it wanted. With these settings, I got some impressive transfer speeds, 1.4 Gbps upload and download, simultaneously. I did not get a screenshot of it, but the 124GB of data transferred in 1 hour and 13 minutes.\nAfter the transfer completes, check the size in the destination to make sure it matches. It does!\nClosing Notes This worked very well, and was easy to execute. If this becomes a regular thing, I will probably make an Ansible Playbook for it to speed up execution even more.\n","date":"2024-07-10T01:46:29-04:00","image":"https://slamanna.com/p/moving-between-clouds/cover_hu_bf390911541850d0.webp","permalink":"https://slamanna.com/p/moving-between-clouds/","title":"Moving Data Between Clouds"},{"content":"Introduction If you record gameplay clips or stream, you might want to limit what gets broadcast or saved. In a standard setup, all sounds go to one audio device and everything is recorded in one audio track. With some lightweight software, we can split up our audio and gain a lot of control over it. With this setup, we can prevent discord voice calls, or music, from being recorded or streamed. We can also stream music, but to a different audio track so it isn\u0026rsquo;t included in Twitch VODs. Instructions are specific to Windows 10/11 but will work for all current versions of windows.\nSoftware Links The software we need is lightweight and be downloaded here:\nVoicemeeter VB-Cable Voicemeeter-Windows-Volume Optional, more info on this in a later section Default Layout Throughout this guide we will be talking about routing audio. Knowing how a default setup looks will help us understand the changes we make. As stated in the introduction, by default, all audio is sent to one audio track and it\u0026rsquo;s all audio or nothing. Displayed as a flowchart, it looks like this:\nAs stated above, we are stuck with one audio track and everything is recorded everywhere. Not optimal and not flexible.\nVoicemeeter Setup Install Voicemeeter and VB-Cable now. Restart your PC after installing the software for the first time. Now we need to change some settings.\nSetting Default Sound Devices Right Click the Speaker Icon at the bottom right of your screen, and click Sound Settings. Scroll to the bottom of the window that pops up and click More Sound Settings.\nOn the Playback tab, right click on VoiceMeeter Input and click Set Default Device. Right Click on CABLE Input and click Set Default Communication Device. It should look like this when you are done.\nConfiguring Voicemeeter Open Voicemeeter. On the left where it says 1 Hardware Input, click the 1 and select WDM: CABLE Output (VB-Audio Virtual Cable). Further down this section you will see Highlighted A \u0026amp; B Buttons. Click on B so it is no longer highlighted. On the right most section, where it says A1 A2 HARDWARE OUT, click on A1 and select the WDM entry for your speakers or headset, for me it was WDM - Speakers (Logitech PRO X Gaming Headset).\nNote about Volume With this setup, changing the volume with Windows no longer does anything. You have to use the Bar on the right most column, the left of the 2. If you have a hardware volume slider on your headset or speakers, this shouldn\u0026rsquo;t be a problem. If you need Windows to be able to control volume, like if your using earbuds, you can with the third download listed above. Installing that third program and starting it with Windows will link Windows and Voicemeeter volume.\nImproved Layout With the changes we made, our audio flowchart now looks very different. We are going to break it down, level by level.\nAt the top we have our Audio sources, nothing has changed here yet. In the middle our Audio out has been renamed to VAIO and Cable Output. These are also the names of the devices we set as defaults in our Windows sound settings. If you notice, no audio is going to the Cable Output yet, we will fix that below. VAIO is our default sound device and were most of our audio will go. In Voicemeeter it is listed as Virtual Input at the top and it is the section that has the equalizer. Cable Output is where we will send audio we don\u0026rsquo;t want in our gameplay clips or Twitch VODs. It is colored red for clarity. The bottom section has gotten an additional label. In Voicemeeter, on the right side of the window you will see A Main Out and B Virtual Out. Main out is our hardware device like speakers or headset, Virtual out is our recorded clips. If you notice, everything that we send to Cable Output will only be sent to our headset/speakers, not to our recorded clips. Routing Audio Now that we have a second audio device and have it setup, we can set applications to use it.\nDiscord Discord is really easy. In Discord, click the User Settings Gear at the bottom left of the window. Click Voice \u0026amp; Video in the list on the left. Click the Dropdown under Output Device and select Cable Input (VB-Audio Virtual Cable)\nOBS OBS requires some special setup to fully take advantage of what we have done. Open OBS and then click File \u0026gt; Settings at the top of the window. Click Audio on the left. In the section labeled Global Audio Devices set the devices as follows and click OK when done:\nDesktop Audio set to VoiceMeeter Input (VB-Audio VoiceMeeter VAIO) Desktop Audio 2 set to CABLE Input (VB-Audio Virtual Cable) Mic/Auxiliary Audio set to your Microphone Back in the main window of OBS, click the 2 Gears in the Audio Mixer section. On the Desktop Audio 2 row, uncheck Track 2 on the right. This will prevent this channel from being included in Twitch VODs.\nUsing the Audio Mixer section you can now independently adjust the volume of each audio device!\nMost Other Applications For applications that do not let you set audio output devices, we can use the Windows Volume Mixer. Right click your Speaker Icon bottom right of your screen and click Open Volume Mixer. Click on the Application you do not want included in your clips. Set the Output device to Cable Input (VB-Audio Virtual Cable).\nFinal Layout After doing all of the above, our final audio layout looks like this:\nOur Music and Discord audio is all sent to our Cable Output only, so they are not recorded in our clips.\nNotes I have used this setup for a couple of years now. It works very well for me and ensures that I can grab a clip at any time with Nvidia Instant Replay. I know the clip will just have gameplay audio and nothing else! The one issue I have found involves USB soundcards.\nIf your headset or speakers uses a USB soundcard, it can lead to awful, jumbled sound in some cases. For me this is mostly when my computer wakes back up from sleep. To fix it, right click the Voicemeeter icon in your system tray and click Restart Audio Engine.\nIt can be prevented by giving the process audiodg.exe High Priority and setting Affinity to one core. The Voicemeeter-Windows-Volume app linked above includes this fix as an option.\n","date":"2024-06-11T01:48:18-04:00","image":"https://slamanna.com/p/splitting-audio-voicemeeter/cover_hu_2becfaf4203e1895.webp","permalink":"https://slamanna.com/p/splitting-audio-voicemeeter/","title":"Splitting Video Game and Discord Audio with Voicemeeter"},{"content":"Introduction The theme-color meta tag. Full info on it can be found here. TLDR: It colors elements of your web browser like the address bar and or status bar.\nAdding it to all pages and post Adding a theme-color to all posts is easy for most hugo sites. For the Stack theme I\u0026rsquo;m using its extremely easy. You just create a custom.html file in the correct location and add your code. It them gets added to the \u0026lt;head\u0026gt; tags of all pages\nCustomizing it for Pages and Posts differently. Using if statements we can set different colors for posts and pages. We can use the resource color method in Hugo to easily get the most dominate color in an image. Put both of those together and we get this code to add to our custom.html file.\n1 2 3 4 5 6 7 8 9 10 11 \u0026lt;!-- Meta theme color for pages --\u0026gt; {{ if eq .Type \u0026#34;page\u0026#34; }} \u0026lt;meta name=\u0026#34;theme-color\u0026#34; content=\u0026#34;#7825a3\u0026#34; /\u0026gt; {{ end }} \u0026lt;!-- Meta theme color for posts, pulls most dominate color from cover image --\u0026gt; {{ if eq .Type \u0026#34;post\u0026#34; }} {{ with .Resources.GetMatch \u0026#34;cover.*\u0026#34; }} {{ $domcolor := index .Colors 0 }} \u0026lt;meta name=\u0026#34;theme-color\u0026#34; content=\u0026#34;{{ $domcolor }}\u0026#34; /\u0026gt; {{ end }} {{ end }} Conclusion I use this feature on this site and while its very cool, I doubt many will notice it.\n","date":"2024-06-02T04:00:19-04:00","image":"https://slamanna.com/p/hugo-post-theme-color/cover_hu_39ee04ddefa17f4.webp","permalink":"https://slamanna.com/p/hugo-post-theme-color/","title":"Unique Meta theme-color Tags For Every Post"},{"content":"I use ansible EXTENSIVELY in my company. It is an open source IT automation engine that automates provisioning, configuration management, application deployment, orchestration, and many other things. You create playbooks detailing how you want a computer to be setup, and Ansible makes it so. Playbooks are kind of like recipes, used by ansible to \u0026ldquo;bake\u0026rdquo; a computer how you want it. Install X package, set this setting, place this file. It can do this for a lot of computers and handle how they all interact. It completely controls my company\u0026rsquo;s web hosting cluster. I want to share more about it in the future, it is extremely cool.\nOne of the many things it does is generate a robots.txt file for all Wordpress sites I host. Generate the file, place it in the directory, super simple. While setting up a robots.txt file for this website, I looked at one of my Wordpress sites as a starting point. When I opened the file I noticed that the sitemap URL was a HTTP address and not HTTPS. The load balancer does redirect all HTTP requests to HTTPS, but this was still not optimal and just not correct. It was an extremely easy fix, but a cautionary tail to double check your work and do it again with fresh eyes the next day.\n","date":"2024-05-31T02:40:31-04:00","image":"https://slamanna.com/p/automated-failure/cover_hu_10bf7d65b2521b08.webp","permalink":"https://slamanna.com/p/automated-failure/","title":"I Automated a Typo Across A Bunch of Websites"},{"content":"Introduction Using Aurora, and also sometimes OpenRGB, we can let games control your computers lighting. The only requirement is that your lights are plugged into your computers motherboard and not an external RGB controller. If you can change your PCs lighting/color with a button on your tower, this guide probably won\u0026rsquo;t work for you.\nAurora Installing Aurora Aurora can be downloaded here, select the latest version, the file that contains Aurora-setup in its name. Run the file that downloads and install should be straight forward. An auto-updater was recently added, so keeping the software up to date is very easy. You will get a popup a login when its time to update, just follow the prompts.\nConfiguring Aurora Once it is installed you will need to make sure all of your RGB devices are detected. Open Aurora from your start menu. On the left side of the window at the very bottom is a gear icon. Click it.\nIn Devices \u0026amp; Wrappers setup your keyboard locale and a layout (if you don\u0026rsquo;t see your keyboard just pick one that looks close).\nIn Device Manager click enable for any company you have RGB devices from. For example if you have a Corsair Keyboard, enable Corsair. If you have a Logitech mouse, enable Logitech, etc. I recommend disabling all of the options you don\u0026rsquo;t use. Note, I use OpenRGB, so the devices enabled in my screenshot will look different than yours.\nIn General Settings make sure Start with Windows is checked and set Delay to 60 seconds.\nRazer Chroma Support Some games like Overwatch 2 use Razer Chroma for their RBG support. We will need to install the Razer Chroma agent to be able to capture that lighting data. In Aurora\u0026rsquo;s settings, on the Devices \u0026amp; Wrappers tab there will be a section on the right called Chroma. If Installed Version is blank or red, Click Install to install a compatible version. When done, it should look like this\nSetup Desktop Profile Aurora needs to be running any time you are playing an RGB compatible game so its best to just leave it on all the time. If you do, you can change how your lighting looks when your not in game as well.\nIn Aurora, on the left side the very top icon should be a computer screen, that is the desktop profile. I use a Radial layer type, this gives me a slow color changing effect that isn\u0026rsquo;t too distracting.\nIssues/Weirdness If Aurora does not detect everything in your PC you can try the OpenRGB section below. It is not guaranteed to work and it is more advanced than just Aurora itself. If I sent you this post, check in with me before you go further.\nOpen RGB If Aurora can not detect or control all of your PC\u0026rsquo;s lights, you can try OpenRGB. This program replaces programs such as Corsair iCue, Asus Aurora, and other manufacturers RGB control applications. If you install OpenRGB you will need to remove them. To check if your parts work with OpenRGB, check the Supported Devices list.\nUninstall Lighting Control Apps Any existing apps you have that control RGB need to go, Corsair iCue, Asus Aurora, etc. I did leave Logitech G Hub installed as I need that for my racing wheel and it has not caused any issues.\nInstall OpenRGB You can download OpenRGB here.If you are unsure on which version you need, select Windows (64-Bit). Unzip the download and move it to your Documents folder. Double click OpenRGB.exe to launch the application.\nCommonly Missed On first launch and any time you manually start OpenRGB you will need to go to the SDK Server tab and click Start Server or it will not communicate with Aurora.\nConfiguring OpenRGB Once OpenRGB opens, click the Settings tab at the top. In General Settings make sure the following items are checked:\nAMD SMBus: Reduce CPU Usage (ONLY IF YOU HAVE AN AMD CPU) Start at Login Start Minimized Start Server Set Server Host (Put 127.0.0.1 in the text box) If any of your devices are acting weird, you can disable them by going to the Supported Devices tab and disabling them there.\nGeneral Usage OpenRGB will talk to all of your RGB devices. You enable the SDK server and then Aurora will talk to OpenRGB. Once you enable the OpenRGB plugin in Aurora\u0026rsquo;s Settings, Aurora will be able to control everything OpenRGB can.\nFinal Notes RGB software can be very finicky. OpenRGB is trying to fix that but it is a slow and long process. The chances of running into issues are very high. Feel free to reach out to me if you get stuck, need help, or something isn\u0026rsquo;t working.\nCPU usage is commonly stated as a reason you shouldn\u0026rsquo;t bother with RGB control software. In my experience there is almost no cpu load from it. With both Aurora and OpenRGB running they account for less than 2% CPU usage on my Ryzen 3600. On top of this, most modern games are bottlenecked by the GPU anyway.\n","date":"2024-05-21T23:13:41Z","image":"https://slamanna.com/p/game-control-rgb/cover_hu_44969e519725c77f.webp","permalink":"https://slamanna.com/p/game-control-rgb/","title":"Letting Games Control Your PCs Lighting"},{"content":"Ubiquiti released a 2.5 Gbps Gateway recently and I got one to upgrade aging Cloud Security Gateway. With it, I can finally use the full speeds of my Xfinity internet package. It claims a speed of 1200 Mbps down but with over provisioning , I am seeing 1380 Mbps down and 200 Mbps up. I wanted to download from Usenet at these speeds, but as this post shares, that took some work.\nUnraid Filesystem One of Unraid\u0026rsquo;s greatest strengths is its ability to pool multiple different sized hard drives together. Multiple mechanical hard drives and a single super-fast NVME SSD all magically combined into one to get the benefits of all. Files are first sent to the fast NVME drive and then moved to the slower but bigger mechanical storage. A system service called the Mover handles this movement.\nAnother piece of the puzzle is the FUSE filesystem. This uses software to make all of the various hard drives appear as one. This works fine most of the time under normal circumstances. It can become a bottleneck though as the server needs to do extra processing every time it stores or accesses a file. In Unraid you can bypass or use the FUSE Filesystem depending on which directory you access.\n/mnt/user/ - Uses FUSE, contains the contents of all of the data disks and cache disk\n/mnt/disk*/ - Does not use FUSE, is the contents of each individual disk\n/mnt/cache/ - Does not use FUSE, directly accesses the Cache Drive.\nDirectories Referenced in the Rest of this Post /media/ - My Media Share, holds all of my TV shows, Movies, etc. This is also where Sabnzbd downloads to. By having Sab download to the same share the files will stay in, moves are instant.\n/media/0Downloads/ - This is where Sab downloads to, completed downloads are then moved to /media/Movies or /media/TV Shows\n/appdata/ - The default Unraid Appdata share, only exists on the cache drive to maximize speed. (Is backed up)\nExclusive Access in Unraid In Unraid 6.12, a new feature was introduced: Exclusive Access. Basically, if an Unraid share exists exclusively on one disk, the FUSE filesystem can be bypassed for the entire share. This is perfect for the Appdata share that lives exclusively on the super-fast NVME drive. If you use apps like Sonarr, Radarr, etc, they benefit heavily from this change. To enable it, ensure a share only has data on the cache drive, Secondary Storage is set to None, and Permit Exclusive Shares is Yes in the Global Share Settings. I also enabled this for my domains and system shares to speed up my Home Assistant VM and my Docker Containers.\nMake Sabnzbd Bypass the FUSE Filesystem The exclusive access changes did speed up a lot of various things but not my Sab downloads. Sab downloads to my Media share to take advantage of instant moves. If I downloaded to an exclusive share, the download would then need to be moved into my media share anyway, taking more time.\nSince Sab only needs to access the Media share while its downloading, it is possible to have it bypass the FUSE Filesystem. On the settings page for your Sabnzbd Container, replace /mnt/user/ with /mnt/cache for your download mounts. Do not do this for your config mount, that should be on your Appdata share and already benefiting from Exclusive Access.\nThis works great but once your mover runs, it will remove the files from the cache drive and your Sab container will no longer be able to write to the download directory. We can fix this with a custom mover script.\nCustom Mover Script We are going to use our own Mover script to pause Sabnzbd, run the mover, recreate our cache directories, and then restart Sab to make it aware of the directories. Pausing Sab lets us continue to add new jobs to Sab that will then get downloaded when the mover is finished. If an *arr app tries to add something during the brief time Sab is restarting, it will just attempt again after the restart.\nWe will need 2 Unraid plugins. Mover Tuning and User Scripts can both be found by searching on the Apps tab of the Unraid Web UI. Install both of them.\nGo to Settings \u0026gt; Scheduler and scroll down to Mover Tuning. Change Disable Mover running on a schedule to Yes.\nNext go to Settings \u0026gt; User Scripts. Click Add New Script and give it a name, I used Custom Mover. Press the Terminal button top right in the Unraid Web UI and navigate to the path it shows on the User Scripts page.\nOnce you are in the script directory type nano script. Paste in the following script by right clicking.\nOn lines 3 and 22, you will need to replace REPLACE-ME with your Sabnzbd API key and set your network address. You will also need to set your download directories below line 8. Mine are left in as an example. Change the name of the Sabnzbd docker container on line 16 if yours differs.\nIf you are on unRaid 7.0+ , line 6 needs to be: /usr/local/sbin/mover start\n1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #!/bin/bash #echo \u0026#34;Stopping NZB Downloads\u0026#34; curl -s \u0026#34;http://10.1.10.22:8080/sabnzbd/api?apikey=REPLACE-ME\u0026amp;mode=pause\u0026#34; #echo \u0026#34;Running Mover\u0026#34; /usr/local/sbin/mover #echo \u0026#34;Creating Download Directories\u0026#34; mkdir -p /mnt/cache/Media/0Downloads/NZB/inter mkdir -p /mnt/cache/Media/0Downloads/NZB/complete #echo \u0026#34;Setting Permissions\u0026#34; chown -R nobody:users /mnt/cache/Media/0Downloads/ #echo \u0026#34;Restarting Sabnzbd Docker Container\u0026#34; docker restart Sabnzbd #echo \u0026#34;Waiting for Sabnzbd to restart\u0026#34; sleep 10 #echo \u0026#34;Starting NZB Downloads\u0026#34; curl -s \u0026#34;http://10.1.10.22:8080/sabnzbd/api?apikey=REPLACE-ME\u0026amp;mode=resume\u0026#34; Press Control + C to exit Nano, when it asks you if you want to save , press Y then enter. Back in the User Scripts Web UI page, click the dropdown that says schedule disabled and set a schedule. Mine runs daily at 6AM using the custom option and a crontab entry of 0 6 * * *\nSabnzbd Tweaks There isn\u0026rsquo;t too much to set in Sabnzbd, the defaults are great. Make sure you set your line speed in general settings, and I set Article Cache Limit to -1. I have plenty of RAM and Sab never uses more than 1GB usually anyway. Direct Unpack should be turned on, same for Pause Downloading During Post-Processing.\nUsenet Provider Config Even with all of the above changes, I was not reliably maxing out my download speed. I use Frugal Usenet as my main usenet provider. They are amazing and they also give you 1.5TB a month access to Usenet.Farm as a backup. While looking through their FAQ I noticed mention of using up to 100 connections. If you have an account with them, there is a different setup guide located in their billing portal, it contains this paragraph:\nYou May Use Up To 100 Total Connections To Access These Servers - Average Users Should Use Between 40-50 Connections For Optimal Speeds. Increase or decrease this amount for faster or slower line speeds from your ISP.\n— https://billing.frugalusenet.com/page/newsreader\nWith this in mind, I setup both the EU and USA servers in Sabnzbd and set both to priority 0 to use both at once. I set both of them to use 49 connections. I have found that fully maxing out connections can cause errors sometimes if Sab opens and closes connections too fast.\nResults Update 7/27/2024 It appears Comcast has increased my internet speeds again, and the work done here is now working just as well at up to 2 Gbps.\n","date":"2024-05-18T00:15:49-04:00","image":"https://slamanna.com/p/unraid-sabnzbd-past1gb/cover_hu_aab26f980a452a31.webp","permalink":"https://slamanna.com/p/unraid-sabnzbd-past1gb/","title":"Optimizing Unraid and Sabnzbd For Speeds Past 1 Gbps"},{"content":"Old Wisdom I have read and been told in the past that you should never let hard drives spin down. They always claim that if you let them spin down, they will fail faster. As I gained experience in IT I noticed that to not be the case. Mechanical hard drives spinning down or not had no affect on lifespan. Some systems used it, some didn\u0026rsquo;t, both had drives fail at about the same rate.\nWhen I set out to write this article, I expected to find a lot of sources one way or the other. I expected everyone to have come to a consensus on this. All I could find was opinions. It seems that no one has ever truly looked into this. Companies like Backblaze release quarterly reports on their fleet of hard drives 1, but they don\u0026rsquo;t track or look into spin down counts. 2\nInternet Opinions On sites like Reddit, plenty share their thoughts but still no actual facts or data.\nI have 2 arrays. One is accessed all the time. The other one is accessed maybe once a week. The first one never spins down. The 2nd one spins down between usage.\nThat being said, I would be more concerned with total power draw and noise levels, opposed to drive health. Even consumer drives are rated for years of use in various work settings. Just have a back-up in case of a sudden failure. Most drives will give you 5-7 years of use either way.\n— H_Q_3\nThere\u0026rsquo;s no conclusive evidence one way or the other whether a spinning disk 24/7 or one turned on and off regularly is better or worse for it. Maybe switching on and off dozens of times a day, just by nature of mechanical devices, isn\u0026rsquo;t the best thing for it. But if that alone will decrease its usable lifespan before it becomes irrelevant or fails for other reasons, there\u0026rsquo;s no way to say one way or the other.\nAll we do know is spinning 24/7 uses electricity that wouldn\u0026rsquo;t otherwise be used if not. Otherwise flip a coin, use your best judgement, and don\u0026rsquo;t worry about it. — HTWingNut4\nIf you do a full power on and off hundreds of times a day for years because of a bad configuration? Yeah, that\u0026rsquo;s probably a pathology. A long while ago when I looked into it, the ratings for the numbers of complete spinups from stopped is a lot less than the rating for the number of times the drive can \u0026ldquo;sleep\u0026rdquo;, parking heads and (possibly) reducing RPM.\nHowever, hard drives are still perfectly fine being turned on and off multiple times (double digits) every day for years. This is what has been expected from them for decades\u0026hellip; — [deleted]5\nPower Savings While people will argue about drive health impacts forever, the power savings of spinning down hard drives can not be disputed. My home Unraid server is a Dell PowerEdge T320 with 8 Mechanical hard drives and 1 NVME SSD. With the drives all spun up and idle, the server uses 126 Watts of power. With the drives spun down it only uses 70 Watts.\nWith Unraid I can put all of my frequently accessed stuff and Appdata on the always on NVME and let the mechanical drives power down.\nMy Opinion It depends on the workload but, for less frequently accessed business items like backup storage, and almost all home servers, spinning down hard drives is worth it. There is no proven link between spinning down hard drives and failures. It\u0026rsquo;s also cheaper, which is never a bad thing.\nBackblaze Hard Drive Test Data: https://www.backblaze.com/cloud-storage/resources/hard-drive-test-data\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nBackblaze Drive Stats for Q1 2024: https://www.backblaze.com/blog/backblaze-drive-stats-for-Q1-2024/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://www.reddit.com/r/selfhosted/comments/ybd09y/comment/itg79q8/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://www.reddit.com/r/DataHoarder/comments/tj4vm1/comment/i1iuan5/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\nhttps://www.reddit.com/r/DataHoarder/comments/tj4vm1/comment/i1iuan5/\u0026#160;\u0026#x21a9;\u0026#xfe0e;\n","date":"2024-04-09T01:39:38-04:00","image":"https://slamanna.com/p/safe-to-spindown/cover_hu_7ab4900e029d6eb5.webp","permalink":"https://slamanna.com/p/safe-to-spindown/","title":"Its Safe to Spin Down Your Mechanical Hard Drives"},{"content":"My Old Setup I have used a DNS based ad blocker for years. I discovered the Pi-Hole project in early 2016 and used it until this year. I even contributed a little to both the main repository and its web interface. Being able to block Ads, Malware and other nasty stuff across my entire network is so handy. Having its own cache means that common queries are super quick and made things feel just a touch faster. I ran Pi-Hole in a Docker container on my Unraid server and it worked flawlessly.\nWhy I Wanted to Upgrade While Pi-Hole worked great and I loved it, it still left me wanting more. I wanted DNS over HTTPS (DoH) support and an easy way to sync multiple servers. With standard DNS, your ISP, hackers or others could spy on you through your DNS requests. By doing them over HTTPS, you can remove this risk. I wanted multiple servers because every time I take my Unraid server down for maintenance, I lose DNS completely.\nInstalling Adguard-Home Installing AdGuard-Home is super easy. There are setup instructions on their github repo for different operating systems. Link. I setup my primary instance on my Unraid server , and a secondary instance on a Nano Pi 2 I had lying around from an older project. I configured DNS over HTTPS using Cloudflare and Quad9s. I didn\u0026rsquo;t configure the second server at all, the sync will handle that for me.\nSyncing Multiple AdGuard-Home Instances AdGuardhome-Sync makes synchronizing multiple servers effortless. I setup the docker container on my Unraid server, modified the config with my instance info and ran it. It automatically synced literally every setting from my primary server to the secondary one. I told my router to use those servers for DNS in my DHCP settings and that was it! Added it to my personal dashboard and Home Assistant to monitor them.\nScreenshots ","date":"2024-03-08T02:31:24-05:00","image":"https://slamanna.com/p/2024-dns-upgrades/cover_hu_66b0f6e01498f1b7.webp","permalink":"https://slamanna.com/p/2024-dns-upgrades/","title":"Upgrading my Home DNS Setup"},{"content":"I created but never used a blog years ago. I am hoping to change that with this project. Keeping things simple and quick should help me post more frequently.\nAbout This Site It\u0026rsquo;s built using Hugo static site generator to power this website. A more complete writeup will be coming later but it turns basic markdown text files into a website. Deployed to Cloudflare pages for ease of use and speed. It also doesn\u0026rsquo;t cost anything!\nWhy Create It I wanted a space to share everything I\u0026rsquo;m working on and doing without worry. Some topics including cannabis or computer exploits can make some communities or hosting providers uneasy. On top of that, a lot of internet communities have unclear and ever changing rules. Hosting it myself makes things easier. I don\u0026rsquo;t need to worry about what I post and can share more freely.\nWhat\u0026rsquo;s Next I am working on lots of things right now, a 3D printed ESPhome project, Home automation stuff, countless computer projects, my company\u0026rsquo;s ansible powered web hosting cluster, and so much more. I am very excited to document and share it here. Thank You.\n","date":"2024-02-09T01:00:00Z","image":"https://slamanna.com/p/first-post/cover_hu_9e6bcf9cfe9a9448.jpg","permalink":"https://slamanna.com/p/first-post/","title":"First Post"}]