Subsections of

Subsections of Linux

My RHCSA 9 Notes

Here are my notes from Asghar Gori’s RHCSA book. Buy the book or read the reviews here.

Track my RHCSA progress: RHCSA Study Tracker

Extra Resourses

RHCSA Vagrant Lab Setup

RHCSA Vagrant Lab RHCSA Vagrant Lab

We are going to use Vagrant to set up two RHEL 8 servers with some custom configuration options. I will include some helpful Vagrant commands at the end if you get stuck.

In this guide, I will be using Fedora 38 as my main operating system. I use Fedora because it is similar in features to Red Hat Linux Distributions. This will give me even more practice for the RHCSA exam as I use it in day-to-day operations.

Note, if you are using Windows, you will need to install ssh. This can be done by installing Git. Which automatically installs ssh for you.

You will also need to have the latest version of Virtualbox installed.

Here are the steps:

  1. Download and install Vagrant
  2. Make a new directory for your vagrant lab to live in
  3. Add the vagrant box
  4. Install the Vagrant disk size plugin
  5. Initialize the Vagrant box and Edit the Vagrant file
  6. Bring up the Vagrant box

1. Download and install Vagrant.

In Fedora, this is very easy. Run the following command to download and install Vagrant:

sudo dnf install vagrant

2. Make a new directory for your vagrant lab to live in.

Make your vagrant directory and make it your current working directory:

cd Vagrant
  1. Add the Vagrant box. vagrant box add generic/rhel8

  2. Install the Vagrant disk size plugin. The disk size program will help us set up custom storage sizes. Since we will be re-partitioning storage, this is a useful feature.

vagrant plugin install vagrant-disksize

  1. Initialize the Vagrant box and edit the Vagrant file. First, initialize the Vagrant box in the vagrant directory:

vagrant init generic/rhel8

After completion, there will now be a file called “Vagrantfile” in your current directory. Since Vim is on the RHCSA exam, it’s wise to practice with it whenever you can. So let’s open the file in Vim:

vim Vagrantfile

You will see a bunch of lines commented out, and a few lines without comments. Go ahead and comment out everything and paste this at the end of the file:

Vagrant.configure("2") do |config


config.vm.box = "generic/rhel8"


config.vm.define "server1" do |server1|


server1.vm.hostname = "server1.example.com"


server1.vm.network "private_network", ip: "192.168.2.110"


config.disksize.size = '10GB'


end


config.vm.define "server2" do |server2|


server2.vm.hostname = "server2.example.com"


server2.vm.network "private_network", ip: "192.168.2.120"


config.disksize.size = '16GB'


end


config.vm.provider "virtualbox" do |vb|


vb.memory = "2048"


end


end|

The configuration file is fairly self-explanatory. Save Vagrantfile and exit Vim. Then, create /etc/vbox/networks.conf and add the following:

* 10.0.0.0/8 192.168.0.0/1
* 2001::/646

This will allow you to be more flexible with what network addresses can be used in VirtualBox.

Bring up the Vagrant box.

Now, we bring up the Vagrant box. This will open two Virtual machines in Virtualbox named server1 and server2 in headless mode (there is no GUI).

vagrant up

Great! Now we can use Vagrant to ssh into server1:

vagrant ssh server 1

From server1 ssh into server2 using its IP address:

[vagrant@server1 ~]$ ssh 192.168.2.120

Now you are in and ready to stir things up. The last thing you need is some commands to manage your Vagrant machines.

Helpful Vagrant commands.

Shut down Vagrant machines:

vagrant halt Suspend or resume a machine:

vagrant suspend
vagrand resume

Restart a virtual machine:

vagrant reload

Destroy a Vagrant machine:

vagrant destroy [machine-name]

Show running VMs:

vagrant status

List other Vagrant options:

vagrant

If you are going for RHCSA, there is no doubt that you will also use Vagrant sometime in the future. And as you can see, it’s pretty quick and simple to get started.

Feel free to reach out with questions.

Networking

Articles

The formatting and images of all of my networking notes go destroyed when migrating away from OneNote. But they still come in handy all of the time.

See my networking notes:

Cisco

Juniper

Subsections of Networking

How to Study for the CCNA Exam

CCNA Study Calendar CCNA Study Calendar

It took me a whopping 2 years to finish my CCNA! I kept giving up and quitting my studies for months at a time. Why? Because I couldn’t remember the massive amount of content covered in the CCNA. It felt hopeless. I could have done it in 6 month (or faster) if I knew how to study.

I hadn’t taken a test in 10 years before this. So I had completely forgotten how to learn. This post is about the mistakes I made studying for the CCNA and how to avoid them.

You will also learn, as I did, about spaced repetition. I’ve also included a 6 month CCNA spaced repetition calendar.

My Mistakes, So You Don’t Make Them

Mistake #1 Didn’t start flashcards until the final 30 days

I wish I would have started flashcards from day 1. This would have helped a crap ton. Remembering all of the little details is not only useful for taking the test. It embeds the concepts in your brain and keeps you processing how things work .

If there is anything you take from this list. You should definitely be doing some flashcards every day.

Mistake #2 Not enough labs as I went.

While studying the OCG and video courses. I did some labs. But I also skipped a ton of labs because it wasn’t convenient at the time. Then I was forced to lab every single topic in the final 30 days. A lot of cramming was done..

Make sure to do all of the labs as you go. Make up your own labs as well. This is very important to building job worthy skills.

Mistake #3 Didn’t have a plan or stick with it.

When your plan consists of, “just read everything and watch the videos and take the test when you feel ready”, you tend to procrastinate and put things off. Make a study schedule and a solid plan. (See below)

Having a set date for when you will take the test was pretty motivating. I did not find this out until about 30 days until my test.


Spaced Repetition

If you are using Anki flashcards for your studies, you may already be using spaced repetition. Spaced repetition is repeatedly reviewing with the time in between reviews getting longer each time you review it.

Here is an excellent article about our learning curves and why spaced repetition helps us remember things https://fs.blog/spacing-effect/

How to set up a spaced repetition calendar for CCNA.

Step 1. Plan how long your studies will take

Figure out how long you need. It usually takes around 240 hours of studying for CCNA. (Depending on experience). Then figure out how many hours per day that you can spend on studying. This example is based on a 6 month study calendar.

You can use this 6 month excel calendar to plan and track your progress. You. can still use this method If you have already been studying CCNA. Just edit your calendar for how much time you have left.

The calendar is also based on Wendel Odom’s Official Cert Guide. You will also want to mix your other resources into your reviews.

Decide what your review sessions will be

Plan to review each chapter 3-4 times. here is what I did for review sessions to pass the exam.

Review 1 Read and highlight (and flashcards)

  • Read the chapter. Highlight key information that you want to remember.
  • Do a lab for the material you studied (if applicable)
  • Answer DIKTA questions
  • Start Chapter 1 Anki Flascards

Review 2 Copy highlights over to OneNote (keep doing flashcards)

  • Copy your highlights over to OneNote. (using copy and paste if you have the digital book)
  • Read your highlights and make sure you understand everything.
  • lab and continue doing flashcards. (just go through Anki suggested flashcards, not just ones for the specific chapter.)

Review 3 Labs and Highlight your notes (and flashcards)

  • More labs!
  • Go over your notes. Color coding everything. (You can find my jumbled note mess here)
  • Green: Read again
  • Teal: Very important Learn this/ lab it.
  • Red/ purple: make extra flashcards out of this.

Review 4 Practice questions and review

  • Go through and answer the DIKTA questions again. Review any missed answers.
  • Lab anything you aren’t quite sure of.

The final 30 days

I HIGHLY recommend Boson ExSim for your final 30 days of studying. ExSim comes with 3 exams (A,B, and C). Start with exam A in test simulation mode. Leave about a week in between each practice exam so you can go over your answers and Boson’s explanations for each answer.

One week before your test, (after you’ve completed exams A,B, and C). Do a random exam. Make sure you do the timed version that don’t show your score as you go.

You should be scoring above 900 by your 3rd and 4th exam if you have been reviewing Boson’s answer explanations.

Schedule your exam

Pearson view didn’t let me schedule the exam past 30 days out from when I wanted to take it. I’m not sure if this is the case all the time. But by the time you are 30 days out you should have your test scheduled. This will light the fire under you. Great motivation for the home stretch.

If your exam is around June during Cisco Live, Cisco usually offers a 50% discount for an exam voucher. You probably won’t find any other discounts unless you pay for Cisco’s specific CCNA training.

Final word on labs

You can technically pass the CCNA without doing many labs. But this will leave you at a HUGE disadvantage in the job market. Labs are crucial for really understanding networking. Knowing your way around the CLI and being able to troubleshoot networking issues will make you stand out from those who crammed for the exam.

If you’ve made it this far I really appreciate you taking the time to read this post. I really hope it helps at least one person.

Resources for Passing CCNA

There are a lot of great CCNA resources out there. This list does not include all of them. Only the ones that I personally used to pass the CCNA 200-301 exam.

Materials for CCNA are generally separated into 5 categories:

  • Books
  • Video courses
  • Labs
  • Practice test
  • Flashcards

Books

Wendell Odom OCG Official cert guide library

To me, this is the king of CCNA study materials. Some people do not like reading but this will give you more depth than any other resource on this list. Link.

Todd Lammle Books

Yes, I read both the OCG and Todd Lammle books cover to cover. No, I do not recommend doing this. Todd has a great way of adding humor into networking. If you need to build up your networking from the ground up. These books are great. Link.

Video Courses

CBT Nuggets

Jeremy Ciara makes learning networking so much fun. This was a great course but is not enough for you to pass the exam on it’s own. Also, a CBT nuggets monthly subscription will set you back $59 per month. Link.

Jeremy’s IT Lab

Jermey’s IT lab course was the most informative for me. Jeremy is really great at explaining the more complex topics. Jeremy’s course also includes Packet Tracer labs and and in depth Anki flashcard deck for free. Link.

Labs

David Bombal’s Packet Tracer Labs

These labs will really make you think. Although they do steer off the exam objectives a bit. Link.

Jeremy’s IT labs

These were my favorite labs by far. Very easy to set up with clear instructions and video explanations. Link.

Practice test

Boson Exsim

I can’t stress this enough. if there is one resource that you invest some money into. it’s the Boson practice exams. This is a test simulator that is very close to what the actual test will be like. Exsim comes with 3 exams.

After taking one of these practice tests you will get a breakdown of your scores per category. You will also get to go through all of your questions and see detailed explantations for why each answer is right or wrong.

These practice exams were crucial for me to understand where my knowledge gaps were. Link.

Subnettingpractice.com

You can learn subnetting pretty good. Then forget some of the steps a month later and have to learn all over again. It was very helpful to go over some of these subnetting questions once in a while. Link.

Flashcards

Anki Deck

These are the only flashcards I used. It is very nice not to have to create your own flashcards. Having the Anki app on your phone is very convenient. You can study whenever you have a few minutes of downtime.

Anki also used spaced-repetition. It will give you harder flashcards more often based on how you rate their difficulty.

This particular deck goes along with the OCG. You can filter by chapter and add more as you get through the book.

I will be using Anki flashcards for every exam in the future. Link.

My Top 3

Be careful not to use too many resources. You may get a bit overwhelmed. Especially if this is your first certification like it was for me. You will be building study habits and learning how to read questions correctly. So focus on quality over quantity.

If I had to study for the CCNA again, I would use these three resources:

  • OCG
  • Boson Exsim
  • Anki Flashcards

If you like these posts, please let me know so i can keep making more like them!

What to Learn After CCNA

What to Learn After CCNA

It’s easy to get overwhelmed with options after completing your CCNA. What do you learn next? If you are trying to get a job as a Network Engineer, you will want to check this out.

I went through dozens of job listings that mentioned CCNA. Then, tallied up the main devices/vendors, certifications, and technologies mentioned. And left out anything that wasn’t mentioned more than twice.

Core CCNA technologies such as LAN, WAN, OSPF, Spanning Tree, VLANs, etc. have been left out. The point here is to target the most sought after technologies and skills by employers. I also left out soft skills and any job that wasn’t a networking specific role.

Devices/ Vendors

Palo Alto is huge! I’m not suprised by this. Depending on the company, a network engineer may be responsible for firewall configuration and troubleshooting. It also looks like Network Engineers with a wide variety of skills are saught after.

Device/Vendor Times Mentioned
Palo Alto 9
Cisco ASA 6
Juniper 6
Office 365 5
Meraki 4
Vmware 4
Linux 4
Ansible 4
AWS 3
Wireshark 3

Technologies

Firewall comes in first again. Followed closely by VPN skills. Every interview I had for a Network Engineer position asked if I knew how to configure and troubleshoot VPNs.

Technology Times Mentioned
Firewall 19
VPN 16
Wireless 12
BGP 12
Security 12
MPLS 10
Load balancers 8
Ipsec 7
ISE 6
DNS 5
SDWAN 5
Cloud 4
TACACS+ 4
ACL 4
SIEM 4
IDS/IPS 4
RADIUS 3
ITIL 3
Ipam 3
VOIP 3
EIGRP 3
Python 3

Certifications

CCNP blew every other cert out of the water. Companies will be very interested if you are working towards this cert. Security + comes highly recommended as well.

Certification Times Mentioned
CCNP 18
Security+ 6
JNCIA 4
JNCIP 4
Network + 4
CCIE 4
PCNSA 3

So what do you do after CCNA?

It depends…

Are you trying to get a new job ASAP? Are there opportunities at your current role that you can use your new skills to leverage? Do you have some study time before you are ready to take the next step?

CCNP Enterprise is a good bet if you really want to stand out in Network Engineering interviews.

Don’t want to be a Network engineer?

Continue to build a good base of IT skills. This will open you up to a larger variety of jobs and open skill paths that you need a good foundation to unlock.

Core skills include:

  • Linux/ Operating systems
  • Networking
  • General Cybersecurity
  • Programming/ Scripting

A good Linux certification like the RHCSA would be great to learn more about Linux, scripting, and operating systems. Security + would be good if you want to get a solid foundation of cyber security. And Python skills will give you a gold star in any IT interview.

Don’t get paralyzed by choices.

Pick something that interests you and go for it. That is the only way to get it right. Doing what you enjoy is better than not doing anything at all because you can’t decide the best path.

Hopefully we can revisit this post after learning Python to get a much bigger sample size.

Tools

Containers

Website

Obsidian

Git

Vim

Misc

Upcoming Projects:

Searx

[[Searx Setup Guide]]

Create my own searx search engine

go to https://searx.space/

RSS

Create and RSS feed of my site and subscribe to other feeds.

Follow these sites:

https://denshi.org/ https://drewdevault.com/ https://opensourcemusings.com/support https://www.mrmoneymustache.com/

DWM Tile Manager

http://thedarnedestthing.com/vim/wiki%20cheatsheet

Browser Sync

https://www.xbrowsersync.org/

Privacy tools

https://www.privacytools.io/

Subsections of Tools

Calibre Web with Docker and NGINX

I couldn’t find a guide on how to set up Calibre web step-by-step as a Docker container. Especially not one that used Nginx as a reverse proxy.

The good news is that it is really fast and simple. You’ll need a few tools to get this done:

  • A server with a public IP address
  • A DNS Provider (I use CloudFlare)
  • Docker
  • Nginx
  • A Calibre Library
  • Certbot
  • Rsync

First, sync your local Calibre library to a folder on your server:

rsync -avuP your-library-dir root@example.org:/opt/calibre/

Install Docker

sudo apt update  
sudo apt install docker.io

Create a Docker network

sudo docker network create calibre_network

Create a Docker volume to store Calibre Web data

sudo docker volume create calibre_data

Pull the Calibre Web Docker image

sudo docker pull linuxserver/calibre-web

Start the Calibre Web Docker container

sudo docker run -d \   
--name=calibre-web \   
--restart=unless-stopped \   
-p 8083:8083 \   
-e PUID=$(id -u) \   
-e PGID=$(id -g) \   
-v calibre_data:/config \   
-v /opt/calibre/Calibre:/books \   
--network calibre_network \   
linuxserver/calibre-web

Configure Nginx to act as a reverse proxy for Calibre Web

Create the site file

sudo vim /etc/nginx/sites-available/calibre-web

Add the following to the file

server { listen 80;   
server_name example.com; # Replace with your domain or server IP location /   
{   
proxy_pass http://localhost:8083;   
proxy_set_header Host $host;   
proxy_set_header X-Real-IP $remote_addr;   
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;   
proxy_set_header X-Forwarded-Proto $scheme;   
} }

Enable the site

sudo ln -s /etc/nginx/sites-available/calibre-web /etc/nginx/sites-enabled/

Restart Nginx

sudo service nginx restart

DNS CNAME Record

Make sure to set up a cname record for your site with your DNS provider such as: calibre.example.com

SSL Certificate

Install ssl cert using certbot

certbot --nginx

Site Setup

Head to the site at https://calibre.example.com and log in with default credentials:

username: admin password: admin123

Select /books as the library directory. Go into admin settings and change your password.

Adding new books

Whenever you add new books to your server via the rsync command from earlier, you will need to restart the Calibre Web Docker container. Then restart Nginx.

sudo docker restart calibre-web  
systemctl restart nginx

That’s all there is to it. Feel free to reach out if you have issues.

How to Build a Website with Hugo

Word Press is great, but it is probably a lot more bloated then you need for a personal website. Enter Hugo, it has less server capacity and storage needs than Word Press. Hugo is a static site generator than takes markdown files and converts them to html.

Hosting your own website is also a lot cheaper than having a provider like Bluehost do it for you. Instead of $15 per month, I am currently paying $10 per year.

This guide will walk through building a website step-by-step.

  1. Setting up a Virtual Private Server (VPS)
  2. Registering a domain name
  3. Pointing the domain to your server
  4. Setting up hugo on your local PC
  5. Syncing your Hugo generate site with your server
  6. Using nginx to serve your site
  7. Enable http over SSL

Setting up a Virtual Private Server (VPS)

I use Vultr as my VPS. When I signed up they had a $250 credit towards a new account. If you select the cheapest server (you shouldn’t need anything else for a basic site) that comes out to about $6 a month. Of course the $250 credit goes towards that which equates to around 41 months free.

Head to vultr.com. Create and account and Select the Cloud Compute option.

Under CPU & Storage Technology, select “Regular Performance”. Then under “Server Location, select the server closest to you. Or closest to where you think your main audience will be.

Under Server image, select the OS you are most comfortable with. This guide uses Debian.

Under Server Size, slect the 10GB SSD. Do not select the “IPv6 ONLY” option. Leave the other options as default and enter your server hostname.

On the products page, click your new server. You can find your server credentials and IPv4 address here. You will need these to log in to your server.

Log into your sever via ssh to test. From a Linux terminal run:

ssh username@serveripaddress

Then, enter your password when prompted.

Registering a Domain Name

I got my domain perfectdarkmode.com from Cloudflare.com for about $10 per year. You can check to see available domains there. You can also check https://www.namecheckr.com/ to see iof that name is available on various social media sites.

In CloudFlare, just click “add a site” and pick a domain that works for you. Next, you will need your server address from earlier.

Under domain Registration, click “Manage Domains”, click “manage” on your domain. One the sidebar to the right, there is a qucik actions menu. Click “update DNS configuration”.

Click “Add record”. Type is an “A” record. Enter the name and the ip address that you used earlier for your server. Uncheck “Proxy Status” and save.

You can check to see if your DNS has updated on various DNS severs at https://dnschecker.org/. Once those are up to date (after a couple minutes) you should be able to ping your new domain.

$ ping perfectdarkmode.com
PING perfectdarkmode.com (104.238.140.131) 56(84) bytes of data.
64 bytes from 104.238.140.131.vultrusercontent.com (104.238.140.131): icmp_seq=1 ttl=53 time=33.2 ms
64 bytes from 104.238.140.131.vultrusercontent.com (104.238.140.131): icmp_seq=2 ttl=53 time=28.2 ms
64 bytes from 104.238.140.131.vultrusercontent.com (104.238.140.131): icmp_seq=3 ttl=53 time=31.0 ms

Now, you can use the same ssh command to ssh into your vultr serverusing your domain name.

ssh username@domain.com

Setting up hugo on your local PC

Hugo is a popular open-source static site generator. It allows you to take markdown files, and builds them into and html website. To start go to https://gohugo.io/installation/ and download Hugo on your local computer. (I will show you how to upload the site to your server later.)

Pick a theme The theme I use is here https://themes.gohugo.io/themes/hugo-theme-hello-friend-ng/

You can browse your own themes as well. Just make sure to follow the installation instructions. Let’s create a new Hugo site. Change into the directory where you want your site to be located in. Mine rests in ~/Documents/.

cd ~/Documents/

Create your new Hugo site.

hugo new site site-name

This will make a new folder with your site name in the ~/Documents directory. This folder will have a few directories and a config file in it.

archetypes  config.toml  content  data  layouts  public  resources  static  themes

For this tutorial, we will be working with the config.toml file and the content, public, static, and themes. Next, load the theme into your site directory. For the Hello Friend NG theme:

git clone https://github.com/rhazdon/hugo-theme-hello-friend-ng.git themes/hello-friend-ng

Now we will load the example site into our working site. Say yes to overwrite.

cp -a themes/hello-friend-ng/exampleSite/* .

The top of your new config.toml site now contains:

baseURL = "https://example.com"
title   = "Hello Friend NG"
languageCode = "en-us"
theme = "hello-friend-ng"

Replace your baseURL with your site name and give your site a title. Set the enableGlobalLanguageMenu option to false if you want to remove the language swithcer option at the top. I also set enableThemeToggle to true so users could set the theme to dark or light.

You can also fill in the links to your social handles. Comment out any lines you don’t want with a “#” like so:

[params.social](params.social)
    name = "twitter"
    url  = "https://twitter.com/"

  [params.social](params.social)
    name = "email"
    url  = "mailto:nobody@example.com"

  [params.social](params.social)
    name = "github"
    url  = "https://github.com/"

  [params.social](params.social)
    name = "linkedin"
    url  = "https://www.linkedin.com/"

 # [params.social](params.social)
   # name = "stackoverflow"
   # url  = "https://www.stackoverflow.com/"

You may also want to edit the footer text to your liking. I commented out the second line that comes with the example site:

[params.footer]
    trademark = true
    rss = true
    copyright = true
    author = true

    topText = []
    bottomText = [
     # "Powered by <a href=\"http://gohugo.io\">Hugo</a>",
     #  "Made with &#10084; by <a href=\"https://github.com/rhazdon\">Djordje Atlialp</a>"
    ]

Now, move the contents of the example contents folder over to your site’s contents folder (giggidy):

cp -r ~/Documents/hugo/themes/hello-friend-ng/exampleSite/content/* ~/Documents/hugo/content/

Let’s clean up a little bit. Cd into ~/Documents/hugo/content/posts. Rename the file to the name of your first post. Also, delete all of the other files here:

cd ~/Documents/hugo/contents/posts
mv goisforlovers.md newpostnamehere.md
find . ! -name 'newpostnamehere.md' -type f -exec rm -f {} +

Open the new post file and delete everything after this:

+++
title = "Building a Minimalist Website with Hugo"
description = ""
type = ["posts","post"]
tags = [
    "hugo",
    "nginx",
    "ssl",
    "http",
    "vultr",
]
date = "2023-03-26"
categories = [
    "tools",
    "linux",
]
series = ["tools"]
[ author ]
  name = "David Thomas"
+++

You will need to fill out this header information for each new post you make. This will allow you to give your site a title, tags, date, categories, etc. This is what is called a TOML header. TOML stands for Tom’s Obvious Minimal Language. Which is a minimal language used for parsing data. Hugo uses TOML to fill out your site.

Save your doc and exit. Next, there should be an about.md page now in your ~/Documents/hugo/Contents folder. Edit this to edit your about page for your site. You can use this Markdown Guide if you need help learning markdown language. https://www.markdownguide.org/

Serve your website locally

Let’s test the website by serving it locally and accessing it at localhost:1313 in your web browser. Enter the command:

hugo serve

Hugo will now be generating your website. You can view it by entering localhost:1313 in your webbrowser.

You can use this to test new changes before uploading them to your server. When you svae a post or page file such as your about page, hugo will automatically update the changes to this local page if the local server is running.

Press “Ctrl + c” to stop this local server. This is only for testing and does not need to be running to make your site work.

Build out your public directory

Okay, your website is working locally, how do we get it to your server to host it online? We are almost there. First, we will use the hugo command to build your website in the public folder. Then, we will make a copy of our public folder on our server using rsync. I will also show you how to create an alias so you do not have to remember the rsync command every time.

From your hugo site folder run:

hugo

Next, we will put your public hugo folder into /var/www/ on your server. Here is how to do that with an alias. Open ~/.bashrc.

vim ~/.bashrc

Add the following line to the end of the file, making sure to replace the username and server name:

# My custom aliases
alias rsyncp='rsync -rtvzP ~/Documents/hugo/public/ username@myserver.com:/var/www/public'

Save and exit the file. Then tell bash to update it’s source config file.

source ~/.bashrc

Now your can run the command by just using the new alias any time. Your will need to do this every time you update your site locally.

rsyncp

Set up nginx on your server

Install nginx

apt update
apt upgrade
apt install nginx

create an nginx config file in /etc/nginx/sites-available/

vim /etc/nginx/sites-available/public

You will need to add the following to the file, update the options, then save and exit:

server {
        listen 80 ;
        listen [::]:80 ;
        server_name example.org ;
        root /var/www/mysite ;
        index index.html index.htm index.nginx-debian.html ;
        location / {
                try_files $uri $uri/ =404 ;
        }
}

Enter your domain in “server_name” line in place of “example.org”. Also, point “root” to your new site file from earlier. (/var/www/public). Then save and exit.

Link this site-available config file to sites-enabled to enable it. Then restart nginx:

ln -s /etc/nginx/sites-available/public /etc/nginx/sites-enabled
systemctl reload nginx

Access Permissions

We will need to make sure nginx has permissions to your site folder so that it can access them to serve your site. Run:

chmod 777 /var/www/public

Firewall Permissions

You will need to make sure your firewall allows port 80 and 443. Vultr installs the ufw program by default. But your can install it if you used a different provider. Beware, enabling a firewalll could block you from accessing your vm, so do your research before tinkering outside of these instructions.

ufw allow 80
ufw allow 443

Nginx Security

We will want to hide your nginx version number on error pages. This will make your site a bit harder for hackers to find exploits. Open your Nginx config file at /etc/nginx/nginx.conf and remove the “#” before “server_tokens off;”

Enter your domain into your browser. Congrats! You now have a running website!

Use Certbot to enable HTTPS

Right now, our site uses the unencrypted http. We want it to use the encrypted version HTTPS (HTTP over SSL). This will increase user privacy, hide usernames and passwords used on your site, and you get the lock symbol by your URL name instead of “!not secure”.

Install Certbot and It’s Nginx Module

apt install python3-certbot-nginx

Run certbot

certbot --nginx

Fill out the information, certbot asks for your emaill so it can send you a reminder when the certs need to be renewed every 3 months. You do not need to consent to giving your email to the EFF. Press 1 to select your domain. And 2 too redirect all connections to HTTPS.

Certbot will build out some information in your site’s config file. Refresh your site. You should see your new fancy lock icon.

Set Up a Cronjob to automatically Renew certbot certs

crontab -e

Select a text editor and add this line to the end of the file. Then save and exit the file:

0 0 1 * * certbot --nginx renew

You now have a running website. Just make new posts locally, the run “hugo” to rebuild the site. And use the rsync alias to update the folder on your server. I will soon be making tutorials on making an email address for your domain, such as david@perfectdarkmode.com on my site. I will also be adding a comments section, RSS feed, email subscription, sidebar, and more.

Feel free to reach out with any questions if you get stuck. This is meant to be an all encompassing guide. So I want it to work.

Extras

Optimizing images

Create assets folder in main directory.

Create images folder in /assets

Access image using hugo pipes

{{ $image := resources.Get "images/test-image.jpg" }}
<img src="{{ ( $image.Resize "500x" ).RelPermalink }}" />

https://gohugo.io/content-management/image-processing/

How to Process Bookfusion Highlights with Vim

Here are my highlights pulled up in Vim:

As you can see, Bookfusion gives you a lot of extra information when you export highlights. First, let’s get rid of the lines that begin with ##

Enter command mode in Vim by pressing esc. Then type :g/^##/d and press enter.

Much better.

Now let’s get rid of the color references:`

:g/^Color/d

To get rid of the timestamps, we must find a different commonality between the lines. In this case, each line ends with “UTC”. Let’s match that:

:g/UTC$/d

Where $ matches the end of the line.

Now, I want to get rid of the > on each line: %s/> //g

Almost there, you’ll notice there are 6 empty lines in between each highlight. Let’s shrink those down into one:

:%s/\(\n\)\{3,}/\r\r/g

The command above matches newline character n 3 or more times and replaces them with two newline characters /r/r.

As we scroll down, I see a few weird artifacts from the book conversion to markdown.

Now, I want to get rid of any carrot brackets in the file. Let’s use the substitute command again here:

%s/<//g

Depending on your book and formatting. You may have some other stuff to edit.

How to Set Up Hugo Relearn Theme

Hugo Setup

Adding a module as a theme

Make sure Go is installed

go version

Create a new site

hugo new site sitename
cd sitename

Initialize your site as a module

hugo mod init sitename

Confirm

cat go.mod

Add the module as a dependency using it’s git link

hugo mod get github.com/McShelby/hugo-theme-relearn

Confirm

cat go.mod

add the theme to config.toml

# add this line to config.toml and save
theme = ["github.com/McShelby/hugo-theme-relearn"]

Confirm by viewing site

hugo serve
# visit browser at http://localhost:1313/ to view site

Adding a new “chapter” page

hugo new --kind chapter Chapter/_index.md

Add a home page

hugo new --kind home _index.md

Add a default page

hugo new <chapter>/<name>/_index.md

or

hugo new <chapter>/<name>.md

You will need to change some options in _index.md

+++
# is this a "chaper"?
chapter=true
archetype = "chapter"
# page title name
title = "Linux"
# The "chapter" number
weight = 1
+++

Adding a “content page” under a category

hugo new basics/first-content.md

Create a sub directory:

hugo new basics/second-content/_index.md
  • change draft = true to draft = false in the content page to make a page render.

Global site parameters

Add these to your config.toml file and edit as you please

[params]
  # This controls whether submenus will be expanded (true), or collapsed (false) in the
  # menu; if no setting is given, the first menu level is set to false, all others to true;
  # this can be overridden in the pages frontmatter
  alwaysopen = true
  # Prefix URL to edit current page. Will display an "Edit" button on top right hand corner of every page.
  # Useful to give opportunity to people to create merge request for your doc.
  # See the config.toml file from this documentation site to have an example.
  editURL = ""
  # Author of the site, will be used in meta information
  author = ""
  # Description of the site, will be used in meta information
  description = ""
  # Shows a checkmark for visited pages on the menu
  showVisitedLinks = false
  # Disable search function. It will hide search bar
  disableSearch = false
  # Disable search in hidden pages, otherwise they will be shown in search box
  disableSearchHiddenPages = false
  # Disables hidden pages from showing up in the sitemap and on Google (et all), otherwise they may be indexed by search engines
  disableSeoHiddenPages = false
  # Disables hidden pages from showing up on the tags page although the tag term will be displayed even if all pages are hidden
  disableTagHiddenPages = false
  # Javascript and CSS cache are automatically busted when new version of site is generated.
  # Set this to true to disable this behavior (some proxies don't handle well this optimization)
  disableAssetsBusting = false
  # Set this to true if you want to disable generation for generator version meta tags of hugo and the theme;
  # don't forget to also set Hugo's disableHugoGeneratorInject=true, otherwise it will generate a meta tag into your home page
  disableGeneratorVersion = false
  # Set this to true to disable copy-to-clipboard button for inline code.
  disableInlineCopyToClipBoard = false
  # A title for shortcuts in menu is set by default. Set this to true to disable it.
  disableShortcutsTitle = false
  # If set to false, a Home button will appear below the search bar on the menu.
  # It is redirecting to the landing page of the current language if specified. (Default is "/")
  disableLandingPageButton = true
  # When using mulitlingual website, disable the switch language button.
  disableLanguageSwitchingButton = false
  # Hide breadcrumbs in the header and only show the current page title
  disableBreadcrumb = true
  # If set to true, hide table of contents menu in the header of all pages
  disableToc = false
  # If set to false, load the MathJax module on every page regardless if a MathJax shortcode is present
  disableMathJax = false
  # Specifies the remote location of the MathJax js
  customMathJaxURL = "https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"
  # Initialization parameter for MathJax, see MathJax documentation
  mathJaxInitialize = "{}"
  # If set to false, load the Mermaid module on every page regardless if a Mermaid shortcode or Mermaid codefence is present
  disableMermaid = false
  # Specifies the remote location of the Mermaid js
  customMermaidURL = "https://unpkg.com/mermaid/dist/mermaid.min.js"
  # Initialization parameter for Mermaid, see Mermaid documentation
  mermaidInitialize = "{ \"theme\": \"default\" }"
  # If set to false, load the Swagger module on every page regardless if a Swagger shortcode is present
  disableSwagger = false
  # Specifies the remote location of the RapiDoc js
  customSwaggerURL = "https://unpkg.com/rapidoc/dist/rapidoc-min.js"
  # Initialization parameter for Swagger, see RapiDoc documentation
  swaggerInitialize = "{ \"theme\": \"light\" }"
  # Hide Next and Previous page buttons normally displayed full height beside content
  disableNextPrev = true
  # Order sections in menu by "weight" or "title". Default to "weight";
  # this can be overridden in the pages frontmatter
  ordersectionsby = "weight"
  # Change default color scheme with a variant one. Eg. can be "auto", "red", "blue", "green" or an array like [ "blue", "green" ].
  themeVariant = "auto"
  # Change the title separator. Default to "::".
  titleSeparator = "-"
  # If set to true, the menu in the sidebar will be displayed in a collapsible tree view. Although the functionality works with old browsers (IE11), the display of the expander icons is limited to modern browsers
  collapsibleMenu = false
  # If a single page can contain content in multiple languages, add those here
  additionalContentLanguage = [ "en" ]
  # If set to true, no index.html will be appended to prettyURLs; this will cause pages not
  # to be servable from the file system
  disableExplicitIndexURLs = false
  # For external links you can define how they are opened in your browser; this setting will only be applied to the content area but not the shortcut menu
  externalLinkTarget = "_blank"

Syntax highlighting

Supports a variety of [Code Syntaxes] To select the syntax, wrap the code in backticks and place the syntax by the first set of backticks.

```bash
echo hello
\```

Adding tags

Tags are displayed in order at the top of the page. They will also display using the menu shortcut made further down.

Add tags to a page:

+++
tags = ["tutorial", "theme"]
title = "Theme tutorial"
weight = 15
+++

Choose a default color theme

Add to config.toml with the chosen theme for the “style” option:

[markup]
  [markup.highlight]
    # if `guessSyntax = true`, there will be no unstyled code even if no language
    # was given BUT Mermaid and Math codefences will not work anymore! So this is a
    # mandatory setting for your site if you want to use Mermaid or Math codefences
    guessSyntax = false

    # choose a color theme or create your own
    style = "base16-snazzy"

Add Print option and search output page.

add the following to config.toml

[outputs]
  home = ["HTML", "RSS", "PRINT", "SEARCH"]
  section = ["HTML", "RSS", "PRINT"]
  page = ["HTML", "RSS", "PRINT"]

Customization

This theme has a bunch of editable customizations called partials. You can overwrite the default partials by putting new ones in /layouts/partials/.

to customize “partials”, create a “partials” directory under site/layouts/

cd layouts
mkdir partials
cd partials

You can find all of the partials available for this theme here

Change the site logo using the logo.html partial

Create logo.html in /layouts/partials

vim logo.html

Add the content you want in html. This can be an img html tag referencing an image in the static folder. Or even basic text. Here is the basic syntax of an html page, adding “Perfect Dark Mode” as the text to display:

<!DOCTYPE html>
<html>
<body>

<h3>Perfect Dark Mode</h3>

</body>
</html>

Add a favicon to your site

  • This is pasted from the relearn site. Add Favicon and edit * If your favicon is a SVG, PNG or ICO, just drop off your image in your local static/images/ folder and name it favicon.svgfavicon.png or favicon.ico respectively.

If no favicon file is found, the theme will lookup the alternative filename logo in the same location and will repeat the search for the list of supported file types.

If you need to change this default behavior, create a new file in layouts/partials/ named favicon.html. Then write something like this:

<link rel="icon" href="/images/favicon.bmp" type="image/bmp">

Changing theme colors

In your config.toml file edit the themeVariant option under [params]

  themeVariant = "relearn-dark"

There are some options to choose from or you can custom make your theme colors by using this stylesheet generator

Menu Shortcuts Add a [[menu.shortcuts]] entry for each link

[[menu.shortcuts]]
name = "<i class='fab fa-fw fa-github'></i> GitHub repo"
identifier = "ds"
url = "https://github.com/McShelby/hugo-theme-relearn"
weight = 10

[[menu.shortcuts]]
name = "<i class='fas fa-fw fa-camera'></i> Showcases"
url = "more/showcase/"
weight = 11

[[menu.shortcuts]]
name = "<i class='fas fa-fw fa-bookmark'></i> Hugo Documentation"
identifier = "hugodoc"
url = "https://gohugo.io/"
weight = 20

[[menu.shortcuts]]
name = "<i class='fas fa-fw fa-bullhorn'></i> Credits"
url = "more/credits/"
weight = 30

[[menu.shortcuts]]
name = "<i class='fas fa-fw fa-tags'></i> Tags"
url = "tags/"
weight = 40

Nextcloud Setup on Alma 9 with Apache

I’m going to show you how to set up your own, self-hosted Nextcloud server using Alma Linux 9 and Apache.

What is Nextcloud?

Nextcloud is so many things. It offers so many features and options, it deserves a bulleted list:

  • Free and open source
  • Cloud storage and syncing
  • Email client
  • Custom browser dashboard with widgets
  • Office suite
  • RSS newsfeed
  • Project organization (deck)
  • Notebook
  • Calender
  • Task manager
  • Connect to decentralized social media (like Mastodon)
  • Replacement for all of google’s services
  • Create web forms or surveys

It is also free and open source. This mean the source code is available to all. And hosting yourself means you can guarantee that your data isn’t being shared.

As you can see. Nextcloud is feature packed and offers an all in one solution for many needs. The set up is fairly simple.

You will need:

  • Domain hosted through CloudFlare or other hosting.
  • Server with Alma Linux 9 with a dedicated public ip address.

Nextcloud dependencies:

  • PHP 8.3
  • Apache
  • sql database (This tutorial uses MariaDB)

Official docs: https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html

Setting up dependencies

Install latest supported PHP

I used this guide to help get a supported php version. As php 2 installed from dnf repos by default: https://orcacore.com/php83-installation-almalinux9-rockylinux9/

Make sure dnf is up to date:

sudo dnf update -y
sudo dnf upgrade -y

Set up the epel repository:

sudo dnf install epel-release -y

Set up remi to manage php modules:

sudo dnf install -y dnf-utils http://rpms.remirepo.net/enterprise/remi-release-9.rpm
sudo dnf update -y

Remove old versions of php:

sudo dnf remove php* -y

List available php streams:

sudo dnf module list reset php -y

Last metadata expiration check: 1:03:46 ago on Sun 29 Dec 2024 03:34:52 AM MST.
AlmaLinux 9 - AppStream
Name                Stream                      Profiles                                  Summary                             
php                 8.1                         common [d], devel, minimal                PHP scripting language              
php                 8.2                         common [d], devel, minimal                PHP scripting language              

Remi's Modular repository for Enterprise Linux 9 - x86_64
Name                Stream                      Profiles                                  Summary                             
php                 remi-7.4                    common [d], devel, minimal                PHP scripting language              
php                 remi-8.0                    common [d], devel, minimal                PHP scripting language              
php                 remi-8.1                    common [d], devel, minimal                PHP scripting language              
php                 remi-8.2                    common [d], devel, minimal                PHP scripting language              
php                 remi-8.3 [e]                common [d], devel, minimal                PHP scripting language              
php                 remi-8.4                    common [d], devel, minimal                PHP scripting language       

Enable the correct stream:

sudo dnf module enable php:remi-8.3

Now the default to install is version 8.3, install it like this:

sudo dnf install php -y
php -v

Let’s install git, as it’s also needed in this setup: sudo dnf -y install git

Install Composer for managing php modules:

cd && curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer

Install needed PHP modules: sudo dnf install php-process php-zip php-gd php-mysqlnd

Upgrade php memory limit: sudo vim /etc/php.ini

memory_limit = 512M

Apache setup

Add Apache config for vhost: sudo vim /etc/httpd/conf.d/nextcloud.conf

<VirtualHost *:80>
  DocumentRoot /var/www/nextcloud/
  ServerName  {subdomain}.{example}.com

  <Directory /var/www/nextcloud/>
    Require all granted
    AllowOverride All
    Options FollowSymLinks MultiViews

    <IfModule mod_dav.c>
      Dav off
    </IfModule>
  </Directory>
</VirtualHost>

Set up the mysql database

Install: sudo dnf install mariadb-server -y

Enable the service: sudo systemctl enable --now mariadb

Nextcloud needs some tables setup in order to store information in a database. First set up a secure sql database:

sudo mysql_secure_installation

Say “Yes” to the prompts and enter root password:

Switch to unix_socket authentication [Y/n]: Y
Change the root password? [Y/n]: Y	# enter password.
Remove anonymous users? [Y/n]: Y
Disallow root login remotely? [Y/n]: Y
Remove test database and access to it? [Y/n]: Y
Reload privilege tables now? [Y/n]: Y

Sign in to your SQL database with the password you just chose:

mysql -u root -p

Create the database:

While signed in with the mysql command, enter the commands below one at a time. Make sure to replace the username and password. But leave localhost as is:

CREATE DATABASE nextcloud;
GRANT ALL ON nextcloud.* TO '{username}'@'localhost' IDENTIFIED BY '{password}';
FLUSH PRIVILEGES;
EXIT;

Nextcloud Install

Clone the git repo into /var/www/nextcloud: git clone https://github.com/nextcloud/server.git /var/www/nextcloud && cd /var/www/nextcloud

Add an exception for git to access the directory:

git config --global --add safe.directory /var/www/nextcloud

Initialize the git submodule that handles the subfolder “3rdpartysudo”:

cd /var/www/nextcloud && sudo git submodule update --init

Change the nextcloud folder ownership to apache and add permissions: sudo chmod -R 755 /var/www/nextcloud sudo chown -R apache:apache /var/www/nextcloud

Selinux:

sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/nextcloud(/.*)?" && \
sudo semanage fcontext -a -t httpd_sys_rw_content_t "/var/www/nextcloud/(config|data|apps)(/.*)?" && \
sudo restorecon -Rv /var/www/nextcloud/

Now we can actually install Nextcloud. cd to the /var/www/nextcloud directory and run occ with these settings to install:

sudo -u apache php occ  maintenance:install \
--database='mysql' --database-name='nextcloud' \
--database-user='root' --database-pass='{password}' \
--admin-user='admin' --admin-pass='{password}'

Create a CNAME record for DNS.

Before you go any further, you will need to have a domain name set up for your server. I use Cloudflare to manage my DNS records. You will want to make a CNAME record for your nextcloud subdomain.

Just add “nextcloud” as the name and “yourwebsite.com” as the content. This will make it so “nextcloud.yourwebsite.com” is the site for your nextcloud dashboard. Also, make sure to select “DNS Only” under proxy status.

Here’s what my CloudFlare domain setup looks with this blog as the main site, and cloud.perfectdarkmode.com as the nextcloud site:

Then you need to update trusted domains in /var/www/nextcloud/config/config.php:

'trusted_domains' =>
   [
    '{subdomain}.{domain}.com',
    'localhost'
  ],

Restart httpd systemctl restart httpd

Install SSL with Certbot

Obtain an SSL certificate. (See my Obsidian site setup post for information about Certbot and Apache setup.)

sudo certbot -d {subdomain}.{domain}.com

Now log into nextcloud with your admin account using the DNS name you set earlier:

I recommend setting up a normal user account instead of doing everything as “admin”. Just hit the “A” icon at the top right and go to “Accounts”. Then just select “New Account” and create a user account with whatever privileges you want.

I may make a post about which Nextcloud apps I recommend and customize the setup a bit. Let me know if that’s something you’d like to see. That’s all for now.

Obsidian to Hugo Website Setup

Sync obsidian dirs to hugo dirs: rsync -av --delete source destination –delete flag deletes files in the destination directory if they do not exist in the source

#!/bin/bash
rsync -av --delete ~/Documents/content/booknotes ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/'health and fitness' ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/images ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/linux ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/networking ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/now ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/philosophy ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/python ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/Recipes ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/Recommended ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/tools ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/writing ~/Documents/blog/content/
rsync -av --delete ~/Documents/content/_index.md ~/Documents/blog/content/

cd /home/david/Documents/blog &&
hugo &&
if ! nmcli connection show --active | grep -q "Primary"; 
	then
		echo "Starting VPN..."
		nmcli connection up id "Primary"
  sleep 5
fi

rsync -rtvzP ~/Documents/blog/docs/ {username}@{ip-address}:/var/www/public

Using inotify to monitor obsidian and run the update script whenever there are changes:

sudo dnf -y install inotify-tools

Script to monitor the folder:

vim ~/Documents/Scripts/obsidian_monitor.sh
#!/bin/bash

inotifywait -m -r -e modify,create,delete "~/Documents/content/" | while read path action file; do
  echo "Change detected: $action on $file"
  ~/Documents/Scripts/hugoupdate.sh
done

Make script executable: chmod +x ~/Documents/Scripts/obsidian_monitor.sh

Create startup script ~/.config/systemd/user/obsidian-monitor.service

vim ~/.config/systemd/user/obsidian-monitor.service 
[Unit]

Description=Obsidian Monitor
After=network.target

[Service]
ExecStart=/home/david/Documents/Scripts/obsidian_monitor.sh
Restart=always
#User=david

[Install]
WantedBy=multi-user.target

Reload systemd, enable, and start the service:

systemctl --user daemon-reload
systemctl --user enable obsidian-monitor.service
systemctl --user start obsidian-monitor.service

Run hugo to build the html

On the server

Create the directory for the html files:

mkdir -p /var/www/public

From your laptop, yeet the files over to the /var/www directory on the server: `rsync -rtvzP ~/Documents/blog/docs/ {username}@{servername or ip}:/var/www/public

Update file owner and permissions:

sudo find /var/www/public -type d -exec chmod +x {} \;
sudo find /var/www/public -type f -exec chmod 644 {} \;
sudo chown -R apache:apache /var/www/public

Check active vhosts:

httpd -D DUMP_VHOSTS  

Firewall Permissions

You will need to make sure your firewall allows port 80 and 443. Vultr installs the ufw program by default. But your can install it if you used a different provider. Beware, enabling a firewalll could block you from accessing your vm, so do your research before tinkering outside of these instructions.

sudo firewall-cmd --add-service https --permanent
sudo firewall-cmd --add-service http --permanent

Setting up the Apache Server

Install apache: sudo dnf -y install httpd

Comment out ServerName and DocumentRoot directives in /etc/httpd/conf/httpd.conf file.

Get rid of userdir.conf sudo mv /etc/httpd/conf.d/userdir.conf /etc/httpd/conf.d/userdir.conf.old

Comment out /etc/httpd/conf.d/welcome.conf:

# 
# This configuration file enables the default "Welcome" page if there
# is no default index page present for the root URL.  To disable the
# Welcome page, comment out all the lines below. 
#
# NOTE: if this file is removed, it will be restored on upgrades.
#
#<LocationMatch "^/+$">
#    Options -Indexes
#    ErrorDocument 403 /.noindex.html
#</LocationMatch>

#<Directory /usr/share/httpd/noindex>
#    AllowOverride None
#    Require all granted
#</Directory>

#Alias /.noindex.html /usr/share/httpd/noindex/index.html
#Alias /poweredby.png /usr/share/httpd/icons/apache_pb3.png
#Alias /system_noindex_logo.png /usr/share/httpd/icons/system_noindex_logo.png

Create vhost file: sudo vim /etc/httpd/conf.d/vhost_{sitename}.com

<VirtualHost *:80>
    ServerAdmin webmaster@{sitename}.com
    DocumentRoot /var/www/public
    ServerName {sitename}.com
    ServerAlias www.{sitename}.com
    Redirect permanent / https://{sitename}.com/
    ErrorLog logs/{sitename}_error.log
    CustomLog logs/{sitename}_access.log combined
</VirtualHost>

Enable the apache service now and at startup: sudo systemctl enable --now httpd

Use certbot to generate certs for SSL/TLS:

Install certbot:

Sudo dnf -y install epel-release
sudo dnf install certbot python3-certbot-apache -y

Restore selinux contexts: sudo restorecon -Rv /var/www/public

Restart the httpd service: sudo systemctl restart httpd

Set Up a Cronjob to automatically Renew certbot certs

crontab -e

Select a text editor and add this line to the end of the file. Then save and exit the file:

0 0 1 * * certbot --httpd renew

You now have a running website. Just make new posts locally, the run “hugo” to rebuild the site. And use the rsync alias to update the folder on your server. I will soon be making tutorials on making an email address for your domain, such as david@perfectdarkmode.com on my site. I will also be adding a comments section, RSS feed, email subscription, sidebar, and more.

Feel free to reach out with any questions if you get stuck. This is meant to be an all encompassing guide. So I want it to work.

Setting Up a Self-hosted NextCloud Server

This is a step-by-step guide to setting up Nextcloud on a Debian server. You will need a server hosted by a VPS like Vultr. And a Domain hosted by a DNS provider such as Cloudflare

What is Nextcloud?

Nextcloud is so many things. It offers so many features and options, it deserves a bulleted list:

  • Free and open source
  • Cloud storage and syncing
  • Email client
  • Custom browser dashboard with widgets
  • Office suite
  • RSS newsfeed
  • Project organization (deck)
  • Notebook
  • Calender
  • Task manager
  • Connect to decentralized social media (like Mastodon)
  • Replacement for all of google’s services
  • Create web forms or surveys

It is also free and open source. This mean the source code is available to all. And hosting yourself means you can guarantee that your data isn’t being shared.

As you can see. Nextcloud is feature packed and offers an all in one solution for many needs. The set up is fairly simple!

Install Dependencies

sudo apt update 

Sury Dependencies

sudo apt install software-properties-common ca-certificates lsb-release apt-transport-https 

Enable Sury Repository

sudo sh -c 'echo "deb https://packages.sury.org/php/ $(lsb_release -sc) main" > /etc/apt/sources.list.d/php.list' 

Import the GPG key for the repository

wget -qO - https://packages.sury.org/php/apt.gpg | sudo apt-key add - 

Install PHP 8.2

https://computingforgeeks.com/how-to-install-php-8-2-on-debian/?expand_article=1 (This is also part of the other dependencies install command below)

sudo apt install php8.2 

Install other dependencies:

apt install -y nginx python3-certbot-nginx mariadb-server php8.2 php8.2-{fpm,bcmath,bz2,intl,gd,mbstring,mysql,zip,xml,curl}

Improving Nextcloud server performance

Adding more child processes for PHP to use:

vim /etc/php/8.2/fpm/pool.d/www.conf

# update the following parameters in the file
pm = dynamic
pm.max_children = 120
pm.start_servers = 12
pm.min_spare_servers = 6
pm.max_spare_servers = 18

Start your MariaDB server:

systemctl enable mariadb --now

Set up a SQL Database

Nextcloud needs some tables setup in order to store information in a database. First set up a secure sql database:

sudo mysql_secure_installation

Say “Yes” to the prompts and enter root password:

Switch to unix_socket authentication [Y/n]: Y
Change the root password? [Y/n]: Y	# enter password.
Remove anonymous users? [Y/n]: Y
Disallow root login remotely? [Y/n]: Y
Remove test database and access to it? [Y/n]: Y
Reload privilege tables now? [Y/n]: Y

Sign in to your SQL database with the password you just chose:

mysql -u root -p

Creating a database for NextCloud

While signed in with the mysql command, enter the commands below one at a time. Make sure to replace the username and password. But leave localhost as is:

CREATE DATABASE nextcloud;
GRANT ALL ON nextcloud.* TO 'david'@'localhost' IDENTIFIED BY '@Rfanext12!';
FLUSH PRIVILEGES;
EXIT;

Install SSL with Certbot

Obtain an SSL certificate. See my website setup post for information about Certbot and nginx setup.

certbot certonly --nginx -d nextcloud.example.com

Create a CNAME record for DNS.

You will need to have a domain name set up for your server. I use Cloudflare to manage my DNS records. You will want to make a CNAME record for your nextcloud subdomain.

Just add “nextcloud” as the name and “yourwebsite.com” as the content. This will make it so “nextcloud.yourwebsite.com”. Make sure to select “DNS Only” under proxy status.

Nginx Setup

Edit your sites-available config at /etc/nginx/sites-available/nextcloud. See comments in the following text box:

vim /etc/nginx/sites-available/nextcloud

# Add this to the file:
# replace example.org with your domain name
# use the following vim command to make this easier
# :%s/example.org/perfectdarkmode.com/g
# ^ this will replace all instances of example.org with perfectdarkmode.com. Replace with yur domain

upstream php-handler {
    server unix:/var/run/php/php8.2-fpm.sock;
    server 127.0.0.1:9000;
}
map $arg_v $asset_immutable {
    "" "";
    default "immutable";
}
server {
    listen 80;
    listen [::]:80;
    server_name nextcloud.example.org ;
    return 301 https://$server_name$request_uri;
}
server {
    listen 443      ssl http2;
    listen [::]:443 ssl http2;
    server_name nextcloud.example.org ;
    root /var/www/nextcloud;
    ssl_certificate     /etc/letsencrypt/live/nextcloud.example.org/fullchain.pem ;
    ssl_certificate_key /etc/letsencrypt/live/nextcloud.example.org/privkey.pem ;
    client_max_body_size 512M;
    client_body_timeout 300s;
    fastcgi_buffers 64 4K;
    gzip on;
    gzip_vary on;
    gzip_comp_level 4;
    gzip_min_length 256;
    gzip_proxied expired no-cache no-store private no_last_modified no_etag auth;
    gzip_types application/atom+xml application/javascript application/json application/ld+json application/manifest+json application/rss+xml application/vnd.geo+json application/vnd.ms-fontobject application/wasm application/x-font-ttf application/x-web-app-manifest+json application/xhtml+xml application/xml font/opentype image/bmp image/svg+xml image/x-icon text/cache-manifest text/css text/plain text/vcard text/vnd.rim.location.xloc text/vtt text/x-component text/x-cross-domain-policy;
    client_body_buffer_size 512k;
    add_header Referrer-Policy                      "no-referrer"   always;
    add_header X-Content-Type-Options               "nosniff"       always;
    add_header X-Download-Options                   "noopen"        always;
    add_header X-Frame-Options                      "SAMEORIGIN"    always;
    add_header X-Permitted-Cross-Domain-Policies    "none"          always;
    add_header X-Robots-Tag                         "none"          always;
    add_header X-XSS-Protection                     "1; mode=block" always;
    fastcgi_hide_header X-Powered-By;
    index index.php index.html /index.php$request_uri;
    location = / {
        if ( $http_user_agent ~ ^DavClnt ) {
            return 302 /remote.php/webdav/$is_args$args;
        }
    }
    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
    location ^~ /.well-known {
        location = /.well-known/carddav { return 301 /remote.php/dav/; }
        location = /.well-known/caldav  { return 301 /remote.php/dav/; }
        location /.well-known/acme-challenge    { try_files $uri $uri/ =404; }
        location /.well-known/pki-validation    { try_files $uri $uri/ =404; }
        return 301 /index.php$request_uri;
    }
    location ~ ^/(?:build|tests|config|lib|3rdparty|templates|data)(?:$|/)  { return 404; }
    location ~ ^/(?:\.|autotest|occ|issue|indie|db_|console)                { return 404; }
    location ~ \.php(?:$|/) {
        # Required for legacy support
        rewrite ^/(?!index|remote|public|cron|core\/ajax\/update|status|ocs\/v[12]|updater\/.+|oc[ms]-provider\/.+|.+\/richdocumentscode\/proxy) /index.php$request_uri;
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        set $path_info $fastcgi_path_info;
        try_files $fastcgi_script_name =404;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $path_info;
        fastcgi_param HTTPS on;
        fastcgi_param modHeadersAvailable true;
        fastcgi_param front_controller_active true;
        fastcgi_pass php-handler;
        fastcgi_intercept_errors on;
        fastcgi_request_buffering off;
        fastcgi_max_temp_file_size 0;
    }
    location ~ \.(?:css|js|svg|gif|png|jpg|ico|wasm|tflite|map)$ {
        try_files $uri /index.php$request_uri;
        add_header Cache-Control "public, max-age=15778463, $asset_immutable";
        access_log off;     # Optional: Don't log access to assets
        location ~ \.wasm$ {
            default_type application/wasm;
        }
    }
    location ~ \.woff2?$ {
        try_files $uri /index.php$request_uri;
        expires 7d;
        access_log off;
    }
    location /remote {
        return 301 /remote.php$request_uri;
    }
    location / {
        try_files $uri $uri/ /index.php$request_uri;
    }
}

Enable the site

Create a link between the file you just made and /etc/nginx/sites-enabled

ln -s /etc/nginx/sites-available/nextcloud /etc/nginx/sites-enabled/

Install Nextcloud

Download the latest Nextcloud version. Then extract into /var/www/. Also, update the file’s permissions to give nginx access:

wget https://download.nextcloud.com/server/releases/latest.tar.bz2
tar -xjf latest.tar.bz2 -C /var/www
chown -R www-data:www-data /var/www/nextcloud
chmod -R 755 /var/www/nextcloud

Start and enable php-fpm on startup

<systemctl enable php8.2fpm --now](><--may not need this.
# Do need this->
sudo systemctl enable php8.2-fpm.service --now

Reload nginx

systemctl reload nginx

Nextcloud occ tool

Here is a built in Nextcloud tool just in case things break. Here is a guide on troubleshooting with occ. The basic command is as follows:

sudo -u www-data php /var/www/nextcloud/occ

Add this as an alias in ~/.bashrc for ease of use.

You are ready to log in to Nextcloud!

Go to your nextcloud domain in a browser. In my case, I head to nextcloud.perfectdarkmode.com. Fill out the form to create your first Nextcloud user:

  • Choose an admin username and secure password.
  • Leave Data folder as the default value.
  • For Database user, enter the user you set for the SQL database.
  • For Database password, enter the password you chose for the new user in MariaDB.
  • For Database name, enter: nextcloud
  • Leave “localhost” as “localhost”.
  • Click Finish.

Now that you are signed in. Here are a few things you can do to start you off:

  • Download the desktop and mobile app and sync all of your data. (covered below)
  • Look at different apps to consolodate your programs all in one place.
  • Put the Nextcloud dashboard as your default browser homepage and customize themes.
  • Set up email integration.

NextCloud desktop synchronization

Install the desktop client (Fedora)

Sudo dnf install nextcloudclient

Install on other distros: https://help.nextcloud.com/t/install-nextcloud-client-for-opensuse-arch-linux-fedora-ubuntu-based-android-ios/13657

  1. Run the nextcloud desktop app and sign in.
  2. Choose folders to sync.
  3. Folder will be ~/Nextcloud.
  4. Move everything into your nextcloud folder.

This may break things with filepaths so beware. Now you are ready to use and explore nextcloud. Here is a video from TechHut to get you started down the NextCloud rabbit hole.

Change max upload size (default is 500mg)

/var/www/nextcloud/.user.ini php_value upload_max_filesize = 16G php_value post_max_size = 16G

Remove file locks

Put Nextcloud in maintenance mode: Edit config/config.php and change this line:
'maintenance' => true,

Empty table oc_file_locks: Use tools such as phpmyadmin or connect directly to your database and run (the default table prefix is oc_, this prefix can be different or even empty):
DELETE FROM oc_file_locks WHERE 1

mysql -u root -p
MariaDB [(none)]> use nextcloud;
MariaDB [nextcloud]> DELETE FROM oc_file_locks WHERE 1;

*figure out redis install if this happens regularly* [https://docs.nextcloud.org/server/13/admin_manual/configuration_server/caching_configuration.html#id4 9.1k](https://docs.nextcloud.org/server/13/admin_manual/configuration_server/caching_configuration.html#id4)

Using Vagrant on Linux

Vagrant is software that lets you set up multiple, pre-configured virtual machines in a flash. I am going to show you how to do this using Linux and Virtual Box. But you can do this on MacOS and Windows as well.

Download Vagrant, VirtualBox and Git.

Vagrant link.

Virtualbox link.

You may want to follow another tutorial for setting up VirtualBox.

Git link.

Installing git will install ssh on windows. Which you will use to access your lab. Just make sure you select the option to add git and unit tools to your PATH variable.

Make a Vagrant project folder.

Note: All of these commands are going to be in a Windows command prompt.

mkdir vagranttest

Move in to your new directory.

cd vagranttest

Add and Initialize Your Vagrant Project.

You can find preconfigured virtual machines here.

We are going to use ubuntu/trusty64.

Add the Vagrant box

vagrant box add ubuntu/trusty64

Initialize your new Vagrant box

vagrant init ubuntu/trusty64

Use the dir command to see the contents of this directory.

We are going to edit this Vagrantfile to set up our multiple configurations.

vim Vagrantfile

Here is the new config without all of the commented lines. Add this (minus the top line) under Vagrant.configure(“2”) do |config|.

Vagrant.configure("2") do |config|  
  config.vm.box = "ubuntu/trusty64"  
  config.vm.define "server1" do |server1|  
    server1.vm.hostname = "server1"  
    server1.vm.network "private_network", ip: "10.1.1.2"  
  end  
  config.vm.define "server2" do |server2|  
    server2.vm.hostname = "server2"  
    server2.vm.network "private_network", ip: "10.1.1.3"  
  end  
end

Now save your Vagrant file in Vim.

Bring up your selected vagrant boxes:

vagrant up

Now if you open virtual box, you should see the new machines running in headless mode. This means that the machines have no user interface..

Ssh into server1

vagrant ssh server1

You are now in serve1’s terminal.

From server1, ssh into server2

ssh 10.1.1.3

Success! You are now in server2 and can access both machines from your network. Just enter “exit” to return to the previous terminal.

Additional Helpful Vagrant Commands.

Without the machine name specified, vagrant commands will work on all virtual machines in your vagrant folder. I’ve thrown in a couple examples using [machine-name] at the end.

Shut down Vagrant machines

vagrant halt

Shut down only one machine

vagrant halt [machine-name]

Suspend and resume a machine

vagrant suspend
vagrant resume

Restart a virtual machine

vagrant reload

Destroy a virtual machine

vagrant detstroy [machine-name]

Show running vms

vagrant status

List Vagrant options

vagrant

Playground for future labs

This type of deployment is going to be the bedrock of many Linux and Red Hat labs. You can easily use pre-configured machines to create a multi-machine environment. This is also a quick way to test your network and server changes without damaging anything.

Now go set up a Vagrant lab yourself and let me know what you plan to do with it!

What is Vagrant?

  • Easy to configure, reproducible environments
  • Provisions virtualbox vms
  • Vagrant box: OS image

Syntax:

vagrant box add user/box

Add centos7 box

vagrant box add jasonc/centos7

Many public boxes to download

Vagrant project = folder with a vagrant file

Install Vagrant here: https://www.vagrantup.com/downloads

Make a vagrant folder:

mkdir vm1
cd vm1

initialize vagrant project:

vagrant init jasonc/centos7

bring up all vms defined in the vagrant file)

vagrant up

vagrant will import the box into virtualbox and start it

the vm is started in headless mode

(there is no user interfaces)

Vagrant up / multi machine

Bring up only one specific vm

  • vagrant up [vm-name]

SSH Vagrant

  • vagrant ssh [vm_name] or vagrant ssh if there is only one vm in the vagrant file

Need to download ssh for windows

downloading git will install this:

https://desktop.github.com/

Shut down vagrant machines vagrant halt

Shutdown only one machine vagrant halt [vm]

Saves present state of the machine

just run vagrant up without having to import tha machines again

Suspend the machine vagrant suspend [VM]

Resume vagrant resume [VM]

Destroy VM vagrant destroy [VM]

List options vagrant

Vagrant command works on the vagrant folder that you are in

Vagrant File

Vagrant.configure (2) do | config |

config.vm.box = "jasonc/centos7"

config.vm.hostname = "linuxsvr1"

(default files)

config.vm.network "private_network", ip: "10.2.3.4"

config.vm.provider "virtualbox" do | vbi

vb.gui = true

vb.memory = "1024"

(shell provisioner)

config.vm.provision "shell", path: "setup.sh"

end

end

Configuring a multi machine setup:

Specify common configurations at the top of the file

Vagrant.configure (2) do | config |

config.vm.box = "jasonc/centos7"

config.vm.define = "server1" do | server1 |

server1.vm.hostname = "server1"

server1.vm.network "private_network", ip: "10.2.3.4"

end

config.vm.define = "server2" do | server2 |

server2.vm.hostname = "server2"

server2.vm.network "private_network", ip: "10.2.3.5"

end

end

You can search for vagrant boxes at https://app.vagrantup.com/boxes/search

Course software downloads: http://mirror.linuxtrainingacademy.com/

Install Git: https://git-scm.com/download/win

  • make sure to check option for git and unit tools to be added to the PATH

vagrant ssh

  • to connect to the vagrant machine in the folder that you are in
  • default password in vagrant
  • tyoe ’exit to return to prompt

vagrant halt

  • stop the vm and save it’s current state

vagrant reload

  • restarts the vm

vagrant status

  • shows running vms in that folder

You can access files in the vagrant directory from both VMs

Example RHEL8 Config

Vagrant.configure("2") do |config|

config.vm.box = "generic/rhel8"

config.vm.define "server1" do |server1|

server1.vm.hostname = "server1.example.com"

server1.vm.network "private_network", ip: "192.168.1.110"

config.disksize.size = '10GB'

end

config.vm.define "server2" do |server2|

server2.vm.hostname = "server2.example.com"

server2.vm.network "private_network", ip: "192.168.1.120"

config.disksize.size = '16GB'

end

config.vm.provider "virtualbox" do |vb|

vb.memory = "2048"

end

end

Plugin to change the disk size:

vagrant plugin install vagrant-disksize

Subsections of Writing

19 Biggest Lessons from Reading 100 Books

I started reading non-fiction after hitting my rock bottom. I found people to look up to and saw that they were reading and learning constantly to better themselves. This inspired me to develop a reading and self improvement habit that I have continued for more than 10 years.

No single book has the ability to change your life. But the things you do, good or bad, over time, compound to extraordinary changes.

Here are some things that have stuck with me. (In no particular order)

1. Become interested in other people.

Once you start to see things from someone else’s view. You will have more empathy for other people. Connecting with others is what life is all about. You will not be successful in life or business without this.

2. The safe route comes with a lot of risk.

Go to college. Add to your 401k. Work a 9-5 until you are 65. This seems like the safer route. But there are a lot of risks in taking the normal path.

3. Personal development is the best way to save a relationship.

You can’t change other people. Start by reading non fictions books to discover solutions to your problems. Get your body in order. Your finances in check. Take control of your health. Start dressing nice around the house. Check in to life.

4. Feeding into sexual instincts makes you crave novelty.

Your animal self wants to mate with a variety of partners. When you reach sexual satisfaction, a cascade of events starts happening that turns you away from your partner. And make you crave novelty. If not a new partner, then some other stimulus to chase.

5. Beat procrastination by just doing the thing.

There is no answer to “How do I start?” or “What do I do next?”. You just need to clear the way for your brain to do it’s job. Open up your canvas and just begin.

6. Leaning into pain will set you free.

We are constantly running from pain and towards pleasure. In order to maintain homeostasis, your body will build tolerance and your pain/ pleasure set points will get all jacked up. Doing hard things is the only way to reset this balance.

7. Just be happy.

We can spend years seeking for answers, wanting and craving more, being unhappy with our situation. They day will never come when things are just right. Let go and just decide to be happy.

8. Take ownership of EVERYTHING.

There is no point of blaming others. To be a leader, you need to own everything. Even stuff that is not your fault.

9. Your mind is very good at getting things to happen that you want to happen.

Once you get out of your own way, you can accomplish great things. Do not underestimate your ability to figure things out.

10. Train your brain to focus by doing less.

Your ability to focus is greatly effected by your ability to let things go. Less is more in this case.

11. Set your goals over 3 months instead of yearly.

It’s almost impossible to plan effectively over a year. There are too many unknowns that can happen. Set shorter term goals and you will be able to plan down to the nitty-gritty details.

12. You can train a dog to do anything without being a dick.

A lot of people think you have to be mean to dogs in order to bend them to your will. Turns out, dogs will endure pain to get rewards. So not only is this ineffective, it’s downright bad for you and your dog. Have some compassion. Don’t be lazy. Do it the right way.

13. People have lived through some shitty situations.

Digging into history will give you some serious perspective. You don’t have to look far to see just how easy you have it. This perspective is essential.

14. You are the only one your kids can depend on. They constantly test you to make sure you will never abandon them.

Your child needs to know that you love them no matter what. Of course you love them but they do not always see it depending on how you act as a parent. Have compassion. You are on their team.

15. Religion is a plague on Humanity.

Belief is the most powerful force. Even more powerful than time. By default, people act according to their beliefs. And will do bad or stupid things without a second thought. We need to abandon this and be okay with not knowing.

16. Humans treat animals very poorly.

How do we have compassion for an insect or even plants in some cases? But we turn a blind eye on industries that experiment, torture, and kill animals with such great complexity? If you had a pet monkey, mouse, cow, chicken, pig, sheep, etc., you would bond with these animals and go through great lengths to make them happy and comfortable.

Is it cognitive dissonance? Fear of finding out the truth? Compassion is the most manly thing ever.

17. Don’t focus on what you can’t control.

We spend a great deal of energy and time worrying about the future or regretting the past. Start to filter out things that you have no control over. And lean into the things you can control. You will be much happier.

18. Do hard things to immunize yourself for when hard things happen.

We live comfortable lives. But things won’t always be that way. Probably for anyone. Find something hard to do. Or give up something you enjoy. Even just for a day. And when the time comes to face adversity, you will be a little bit more prepared then if you never left your comfort zone in the first place.

19. We may not have as much Free Will as we think.

Imagine Osama Bin Laden’s son becoming anything other than what he is. When and where you were born. Who you were raised by. And life circumstances greatly impact who you are, the way you think, and how you behave. We aren’t in as much control as we think.

But all is not lost. Understanding this will give you compassion not just for others, but for your own shortcomings as well.


If you made it this far…

Please consider giving me some feedback. I want to become a better writer and help others grow along with me. Feedback is invaluable for this goal.

Thanks for reading!

Nat Eliason's SEO Course

Things I learned for Nat Eliason’s SEO Course

Leveling up

  • Start with an easy keyword
  • Over time, adjust article for harder and harder keywords
  • Long tail keywords with low competition
  • Can change meta title for google to the harder keyword later
  • Can only change the meta title unless there is something the content is missing that the broader keyword asks for.
  • At first, pick something under 5,000 searches

You don’t need to spend time building backlinks. You can rank for keywords that aren’t even IN your articles. You don’t need to focus on keyword density. Focus on intent.

Google analytics and keyword planner are all that’s needed. They are completely free.

How to think about SEO

Google is for answering people’s questions Google knows more that SEO experts about how Google works Any ranking trick will be fixed

Your goal: Answer questions better than anyone else on the internet.

Step 1: Topic Research Step 2: Keyword research Step 3: Writing Content that Ranks Step 4: Promoting Content Step 5: Increasing Ranking in the Future

Topic Research

Is this something people are searching for? If Yes -> Existing Topic If No -> New Topic

Existing Topics

  • High SEO Potential
  • High SEO Competition
  • Make sure to look at your rankings in incognito mode or it will show you searches based on your own browsing history.
  • You can rank on words with high competition.

New Topics

  • Something people aren’t searching for.
  • Lower SEO Potential
  • Low SEO Competition
  • Make up a term or word to describe what you are talking about.
  • (Examples: savable income, second degree dinners, stamena, etc.)
  • Keyword research not neccesary

Keyword Research

Step 1: Come up with addressable keywords Step 2: Assess their keyword volume Step 3: Assess the competition Step 4: Pick your keyword

Step 1: Come up with addressable keywords

Organize information in a spreadsheet. https://docs.google.com/spreadsheets/d/1XitO95OO6q3djdnOZpESaaK9xVcGKGv791mAL3IuRl0/edit?pli=1&gid=0#gid=0

List Possible keywords Subjectively rate how broad the keyword is

Step 2: Assess their keyword volume

Use Google keyword planner to add the search volume to the spreadsheet. View the recommended options and add relevant Keywords to your list.

Step 3: Assess the competition

New sites will be hard to rank for higher competition keywords. Ignore competition rating in Google keyword planner. Search for the keyword in Google Rank the competition in your spreadsheet based on the top sites that show up. Is there an article that directly addresses the question? If you see a lot of social media results that means there is a good chance it’s a low competition keyword.

Step 4: Pick your keyword

Don’t go after the hard keywords at first. Use the leveling up strategy to go for harder keywords. Set meta title tag for title in google You can level up just by changing the meta title, On adjust the content if the keyword calls for it Start with easy, more narrow, less competition keyword. Can level up to harder keywords multiple times after they are ranking

Part 3: Writing the Post

5 Principles of Great SEO

  1. Answer their question
  2. Provide the best answer
  3. Provide a complete answer
  4. Make it actionable
  5. Overdeliver

Principle 1: Answer their Question

Answer the question Make it easy to find those answers with content menu or skimmability (Headings) Have a heading with the keyword

Principle 2: Provide the best answer

What did everyone else do to answer this? Search for the keyword and view the top results. What did they do and not do well?

Principle 3: Provide a complete answer

Figure out everything somebody could be looking for when they ask the question. Good SEO content is usually long because of this. (GOal is not to be long, it’s to fully answer the question)

Principle 4: Make it actionable

Are they going to need to go back to google for more answers? Make the reader ready to go with what they just read. What’s next? How can they do it? Add steps to doing the thing.

Principle 5: Overdeliver

Give them more than they expected when they showed up. Could be a free PDF, tools, or additional info or story in the article.

Structuring your articles for SEO

Easily readable (breaks, images, etc.) Shorter paragraphs, logical structure, fun and readable No keyword stuffing (have it in your headline) Include relevant links in the article. Link to other relevant content on your site. Link to high quality sources (research article, wikipedia, etc.) Takeaways, steps, action items at the end of your article. Make it easy for them to find what to do.

Creating Your Headline

If you don’t have a good headline then nobody will click on it. What people see when they go to google. Come up with 10-30 headlines that sound clickable and excited and also the most informative. Make sure Keyword is in the Headline

Part 4: Promotion

3 Keys to Content Promotion

  • Promoting to your audience
  • Promoting to others’ audiences
  • Adding to your structure

Promoting to your audience

They want to hear from you Social media Email Groups you are part of (Forums, message boards) Automate as much as possible

Can automate with Zapier.

  • Will share to all social media profiles automatically

Promoting to Other Audiences

Used to get an initial surge to get on Google’s radar. Reddit

  • Find subreddit where your content will fit and post content there.
  • Find communities that let you just drop a link.
  • Can also make a discussion and provide info in the post and add links.
  • Can talk about a high level overview of the article.

Message boards Emailing people mentioned or who might be interested (Hey I wrote this thing, I thought you would like it, I would love to hear your thoughts on it.) Don’t ask them to share it.

Adding to your structure

Add link to past articles that it may be helpful in. Have pages that collect themes on your site. Like a map of Content Link back in future articles (reference past articles in new ones) Add useful things.

Re optimize

Identify higher value keywords that it’s starting to rank for just a little bit. Re-word the headline to fit that keyword Repeat promotion as relevant How to identify higher value keywords

  • Go to google analytics
  • Go to Acquisition > Search Console > Queries
    • Can view queries that people are landing on your page by
    • Go to search console > landing pages and select the specific article and then view queries that it’s ranking for.
    • Can see position in search results here.
  • Give article some time to settle in

Writing Off the Cuff

My favorite and by far easiest method of writing is writing off the cuff. You get your thoughts down and spring new thoughts to life. You are finding out what you know without referencing materials.

You are creating out of nothing. It is pure writing and creativity folded into one. We all have a “Muse” that will give to us whenever we ask.

All you have to do is start writing.

Writer’s block doesn’t exist.

Writer’s Block sucks. You don’t Know what to write next. You are stuck in limbo. But are you really stuck? You really can’t Think of ANYTHING to put down next?

Writer’s Block is a trick! Perhaps it’s An excuse cropping up to get you out of the zone.

Your thoughts never stop. So start there. What’s The first thing that comes to mind when you read your last sentence?

Just write that down and move on. Follow your train of thought to find out who you really are.

And to find out what you really have to say.

The first draft is always garbage.

Live it. Accept it. Once you do. It doesn’t matter what you write. Just put down whatever comes to your mind. No matter how bad it seems. You will touch up later.

Writers block doesn’t even exist. It’s Just a concept. You aren’t writing because you can’t think of anything.

It’s because you are a perfectionist. You are unwilling to put down “garbage” on a piece of paper.

Just keep going…

Don’t Stop. You have set aside this time to create. And creating is what gets your blood flowing. It’s The reason you are alive.

Distractions are going to try and stop you. They are the enemy. And this is how you win.

Stay on the course. The wind is your muse and your sail is your unrelenting determination.

The ocean wants to keep your from going anywhere. It can’t do this if you do not will it.

The conclusion doesn’t matter.

You have to end your writing. But this is not the end. It is actually a new beginning for your reader. You have given them your best.

Remind them what you said and give them a plan of what is next. You just changed a life forever. No matter how big or small of a change.

This is your impact. This is why you are here.

Philosophy

Subsections of Philosophy

Austerities

There are austerities you should avoid all together. Such as any poison to the body. (Drugs, alcohol, caffeine, etc.) 

There may be drugs or chemicals prescribed by a doctor that are life saving. Choose your doctor wisely. Some may do more harm than good.

Other austerities should be used or enjoyed. But periodically given up. Both as a test of suffering and to open up other doors.

The Journey

The journey you are on is about self discovery, growth, and redemption.

You are on the path. Do not cling to the past or in the future.

Do not rush it. Experience your surroundings. Fill every moment with greatness.

Let go.

Your pains today lead to solutions for the world forever.

`

Subsections of Recipes

Creamy Jalepeno Sauce

Creamy Jalepeno Sauce

  • 1 cup vegan mayo
  • 1 tsp onion powder
  • 1 tsp garlic powder
  • 1 tsp smoked paprika
  • 1 tsp chipotle powder
  • 2 tbps pickled jalepeno brine
  • 8 slices pickled jalepenos finely diced
  • Can add citric acid or lime juice for more zip
  • 2-4 tablespoons vegan sour cream

Blend ingredients and add to sauce bottle.

Easy Mango Salsa Quinoa Bowl

Ingredients

Tempeh Bacon

Marinade:

2 cups Liquid Amino 2 cups Water 2 tbsp Liquid Smoke 1/4 cup Maple Syrup 2 tsp Cumin 2 tsp Pepper 2 tsp Garlic Powder 2 tsp Smoked Paprika

Marinate for 1 hour and place on parchment paper on baking sheet. Bake at 400 degrees for 25 minutes Save Marinade, good for 7 days.

Vegan Tofu Quesadilla

Super firm tofu

Rough chop tofu

Marinade:

  • 2 Tbsp soy sauce
  • 2 Tbsp Nooch
  • 1 tsp chilli powder
  • 1/2 tsp garlic powder
  • 1/2 tsp onion powder
  • 1/2 tsp smoked paprika or chipotle powder
  • 1/2 tsp cumin
  • 1/2 tsp oregano
  • 1/4 tsp ground coriander
  • 1 tbsp taco bell hot sauce
  • 2 tbsp vegan mayo
  • 1 tbsp water

Mix and blend marinade ingredients Add in chopped tofu and mix let it sit for 30 minutes

Cook tofu

  • add some oil and cook on griddle

Creamy Jalepeno Sauce

Cook:

Oil pan and heat > coat the tortilla in it by smearing it around add vegan moz and cheddar shreds and the tofu and some creamy jalepeno sauce

1/2 cup cheese and 1/2 cup tofu let some cheeze sneak out

Health and Fitnesses

Subsections of Health and Fitnesses

4 Ways to Quit Caffeine

The cycle of caffeine addiction can be vicious. Just like any other drug.

The cycle goes like this:

Caffeine causes a variety of pains and withdrawal symptoms. > You use caffeine to relieve these pains and withdrawal symptoms. > Caffeine causes pains and withdrawal symptoms.

Unless you can break this pattern. You will be trapped in this cycle forever. How do you break the cycle?

Here are 4 options for breaking the cycle. Along with the benefits and drawbacks for each.

1. Cold turkey - dealing with the pains and withdrawal symptoms. (Suck it up!)

This options requires mental toughness and discipline. If you take this path. You are fed up with caffeine and are all in on quitting. You may have had an event that pushed you over the edge. You’ve had enough.

You may also realize that trying to wean off may be harder because you are feeding the addiction cycle.

You are immediately stepping out of the cycle. This is the fastest way to quit. But many relapse when the pressure is too great to continue.

2. Tapering - slowly lower your dose so that the cycle fades away without noticing. (Easy does it!)

This option lets you continue to live a normal life. If you have to function at work or at home (or both), this may be a good option. You pick a time frame. Whether it be a few days, or 6 months. Pick an option that you think you can stick with.

This option may, however, lead to “serial tapering”.

This is where you do a good job weaning for a week or a few days or whatever. But then, due to normal life circumstances, you have a stressful day, a short deadline, a bad night of sleep, or a combo of many different things. And you default to solving this problem with caffeine.

Your dose ends up being reset to where you started, or worse, higher.

3. Replacing routines - finding other ways to resolve the pain. (Now we are talking!)

In the book “Atomic Habits”, the author explains the cycle of cue, craving, routine, reward. The cue is the thing that triggers the craving, which leads to performing a routine, which is what gets you the reward. For caffeine, this could look like:

Cue = You are tired, but you need to get stuff done at work.

Craving = You start to crave caffeine.

Routine = You take caffeine.

Reward = You feel “Energy” and get your work done.

With replacement theory, you replace the routine, to get the exact same reward.

Cue = You are tired, but you need to get stuff done at work.

Craving = You crave caffeine.

Routine = You go on a run.

Reward = You feel “Energy” and get your work done.

The trick is, finding a routine to replace caffeine can be difficult. Because there are actually so many factors in the cue to begin with.

In my experience, a caffeine-cycle withdrawal cue looks more like this:

Cue = You have anxiety, are slightly down, have brain fog, you feel pressure to get work done, or chores, dealing with back pain, lack motivation, etc.

Craving = You crave caffeine.

Routine = You take caffeine.

Reward = All of the cues, which are just a myriad of withdrawal symptoms, paired with normal life stress, are temporarily resolved.

Which leads me to the best option..

4. A combination of all three (Super Saiyan!)

How can you combine cold turkey AND tapering? Well, by definition you can’t. But if you merge the two, you dramatically shorten the time frame of your taper. I believe this could give you some serious momentum. Let’s break down this combo, as well as adding routine replacement:

  1. Meet in the middle of cold turkey and tapering to do a short, two week taper.

  2. Find new replacements for all of your cues.

During your two week taper, write down a list of all of your cues. Then write 2-3 ideas on how to solve them.

Here are some examples:

Cue New Routine
Tired Jog, exercise, drink water
Bored Pursue a new hobby or skill, read, go on a walk
Feeling Down Journal, exercise, watch a inspiring video
Achy Joints Stretch, mobility work, massage
Anxiety Meditate, Journal, Talk to friends
Hungry Drink water, Fill up with fruits and veggies, exercise
Stressed Meditate, work on solving problems, support group

These may be different for you. But the point is, relentless pursuit of actually solving your problems, and living a fulfilling life. Instead of masking issues with caffeine.

I think this option is the best bang for your buck. As you are not negating the impact that withdrawal has on your life, but still dealing with any underlying problems you may face when fully caffeine free.

Notes on the half life of caffeine.

The average half life of caffeine is 5 hours. This means, if you consume 500 mg of caffeine, in 5 hours you will still have 250mg of caffeine in your system. 5 hours after that, you will have 125mg. Screw it, i’ll make a chart:

Hour Caffeine in your body (mg)
0 500
5 250
10 125
15 62.5
20 31.2
25 15.6
30 7.8
35 3.9
40 1.9

The half life of drugs can be misleading. Just because the half life is 5 hours, doesn’t mean that the drug will be clear in 10 hours. As you can see, a single dose of caffeine can technically still be in your system more than 40 hours later. And that’s just accounting for the average half life.

The high end can be up to 9.5 hours. This means, it can take more than 72 hours for caffeine to fully leave your system after a single dose.

But wait, there’s more..

Each subsequent dose adds to the amount of caffeine in your blood system. You are likely going to start some form of mild withdrawals at the 24 hour mark. And most of us have a daily caffeine habit. This means at 24 hours, if you take another 500mg of caffeine, your new starting point is 515mg.

If you take caffeine daily, you ALWAYS have caffeine in your system.

I don’t want to do anymore math, but as you can see, your caffeine levels will drop more rapidly the higher the dose. So your tapering, in theory, could get faster without feeling the same withdrawals from lowering a higher dose.

Keep that in mind.

7 Steps to Get Back on a NoFap Streak Immediately

  1. Reconnect with your reason why. Is there a book or YouTube video that explained the benefits. What motivated you to start in the first place? Write down the negatives associated with porn and masturbation. And the benefits you have felt from previous attempts.

  2. Set a goal related to nofap. A 90 day timeline is far enough to make real progress. But not so far out that your timeline is unpredictable.

  3. Set up process controls. This is what you do to keep your goal from breaking down in a lapse of willpower. This includes a weekly plan, daily habits, and peer support. Make sure you track your plan and habits.. And discuss setbacks in a weekly meeting with peers.

  4. Use your time with purpose. Say no to anything that goes against your goals. Align your time and energy with things you enjoy doing. And other goals that you have or skills that you want to practice.

  5. Schedule time for important tasks. Schedule time to reconnect with your why, every day. And time to work on your plan and daily habits. Create an “Ideal Week” calendar. To live every moment with intention. See

Ali Abdaal‘s video: https://youtube.com/watch?v=6o2tm00Ar8A&t=407s

  1. Take Ownership You are the only one who can take control of your results. Regardless of circumstances. Surround yourself with people who own their lives. Take up a Growth mindset: https://amazon.com/Mindset-Psychology-Carol-S-Dweck/dp/0345472322/ref=sr_1_1?sr=8-1

  2. Take your commitments seriously. How you do one thing is how you do everything. People will notice. And most importantly, you will notice. This creates a flywheel for success and will spill over to all areas of your life.

Caffeine is Destroying You

Look at this bird.

https://www.youtube.com/watch?v=HUngLgGRJpo

Any substance that gives you a lift follows the same journey as the bird in the video. You start out at a healthy balance. But before you know it. You are trapped in an addictive cycle.

DISCLAIMER: YOU MAY NOT FEEL ANY NEGATIVES OF CAFFEINE UNTIL YEARS OF USE!!

Or.. you may not associate the negatives that are currently happening with caffeine. This is because there is a disconnect with the immediate response to caffeine and the negatives it brings.

Here’s how it goes:

  1. You take caffeine through your medium of choice. (Some even go for the suppository… Coffee ENEMAS anyone?)

  2. You think, “Caffeine is great”. Look at all your new “energy, adrenaline rush, tomato!”.

  3. You wake up the next morning. Dreary and weary. Can’t get out of bed. Let’s get some of that caffeine to make you feel better.

And the cycle repeats. You associate your dreary wearies with getting old. Your lack of sleep is because you just suck at sleeping. Your fits of irritability are just your personality.

Your joint pain is your poor posture, not the fact that you no longer have the energy to maintain a good posture, because caffeine is sucking the life out of you.

Take a look at this advertisement from 1924 mentioned in Eugene M. Schwartz’s famous book “Breakthrough Advertising”:

WHY MEN CRACK.. .

An authority of international standing recently wrote;

“You have overeaten and plugged your organs with moderate stimulants, the worst of which are not only alcohol and tobacco, but caffeine and sugar . . . “

You know them. Strong men. Vigorous men, robust men — men who have never had a sick day in their lives.

They drive. They drive themselves to the limit. They lash themselves over the limit with stimulants. They crack. Often, they crash.

You have seen them afterwards. Pitiful shells. The zest gone, the fire gone. Burnt-out furnaces of energy.

“He was such a healthy-looking man “

He was. His health was his undoing. His constitution absorbed punishment. Otherwise he might have been warned in time.

“For every action there is an equal and contrary reaction.” You learned the law in physics. It applies to bodies.

For every ounce of energy gained by stimulation, by whipping the nerves to action, an ounce of reserve strength is drained . . .
But repeated withdrawals exhaust any reserve.

Physical bankruptcy. Then the crash . . .

It’s time to get back to normal, to close the drafts, to bank some of the fires…

Avoid stimulants. What is good for the boy is good for the man . . .

Borrowed Energy Must Be Repaid!

Two million American families avoid caffeine by drinking Postum.

And two million American families are better

off for it. . .

People knew this was a problem 100 years ago. Yet, we are all still addicted.

Caffeine is the #1 ignored factor when it comes to health.

Here is the “advice” we see over and over again in regards to taking control of your physical health:

  • Cut carbs.
  • Cut out blue light.
  • Don’t eat past 6.
  • Don’t eat uncooked spinach.
  • Eat only meat.
  • Stop eating unsoaked almonds.
  • Take this supplement.

80% of Americans consume some form of caffeine daily. I’ve seen mothers give their toddlers Mountain dew! Almonds are the problem? What world are we living in?

We are so obsessed with minor details that we miss the obvious. Seriously, anyone who is recommending putting butter in your coffee for optimal health has no clue what optimal health is.

People are clueless about caffeine. Why?

Because it’s “Normal”.

It’s a problem that is hard to see before it’s too late.

“But caffeine is not a problem for me.”

Any amount of stimulants in your body is a problem. It’s effecting you today. If you want to feel breadth of emotions again, have unlimited energy throughout the day, have healthy joints, be able to recover fully from exercise, have the most creative thoughts you can possibly have…

You need to quit caffeine. Plain and simple. You are not living the life you are fully capable of.

Studies showing caffeine is “Healthy”.

Really think about it. Would you believe studies about cocaine funded by cocaine dealers or done my cocaine addicts that think cocaine gives them a positive lift?

There is a billion dollar industry that thrives off of you believing this nonsense. And the mildness of the drug and normalization make many people never second guess it.

The science is not as bleeding edge as we think. Especially when it comes to nutrition. Caffeine is not a vitamin. We need to start relying a little bit more on human intuition then studies funded by big caffeine and drug addicts.

Is caffeine stopping us from living the lives we truly want?

Here’s the #1 post on Reddit regarding caffeine:

It’s Not Withdrawal. Your Career Just Sucks

I’m a software developer, about a year and a half caffeine-free. Immediately after quitting, my productivity at work plummeted. It hasn’t returned to pre-caffeine levels since.

I have realized that this is not due to withdrawal, but rather because I cannot, as a human being, sit in front of a screen all day, toiling away at meaningless work for a soulless corporation. Caffeine played a pivotal role in hiding this reality. With caffeine, I can slog through all manner of tedium and even have fun. Without it, I feel a strong attraction to a “stop and smell the roses” mode of living. I go on long walks, look at trees, write poetry, and I don’t get jack shit done at work.

I can breathe. My sleep is perfect. My digestion is perfect. My livelihood, however, is in jeopardy. I just wanted to put this out there, in case anyone has quit caffeine but is struggling with productivity or lack of motivation: It’s not withdrawal. You’re a spiritual creature in a cold, mechanical system, and now there’s no hiding.

There is something deeper going on here. Is caffeine used as a form of control? I mean, the Nazi’s gave prisoners soup, bread, and coffee for a reason right?

Caffeine is a worker bee drug. It makes you a slave and complacent. It numbs your prefrontal cortex just like any other drug.

This screws with your ability to delay gratification and makes you seek out more short term rewards to numb the pain.

I go over the pain-pleasure balance in my Dopamine Nation summary. So I won’t re-hash it here.

But the pain-pleasure balance is important to understand. Once you do. You will realize that putting anything in your body that is not food or water is making you miserable.

Caffeine is a gateway drug.

Imagine this..

You are anxious, on edge, irritable, depressed, have trouble sleeping. You think this is just you. You reach for alcohol or weed or Kratom or whatever to take the edge off. You were only in that state because of caffeine.

This scenario may not have happened to you yet. But I guarantee it has happened to millions of people who have turned towards drugs to numb the pain.

Caffeine kills people, tips people with deadly heart disease over the edge, plays a factor in road rage car accidents, causes vitamin and mineral deficiencies, cardiac arrhythmia, perpetuates drug addiction, and much more.

It’s poison.

When are we going to wake up?