Updated content in old posts.

This commit is contained in:
Hamza Ahmed
2024-01-05 23:54:51 +00:00
parent c916352195
commit cf68a1d2cc
10 changed files with 745 additions and 639 deletions
+197 -192
View File
@@ -5,7 +5,7 @@ author: "ahmza"
draft: false draft: false
weight: weight:
tags: ["Homelab","Docker","Docker Swarm","Raspberry Pi","Pi4"] tags: ["Homelab", "Docker", "Docker Swarm", "Raspberry Pi", "Pi4"]
description: "Pis are very capable computers, when banded together they're almost unstoppable" description: "Pis are very capable computers, when banded together they're almost unstoppable"
canonicalURL: "https://blog.ahmza.com/Page%28/posts/building-a-docker-swarm-with-pis.md%29" canonicalURL: "https://blog.ahmza.com/Page%28/posts/building-a-docker-swarm-with-pis.md%29"
@@ -18,214 +18,203 @@ showtoc: true
searchHidden: false searchHidden: false
--- ---
> This post is no longer valid as the cluster runs Kubernetes. The build process
> is the same
## **Intro** ## **Intro**
The _Raspberry Pi_ from it's first iteration has been a great hit.
Adopted by many as the computer of choice for projects, and for
very good reason. The Pi is a fully fledged computer that fits in
your pocket and the most recent edition has blown fans away with
the flagship model boasting an ARM64 CPU and 8GB of RAM.
Now one _Raspberry Pi 4 8GB_ is more than powerful enough for most The _Raspberry Pi_ from it's first iteration has been a great hit. Adopted by
workloads and in some cases totally unnecessary, **so you may even most as the computer of choice for projects. The Pi is a fully fledged computer
get away with a single 4GB model**. However taking into consideration that fits in your pocket and the most recent edition boasts an ARM64 CPU and 8GB
their relatively low price and power consumption why not go all out of RAM.
and build a cluster.
> **You can never have too many _Raspberry Pis_, just Now one _Raspberry Pi 4 8GB_ is more than powerful enough for most workloads,
not enough Ideas** **so you may even get away with a single 4GB model**. Taking into consideration
their low price and power consumption why not go all out and build a cluster.
My excuse to build a Pi cluster is, I would like to migrate the My excuse to build a Pi cluster: I would like to migrate the services running on
services currently running on a **bare metal server that sucks a **bare metal server that sucks a lot of power to a low power solution.**
a lot of power to a low power solution.** What better way to do that
than a Pi cluster.
### **My Setup** ### **My Setup**
* 4 x _Raspberry Pi 4 8GB_
* 4 x 32GB SD cards
* 4 x PoE hats
* 1 x 5 port PoE Switch
![Cluster](/img/pi-docker-swarm/cluster.webp) - 4 x _Raspberry Pi 4 8GB_
- 4 x 32GB SD cards
- 4 x PoE hats
- 1 x 5 port PoE Switch
![Cluster(fix this image)](/img/pi-docker-swarm/cluster.webp)
### **Point of this post** ### **Point of this post**
Hopefully after following this post you will have setup _Docker
swarm_ on a cluster of Pis **- stay even if you currently only have
one -** and understand how to bend it to your will 🦾.
### **Why** ***Docker Swarm*** 🧐 After following this post you will have setup _Docker swarm_ on a cluster of Pis
**- stay even if you have one -** and understand how to bend it
to your will 🦾.
### **Why** **_Docker Swarm_** 🧐
While we can manage each docker node - _Raspberry Pi_ - individually While we can manage each docker node - _Raspberry Pi_ - individually
, **_Docker swarm_ enables us to manage all the devices from a single , **_Docker swarm_ enables us to manage all the devices from a single
main node** making managing the cluster a lot easier. main node** making managing the cluster a lot easier.
Think of _Docker swarm_ as a set of 🤖 hands which will run tasks on Think of _Docker swarm_ as a set of 🤖 hands which will run tasks on
each individual node for us. These tasks can consist of: each individual node for us. Some of these tasks are:
* Cluster Management
* Deployment and Scaling across the cluster
* Multi-host networking
* load balancing
* etc...
### **Well why not** ***Kubernetes*** - Cluster Management
Although _Kubernetes_ is awesome, **it adds a bunch of complexity that - Deployment and Scaling across the cluster
is simply not needed in a home lab environment** where we only have - Multi-host networking
a small cluster. As well as that, from my experience creating - load balancing
```docker-compose``` files is a lot easier than writing manifests.
**_Docker swarm_ can do everything I want it to and requires less ### **Well why not** **_Kubernetes_**
effort** which is great if you're like me 🥱 😂
Although _Kubernetes_ is awesome, it adds a bunch of complexity I'm not ready
for. As well as that, from my experience creating _docker-compose_ files is a
lot easier than writing manifests. **In the future I will try _Kubernetes_**
### **Required Stuff** ### **Required Stuff**
> The links below are reccomendations/stuff I used > The links below are reccomendations/stuff I used
* [_Raspberry Pi_ 4B](https://thepihut.com/products/raspberry-pi-4-model-b?variant=31994565689406) (Reccomend 4-8 @ 8GB)
* [_Raspberry Pi_ PoE Hats](https://thepihut.com/products/power-over-ethernet-poe-hat-d-for-raspberry-pi) (If you can find the [PoE+](https://thepihut.com/products/raspberry-pi-poe-plus-hat) version get them)
* [Cluster Case](https://thepihut.com/products/cluster-case-for-raspberry-pi) (Get any case you want)
* [PoE switch](https://www.amazon.co.uk/gp/product/B076982FVC/) (Get one that has enough ports for the nuber of pis you want)
* [RJ45 Ethernet Cable](https://www.amazon.co.uk/gp/product/B00C4U030G) (Reccomend short cables as it will look neater)
* [Micro SD cards](https://www.amazon.co.uk/gp/product/B08J4HJ98L) (Get enough cards for the number of Pis, Get the biggest cards you can afford)
**This is without a doubt an expensive project**, however in my eyes - [_Raspberry Pi_ 4B](https://thepihut.com/products/raspberry-pi-4-model-b?variant=31994565689406) (Reccomend 4-8 @ 8GB) (Or newer)
it's the cost of another server 😂 and the best part about this - [_Raspberry Pi_ PoE Hats](https://thepihut.com/products/power-over-ethernet-poe-hat-d-for-raspberry-pi) ([PoE+](https://thepihut.com/products/raspberry-pi-poe-plus-hat)) (Check compatibility with Pi Version)
project is **you can add to the cluster over time** spreding the cost - [Cluster Case](https://thepihut.com/products/cluster-case-for-raspberry-pi) (Get any case you want)
which is how I managed to purchase all the hardware. A suggestion - [PoE switch](https://www.amazon.co.uk/dp/B0769C24T1/) (get one with enough 1Gb ports for the number of pis you want)
would be to **buy equipment that allows you room to grow** so an 8 port - [RJ45 Ethernet Cable](https://www.amazon.co.uk/gp/product/B00C4U030G) (Recommend short cables as it will look neater)
PoE switch instead of a 4 port if you know you will scale to 8 - [Micro SD cards](https://www.amazon.co.uk/gp/product/B08J4HJ98L) (Get enough cards for the number of Pis, Get the biggest cards you can afford)
nodes
If you build this then you can safely say another server is not **This is an expensive project**, but the best part is **you can add to the
needed. This cluster should be more than capable to serve all your cluster over time** spreading the cost, which is how I managed to buy all the
home needs even if you only have 2 nodes. Put it this way, if you hardware. If I could start again though I would **buy equipment that allows room
have 4 8GB nodes then you have a combined total of: to grow** so an 8 port PoE switch instead of a 4 port if you know you will scale
* 32GB of RAM to 8 nodes
* 16 physical CPU cores @ 1.5GHz
This cluster should be capable of serving most of your needs even with 2 nodes.
Put it this way, if you have 4 x 8GB nodes then you have a combined total of:
- 32GB of RAM
- 16 physical CPU cores @ 1.5GHz (You can OverClock !!)
#### **Money Saving Tips** #### **Money Saving Tips**
* Just get 1-2 nodes to start
* cut PoE and use normal power cables - 1-2 nodes to start
* Use Raspberry Pis with less memmory eg 4GB - Drop PoE and use normal power cables
* Grab a really cheap case or make one using [these](https://www.amazon.co.uk/dp/B091KJNZLB/) - Raspberry Pis with less memory i.e 4GB
* Use smaller SD Cards try not to go below 32GB (Reccomended 64GB If money saved elsewhere) - Cheaper case or make one using [these](https://www.amazon.co.uk/dp/B091KJNZLB/)
- Smaller SD Cards try not to go below 32GB (Recommended 64GB If money saved elsewhere)
## **BUILD TIME !!** ## **BUILD TIME !!**
Pull yourself up by your bootstraps were jumping into this one
runnig 💨
### **Image the SD Cards** ### **Image the SD Cards**
So interesting fact the CPUs used in the raspberry pi 4 use an ARM64
archetecture. When looking for images of Raspbian you will only find
32bit variants which will work however will not make use of all the
hardware which is just a waste. 64bit images exist however are well
hidden, Dont fear 😨 **you can download the latest images from the
[raspberrypi.org index](https://downloads.raspberrypi.org/raspios_arm64/images/)**
To write the cards I use the [**Raspberry Pi imager**](https://www.raspberrypi.com/software/). The CPU in a RaspberryPi 4 is the ARM64 architecture. When selecting Raspbian
once you have **rpi-imager** installed and you have the 64bit raspbian pick the 64-BIT option. 32bit variants will work but not make use of the hardware
image, open ```sudo rpi-imager``` and on the "CHOOSE OS" section go to capabilities.[RaspberryPi Imager](https://www.raspberrypi.com/software/)
the bottom and select use custom image.
> We dont need to unzip the file as the tool is clever enough to when prompted with **"Use OS Customisation"** go with **"Edit Settings"**.
handle that for us General:
**Before removing the SD card, mount the boot partition - usually the - Set the hostname
first partition, look for a file called cmdline.txt - and create an - Set a username and password
empty file called ssh** ```sudo touch ssh``` this basically enables - Set Locale settings
SSH on the Pis first boot allowing us to access the Pis in a totally Services:
headless manner. - Enable SSH
- Allow public-key authentication only
- Set your SSH Key
> If you dont have an SSH key, read my post on SSH [Securing
> SSH](https://blog.ahmza.com/posts/securing-ssh/)
### Assemble the cluster ### Assemble the cluster
So assembly is very dependant on the kit you bought, and more
often than not the stuff needed here comes with instructions or is
self explanitory. So go ahead and assemble the cluster 🛠
**There is an order of operations that I reccomend:** Assembly depends on the case you bought, instructions should be included. Go
* Install PoE hats onto the Pis ahead and piece together the cluster 🛠
* Install the SD Cards into the Pis
* Assemble the case and install Pis
* plug in ethernet cables
**Now allow the Pis to boot for a few minutes so it can resize the **There is an order of operations that I recommend:**
- Install PoE hats onto the Pis
- Install the SD Cards into the Pis
- Assemble the case and install Pis
- plug ethernet cables in
**Now allow the Pis to boot for a few minutes**
### **Sort out the Network bits** ### **Sort out the Network bits**
This is the easy part, there are two methods you can use to set a
static IP address, one is on your DHCP server and the other is on
the device itself. Personally I prefer to set static IPs on the
device itself so I will cover that here.
To find the current ip of your Pis you can go to your DHCP server There are two methods you can use to set a static IP address, one is on your
and look for the DHCP leases for the Pis. DHCP server and the other is on the device itself. Personally I prefer to set
static IPs on the device itself so I will cover that here.
To find the current ip of your Pis you can go to your DHCP server and look for
the DHCP leases for the Pis.
> there are naming conventions for naming primary and secondary > there are naming conventions for naming primary and secondary
things but this is your cluster so be creative with it, I have my > things but this is your cluster so be creative with it, I have my
primary node named ```Goob``` and the secondary nodes named ```Doris1``` > primary node named `Goob` and the secondary nodes named `Doris1` > `Doris2` and `Doris3` > [reference](https://www.youtube.com/watch?v=oFb7FVe8sdQ)
```Doris2``` and ```Doris3```
[reference](https://www.youtube.com/watch?v=oFb7FVe8sdQ)
**SSH to the Pi** then open and edit the following files **SSH to the Pi** then open and edit the following files
* /etc/hosts
* edit this line with your hostname: ```127.0.1.1 goob``` - /etc/dhcpcd.conf
* /etc/hostname \_ knowing we will be using only static IPs here I delete
* edit this file with your hostname: ```goob```
* /etc/dhcpcd.conf
* knowing we will be using only static IPs here I delete
everything in the file add the following everything in the file add the following
* ```
interface eth0
static ip_address=10.10.10.20/24
static routers=10.10.10.1
static domain_name_servers=10.10.10.1
```
**Now reboot the pi** ```sudo shutdown -r now```
**Once the Pis are back up log into each one and change the default ```
passwords** you may also want to create a new user for yourself but interface eth0
thats totally optional. static ip_address=<your-Pi-ip>/24
static routers=<your-router-ip>
static domain_name_servers=<your-dns-ip-usually-same-as-router>
```
**Now reboot the pi**
### **Provision with** ***Ansible*** ```bash
you want to **create an _Ansible_ control node** and that is as simple as sudo shutdown -r now
installing a package onto your machine. _Ansible_ is built using python ```
which makes it easy to install as **we can use the python pip package
manger.** To check you have it installed do ```pip --version``` if
it's not installed do the following
### **Provision with** **_Ansible_**
```curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py``` Ansible will allow us to setup our RaspberryPi Cluster from a remote machine
where we only administer the commands once and Ansible will replicate across the
cluster.
```python get-pip.py --user``` > Make sure pipx is installed. [Install
> Instructions](https://pipx.pypa.io/stable/)
**once you have pip installed proceed to installing _Ansible_** Install Ansible
[Install Docs](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#installing-and-upgrading-ansible-with-pipx)
[Docs](https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html) ```bash
pipx install --include-deps ansible
```
```pip install ansible``` A playbook defines steps _Ansible_ needs to take on the remote machine to
provision it. Playbooks are written in yaml so get ready to make sure your
Now that _Ansible_ is installed we can create a runbok that defines the indents are correct 😬
steps _Ansible_ needs to take on the remote machine to correctly
provision it. This playbook is written in yaml so get ready to make
sure your indents are correct 😬
**Creating the playbook** **Creating the playbook**
now you can copy what I have and it should work - after changing a Copy what I have and it should work -- after changing a thing or two -- I
thing or two - which is fine however I encourage you to copy what I encourage you to read the Ansible
have, read the [Docs](https://docs.ansible.com/ansible/latest/user_guide/index.html) [Docs](https://docs.ansible.com/ansible/latest/user_guide/index.html) and make
and make any changes you feel are necessary. any changes you feel are necessary.
> Check the [git repo](https://gitlab.com/AHMZA/pi-docker-swarm-ansible-deploy/-/tree/main) for the most up to date yaml file im using. > Check this [Gitlab Repo](https://gitlab.com/ahmza/ansible-playbooks/-/tree/main/docker-swarm?ref_type=heads) for the most up to date playbook.
**This script assumes you are using SSH keys, which you should but if **This script assumes you are using SSH keys, which you should but if
not you can skip the whole "Configure SSH" block,** not you can skip the whole "Configure SSH" block,**
***I RECCOMEND YOU USE SSH KEYS*** - [read this](https://blog.ahmza.com/posts/securing-ssh/) **_I RECCOMEND YOU USE SSH KEYS_** - [read this](https://blog.ahmza.com/posts/securing-ssh/)
**Create the deploy.yml** **Create the deploy.yml**
```bash
# Open the yaml file in a text editor
vim deploy.yml
```
```yaml ```yaml
--- ---
- hosts: piCluster - hosts: piCluster
become: yes become: yes
tasks: tasks:
- name: Configure SSH - name: Configure SSH
block: block:
- name: Auth local SSH Keys - name: Auth local SSH Keys
ansible.posix.authorized_key: ansible.posix.authorized_key:
user: <pi_user> user: <pi_user>
@@ -239,7 +228,7 @@ not you can skip the whole "Configure SSH" block,**
copy: copy:
src: ./pi_rsa src: ./pi_rsa
dest: /home/<pi_user>/.ssh/id_rsa dest: /home/<pi_user>/.ssh/id_rsa
mode: '0600' mode: "0600"
owner: <pi_user> owner: <pi_user>
group: <pi_user> group: <pi_user>
@@ -247,11 +236,10 @@ not you can skip the whole "Configure SSH" block,**
copy: copy:
src: ./pi_rsa.pub src: ./pi_rsa.pub
dest: /home/<pi_user>/.ssh/id_rsa.pub dest: /home/<pi_user>/.ssh/id_rsa.pub
mode: '0644' mode: "0644"
owner: <pi_user> owner: <pi_user>
group: <pi_user> group: <pi_user>
- name: Check for any updates and install them - name: Check for any updates and install them
apt: apt:
update_cache: true update_cache: true
@@ -266,14 +254,12 @@ not you can skip the whole "Configure SSH" block,**
- vim - vim
- curl - curl
- name: Check Docker is installed - name: Check Docker is installed
shell: "docker --version" shell: "docker --version"
register: docker_version register: docker_version
- name: Install Docker - name: Install Docker
block: block:
- name: Download Docker script - name: Download Docker script
command: curl -fsSL https://get.docker.com -o get-docker.sh command: curl -fsSL https://get.docker.com -o get-docker.sh
@@ -297,7 +283,6 @@ not you can skip the whole "Configure SSH" block,**
when: docker_version.stdout.find('Docker version') when: docker_version.stdout.find('Docker version')
- name: check Docker compose is installed - name: check Docker compose is installed
shell: "docker-compose --version" shell: "docker-compose --version"
register: dc_version register: dc_version
@@ -306,7 +291,6 @@ not you can skip the whole "Configure SSH" block,**
command: sudo pip3 -v install docker-compose command: sudo pip3 -v install docker-compose
when: dc_version.stdout.find('docker-compose version') when: dc_version.stdout.find('docker-compose version')
- name: wait for network on boot - name: wait for network on boot
command: raspi-config nonint do_boot_wait 0 command: raspi-config nonint do_boot_wait 0
@@ -315,49 +299,57 @@ not you can skip the whole "Configure SSH" block,**
``` ```
The steps this playbook takes are as follows: The steps this playbook takes are as follows:
1. Copy your SSH keys to the pi authorized_keys 1. Copy your SSH keys to the pi authorized_keys
2. Copy same Pi ssh key between the Pis for intercommunication 2. Copy same Pi ssh key between the Pis for intercommunication
3. Check for and Install updates 3. Check for and Install updates
4. Install any build dependancies 4. Install any build dependencies
5. Check if Docker is Installed 5. Check if Docker is Installed
* Download the Docker Script - Download the Docker Script
* Install Docker from script - Install Docker from script
* Enable the Docker service - Enable the Docker service
* Add user to Docker group - Add user to Docker group
6. Check if docker-compose is installed 6. Check if docker-compose is installed
* Install docker-compose (This will take a while on each pi so be patient, grab a coffee) - Install docker-compose (This will take a while on each pi so be patient, grab a coffee)
9. Change raspi config to wait for network before boot 7. Change raspi config to wait for network before boot
10. Reboot 8. Reboot
take some time to read through the playbook, read the docs and try to take some time to read through the playbook, read the docs and try to
understand whats going on. Change the usernames to your username. understand whats going on. Change the usernames to your username.
**Make the hosts file in the same directory as the deploy.yml** **Create an inventory hosts file in the same directory as the deploy.yml**
``` yaml
[piCluster] ```bash
10.10.10.20 # Open file in a text editor
10.10.10.21 vim hosts
10.10.10.22
``` ```
* `[piCluster]` - specifies a group of hosts
* `10.10.10.xx` - specifies the Pis IP ```yaml
[piCluster]
<ip address 1>
<ip address 2>
<ip address 3>
```
- **_[piCluster]_** - specifies a group of hosts
- **_<ip address>_** - change these to the Pis IP addresses
**create the Pi Intercommunication keys** **create the Pi Intercommunication keys**
``` bash
```bash
ssh-keygen ssh-keygen
# Please note the ".pi_rsa" here
Enter file in which to save the key (/home/ahmza/.ssh/id_rsa): .pi_rsa Enter file in which to save the key (/home/ahmza/.ssh/id_rsa): .pi_rsa
``` ```
* save the keys in the same directory the deploy.yml file is
**heres the command to run the playbook.** **heres the command to run the playbook.**
`ansible-playbook -i hosts -kK deploy.yml -c paramiko` **_ansible-playbook -i hosts -kK deploy.yml_**
* `ansible-playbook` - the command to run the playbook - _ansible-playbook_ - the command to run the playbook
* `-i hosts` - specifies the host/inventory file - _-i hosts_ - specifies the host/inventory file
* `-kK` - asks you for password for the SSH connection(-k) and the sudo password(-K) - _-kK_ - asks you for password for the SSH connection(-k) and the sudo password(-K)
* `deploy.yml` - the _Ansible_ playbook - _deploy.yml_ - the _Ansible_ playbook
* `-c paramiko` - Use the paramiko connection method, I found this works best with ssh keys
You can do so much with _Ansible_, for example mount network shares etc, You can do so much with _Ansible_, for example mount network shares etc,
if you can do it in the cli you can do it in _Ansible_ !! if you can do it in the cli you can do it in _Ansible_ !!
@@ -366,35 +358,35 @@ Now that the _Ansible_ script is done we can go ahead and actually
configure all the Pis into the cluster. configure all the Pis into the cluster.
### **Creating/Joining the swarm** ### **Creating/Joining the swarm**
Creating and joining the cluster is easy - It is manual and tedious so
this is something you could impliment into the ansible playbook using Creating and joining the cluster is easy - It is manual and tedious so this is
multiple host groups. something you could implement into the _Ansible_ playbook using host groups.
**Follow these steps to create the swarm:** **Follow these steps to create the swarm:**
1. ssh to the main Pi, this will be the manager node. 1. ssh to the main Pi, this will be the manager node.
2. run `docker swarm init` 2. run `docker swarm init`
* This will return a command and token. Make sure to copy them - This will return a command and token. Make sure to copy them
3. exit the main Pi 3. exit the main Pi
4. ssh to one of the worker nodes 4. ssh to one of the worker nodes
5. paste and run the copied command 5. paste and run the copied command
6. do the same on the remaining worker nodes 6. do the same on the remaining worker nodes
You should now have a correctly configured cluster !! You should now have a configured cluster !!
### **Optional Step - Portainer** ### **Optional Step - _Portainer_**
Portainer is a webgui that will allow us to manage the cluster, it will
_Portainer_ is a webgui that will allow us to manage the cluster, it will
make deploying and destroying containers across the cluster a breeze. make deploying and destroying containers across the cluster a breeze.
I do understand that all of what portainer does can simply be accomplished
in the command line, however portainer just makes it less hastle to manage.
**Install Portainer** **Install _Portainer_**
Firstly we want to download the yaml file that will be used to deploy Firstly we want to download the yaml file that will be used to deploy
the portainer contiainer on our cluster. the _Portainer_ container on our cluster.
`curl -L https://downloads.portainer.io/portainer-agent-stack.yml -o portainer-agent-stack.yml` `curl -L https://downloads.portainer.io/portainer-agent-stack.yml -o portainer-agent-stack.yml`
Now we can actually deploy portainer to the cluster using the following Now we can actually deploy _Portainer_ to the cluster using the following
command: command:
`docker stack deploy -c portainer-agent-stack.yml portainer` `docker stack deploy -c portainer-agent-stack.yml portainer`
@@ -412,10 +404,10 @@ to create a private repository to host any images that you need to run
across the cluster. across the cluster.
to create this private repository create a file called docker-compose.yml to create this private repository create a file called docker-compose.yml
in a folder called repository or whatever and enter the following. in a folder new folder called repository and enter the following.
``` yaml
version: '3.9' ```yaml
version: "3.9"
services: services:
registry: registry:
image: registry:2 image: registry:2
@@ -428,26 +420,39 @@ services:
**Be sure to change pi-user to your pi user** **Be sure to change pi-user to your pi user**
**create a file /etc/docker/daemon.json and eter the following** **create a file /etc/docker/daemon.json and eter the following**
``` json
```bash
vim /etc/docker/daemon.json
```
```json
{ {
"insecure-registries": ["localhost:5000", "<pi-address>:5000"] "insecure-registries": ["localhost:5000", "<pi-address>:5000"]
} }
``` ```
where `pi-address` is the ip address of the main swarm node.
**restart the docker service with `sudo systemctl restart docker`** where **_pi-address_** is the ip address of the main swarm node.
\*\*restart the docker service
```bash
sudo systemctl restart docker
```
now we need to deploy the registry to the stack like we did with portainer now we need to deploy the registry to the stack like we did with portainer
`docker stack deploy -c docker-compose.yml registry` ```bash
docker stack deploy -c docker-compose.yml registry
```
and we should have a private registry setup that we can use to push our and we should have a private registry setup that we can use to push our
custom docker images to. custom docker images to.
## **Conclusion** ## **Conclusion**
Well done, you have successfully setup a docker swarm cluster on a bunch Well done, you have successfully setup a docker swarm cluster on a bunch
of Pis and along the way you managed to learn a bit about SSH, Ansible, of Pis and along the way you managed to learn a bit about SSH, Ansible,
docker-compose, yaml and networking on Pis. The next step would be to docker-compose, yaml and networking on Pis. The next step would be to
setup a few containers but I'll leave that to you, dont be affraid to setup a few containers but I'll leave that to you, dont be affraid to
play around and even ruin the cluster, you can always rebuild it so have play around and even ruin the cluster, you can always rebuild it have
fun 😊 fun 😊
+45 -66
View File
@@ -5,54 +5,46 @@ author: "ahmza"
draft: false draft: false
weight: weight:
tags: ["blog","website","web development","HUGO"] tags: ["blog", "website", "web development", "HUGO"]
description: "HUGO is a static site generator. No idea what that is ? Check out this post to learn more !" description: "HUGO is a static site generator. No idea what that is ? Check out this post to learn more !"
canonicalURL: "https://blog.ahmza.com/Page%28/posts/hugo-static-site-generator.md%29" canonicalURL: "https://blog.ahmza.com/Page%28/posts/hugo-static-site-generator.md%29"
cover: cover:
image: "/img/hugo/feature.webp" # image path/url image: "/img/hugo/feature.webp" # image path/url
alt: "HUGO logo" # alt text alt: "*HUGO* logo" # alt text
caption: "The HUGO logo" # display caption under cover caption: "The *HUGO* logo" # display caption under cover
relative: false # when using page bundles set this to true relative: false # when using page bundles set this to true
--- ---
## **Introduction** ## **Introduction**
Hugo is a static site generator, which basically means it's a tool that _HUGO_ is a static site generator, which basically means it's a tool that
allows us to pre-compile all of our website into static HTML, CSS and allows us to pre-compile all of our website into static HTML, CSS and
JS. The main benefit of using such methods to crate a site is speed. A JS. The main benefit of using such methods to crate a static site is speed. A
Static site takes a lot less time to load than a site that uses Static site takes a lot less time to load than a site that uses
databases for example. databases for example.
## **Disadvantages** ## **Disadvantages**
Some of the disadvantages I have come across are as follows: Some of the disadvantages (for me):
* A lot more backend work - A lot more infrastructure setup (for my setup)
* Harder to manage content - Editing and creating content can be a pain
* Editing and creating content can be a pain
**This is to no fault of hugo itself but to the unnecessary complexity **This is to no fault of _HUGO_ itself but the complexity of my infrastructure!!**
in my infrastructure!!** Deploying the site in my environment was a Deploying the site in my environment was a challenge as I had to get the site
challenge as I had to get the site files from gitlab and build a docker files from gitlab and build a docker image that would compile the site as well
image that would compile the site as well as create an image to be as create an image to be deployed in my [docker
deployed in my [docker swarm.](https://blog.ahmza.com/posts/building-a-docker-swarm-with-pis) swarm.](https://blog.ahmza.com/posts/building-a-docker-swarm-with-pis) I do feel
I do feel I made this more complicated than it needed to be, however now I made this more complicated than it needed to be, but now that I have it
that I have it working the workflow is great. working the workflow is great.
The content is manually managed meaning you have to create edit and Because there is no integrated webui or CMS for _HUGO_, the experience
delete posts yourself. HUGO does a great job at making this as pleasant
of an experience as possible but coming from a CMS (Content Management
System) it is a lot more involved.
Because there is no integrated webui or CMS for Hugo, the experience
you get when creating content will vary person to person depending on you get when creating content will vary person to person depending on
the environment you use to create the content. When using a CMS I took the environment you use to create the content. When using a CMS I took
dragging and dropping images for granted where now I have to explicitly dragging and dropping images for granted where now I have to explicitly
define full paths to images which can get me out of the flow of writing define full paths to images which can get me out of the flow of writing
content, however it's finding solutions for these challenges that makes content. Finding solutions for these challenges that makes this interesting.
this interesting.
## **Then Why?** ## **Then Why?**
@@ -62,47 +54,34 @@ total size of the content on this site including images is ~5mb which
is considerably smaller than a full CMS and database alone with no is considerably smaller than a full CMS and database alone with no
content. content.
Some advantages of static sites in general:
* Security
* Reliability
* Scalability
* Low Resource Requirement
Although the pursuit of speed brought me to HUGO, here are a few things
that kept me:
* Git
* Markdown
* Simplicity
* Live Preview
As mentioned before my initial reason for switching to a static site
generator was speed and how lightweight the final product is, at the
time of writing this the total size of the content on this site
including images is ~5mb which is considerably smaller than a full CMS
and database alone with no content.
I have recently started to use git a lot more and I'm able to
implement a content versioning system that can follow me everywhere and
on any device very easily. It also means there is always a backup of my
site on gitlab and I don't need to worry about backing up databases.
Markdown makes life a lot easier, Its quick, easy and doesn't require
me to right click or use buttons. Markdown is also very transferable,
scroll up to the top of this page and hit the "Suggest Changes" button
and you will see how a markdown file can be interpreted by not only
HUGO but gitlab too and so many other tools.
{{< video label="i love it" webm="/webm/i-love-it.webm" >}} {{< video label="i love it" webm="/webm/i-love-it.webm" >}}
Regarding themes, HUGO allows you to easily create your own, or just as Some advantages of static sites in general:
easily implement other peoples themes.
Although at the start HUGO seemed difficult to me I managed to learn it - Security
pretty quickly and appreciate the simplicity it brings to the table. I - Reliability
wouldn't say my workflow is perfect by any means but I feel HUGO makes - Scalability
it easy to develop a smooth workflow. - Low Resource Requirement
Although the pursuit of speed brought me to _HUGO_, here are a few other great
reasons:
- Git
- Markdown
- Simplicity
- Live Preview
I have recently started to use git a lot more and I'm able to implement a
content versioning system that can follow me everywhere.
Markdown is quick, gives me what I need and doesn't require me to right click.
_HUGO_ allows you to import pre-made themes or if your feeling up to it, make
your own.
Although at the start _HUGO_ seemed difficult to me I managed to learn and
appreciate the simplicity it brings to the table. My workflow is not perfect but
I feel _HUGO_ makes it easy to develop a smooth workflow.
Live Preview allows you to start up a light weight web server locally Live Preview allows you to start up a light weight web server locally
and has an auto refresh feature so whenever a change is made the web and has an auto refresh feature so whenever a change is made the web
@@ -110,7 +89,7 @@ page refreshes so you can see changes without manually refreshing.
## **Conclusion** ## **Conclusion**
This post is a quick intro to HUGO and why I choose to use it, However You've had a quick intro to _HUGO_ and why I choose to use it, I wrote another
there is another post on setting up a HUGO site from start to finish. post on setting up a _HUGO_ site from start to finish.
[Setting Up a HUGO Site](https://blog.ahmza.com/posts/setup-a-hugo-site) [Setting Up a _HUGO_ Site](https://blog.ahmza.com/posts/setup-a-hugo-site)
+133 -91
View File
@@ -20,21 +20,17 @@ searchHidden: false
## **Introduction** ## **Introduction**
Minecraft is a great game and when it comes to multiplayer, a dedicated Minecraft is a great game and better with friends. A dedicated server allows you
server is the way to go (here's why[^1]). Myself and a few others to do that[^1].
recently decided to start playing this game again, and I took the
opportunity to deploy the server in my lab.
A Minecraft server does not require a ton of resources to run, However A Minecraft server does not require a ton of resources to run, but from my
from my experience the more resources you can throw at it the better, experience the more resources you can throw at it the better when you start to
especially when you start to introduce mods and more than a few players. introduce mods and more players.
I run our server on my main PC within WSL and Docker. This allows me to I run our server on my main PC. This allows me to leverage the system resources
leverage the system resources in my PC 🦾 leaving the [Pi Cluster](https://blog.ahmza.com/posts/building-a-docker-swarm-with-pis/) in my PC 🦾 leaving the [Pi
to handle the rest of the stuff in my lab. The only reason I opted to Cluster](https://blog.ahmza.com/posts/building-a-docker-swarm-with-pis/) system
go this route is that I don’t want our server to be limited by hardware resources to handle the rest of the stuff in my lab.
resources as well as the Minecraft server effecting the overall
performance of the Pis.
## **Prerequisites** ## **Prerequisites**
@@ -63,35 +59,43 @@ performance of the Pis.
## **Building the Container** ## **Building the Container**
Now we have the formalities sorted, we can get to work on creating the
docker container for Minecraft.
1. **Create a directory in which you will keep the Minecraft server files** 1. **Create a directory in which you will keep the Minecraft server files**
- `mkdir minecraft-server`
- `cd minecraft-server` ```bash
# Make the folder
mkdir minecraft-server
# Ender the folder
cd minecraft-server
```
2. **Create an environment file to be used by the Docker Container** 2. **Create an environment file to be used by the Docker Container**
- The *.env* file allows us to specify variables which we can use - The _.env_ file allows us to specify variables used in the build process.
across the build process.
- `touch .env` ```bash
- Edit the file in a text editor, i.e. vim `vim .env` # Create a .env file
```bash touch .env
CONTAINER_NAME=minecraft-server # Open in a text editor
SERVER_MEM=4096 #change this to your desired value (in MB) vim .env
SERVER_JAR=minecraft_server.1.18.2.jar # Enter the following variables
``` CONTAINER_NAME=minecraft-server
SERVER_MEM=4096 #change this to your desired value (in MB)
SERVER_JAR=minecraft_server.<version>.jar # change the version
```
3. **Create the docker-compose.yml file** 3. **Create the docker-compose.yml file**
- The *docker-compose.yml* file specifies the container that we - The _docker-compose.yml_ file specifies the container that we want to build [^3]
want to build, outlining the build context (Dockerfile),
setting the variables (from .env), configuring storage volumes
for persistence as well as ports and the container name.
- `touch docker-compose.yml`
- Edit the file in a text editor[^3], I.e. vim `vim docker-compose.yml`
```bash
version: "3"
services: ```bash
# Create the file
touch docker-compose.yml`
# Open in a text editor
vim docker-compose.yml
```
```yaml
version: "3"
services:
minecraft-server: minecraft-server:
build: build:
context: . context: .
@@ -106,37 +110,41 @@ docker container for Minecraft.
container_name: ${CONTAINER_NAME} container_name: ${CONTAINER_NAME}
restart: unless-stopped restart: unless-stopped
volumes: volumes:
server-data: server-data:
``` ```
4. **Create the Dockerfile file** 4. **Create the Dockerfile file**
- The Dockerfile builds the container. We take the 17-jre base
image apply our variables change the working directory to
/server and start the jar file, effectively starting the
Minecraft server.
- `touch Dockerfile`
- Edit the file in a text editor, i.e. vim `vim Dockerfile`
```bash
FROM eclipse-temurin:17-jre
ARG SERVER_MEM - The Dockerfile builds the container image.
ARG SERVER_JAR
ENV SERVER_MEM=${SERVER_MEM} ```bash
ENV SERVER_JAR=${SERVER_JAR} # Create the file
touch Dockerfile`
# Open the file in a text editor
vim Dockerfile
```
WORKDIR /server ```Dockerfile
FROM eclipse-temurin:17-jre
CMD echo "Minecraft Server is starting\n" && java -Xms128M -Xmx${SERVER_MEM}M -jar ${SERVER_JAR} nogui ARG SERVER_MEM
``` ARG SERVER_JAR
ENV SERVER_MEM=${SERVER_MEM}
ENV SERVER_JAR=${SERVER_JAR}
WORKDIR /server
CMD echo "Minecraft Server is starting\n" && java -Xms128M -Xmx${SERVER_MEM}M -jar ${SERVER_JAR} nogui
```
## **Setup the Server files** ## **Setup the Server files**
We’re almost there, just a few steps left !! We’re almost there, just a few steps left !!
The curious among you may have realised when trying to start the The curious among you may have realised when trying to start the container that
container that it fails with the error below: it fails with the error below:
```bash ```bash
Minecraft Server is starting Minecraft Server is starting
@@ -151,58 +159,92 @@ our next step.
- [Vanilla Minecraft Server](https://www.minecraft.net/en-us/download/server) - instructions found here[^5] - [Vanilla Minecraft Server](https://www.minecraft.net/en-us/download/server) - instructions found here[^5]
- [Fabric Mod loader server](https://fabricmc.net/use/server/) - instructions found here [^6] - [Fabric Mod loader server](https://fabricmc.net/use/server/) - instructions found here [^6]
2. **Create a folder in the Minecraft-server folder called .server-data** 2. **Create a folder in the Minecraft-server folder called .server-data**
- `mkdir .server-data`
- `cd .server-data` ```bash
mkdir .server-data
cd .server-data
```
3. **Download the jar file - This will depend on the option above so read the instructions** 3. **Download the jar file - This will depend on the option above so read the instructions**
4. **Go back to the root minecraft-server folder** 4. **Go back to the root minecraft-server folder**
- `cd ..`
```bash
cd ..
```
5. **Run the container** 5. **Run the container**
- `docker compose up` (use CTRL+C to exit) This will create our eula.txt as well as other files needed.
- Once the server unpacks all the files you will see this:
```bash ```bash
minecraft-server | Starting net.minecraft.server.Main docker compose up # use CTRL+C to exit
minecraft-server | [18:05:50] [ServerMain/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info. ```
minecraft-server exited with code 0
``` ```bash
7. **Accept the EULA** minecraft-server | Starting net.minecraft.server.Main
- Go into the .server-data folder minecraft-server | [18:05:50] [ServerMain/INFO]: You need to agree to the EULA in order to run the server. Go to eula.txt for more info.
1. `cd .server-data` minecraft-server exited with code 0
- Edit the file named eula.txt in a text editor i.e. vim `vim eula.txt` ```
1. Simply change `eula=false` to `eula=true`
8. **While in the .server-data folder make any changes you want** 6. **Accept the EULA**
- Some files to note in here are
```bash
# enter the .server-data folder
cd .server-data
# edit eula.txt in a text editor
vim eula.txt
# change `eula=false` to `eula=true`
eula=true
```
7. **While in the .server-data folder make any changes you want**
- Notable files:
- **server.properties** - properties like server name, game mode, world type etc… - **server.properties** - properties like server name, game mode, world type etc…
- **ops.json** - list of server operators (easier to set ingame) - **ops.json** - list of server operators (easier to set ingame)
- **whitelist.json** - list of players allowed to join the server everyone else rejected access. - **whitelist.json** - list of players allowed to join the server everyone else rejected access.
9. **Run the container**
- `docker compose up -d` (the -d means detatched so we can run the server in the background) 8. **Run the container**
- `docker logs minecraft-server --follow` Will show us the progress of the server startup (to exit out of this do CTRL+C)
- If you see something like the following then you’re a winner 🥳 ```bash
```bash # -d flag allows the container to run in detached mode i.e in the background
docker compose up -d
```
```bash
# monitor the logs as the server starts. CTRL+C to exit
docker logs minecraft-server --follow
# If you see the bottom line then your server is up and running
[18:17:01] [Server thread/INFO]: Time elapsed: 25529 ms [18:17:01] [Server thread/INFO]: Time elapsed: 25529 ms
[18:17:01] [Server thread/INFO]: Done (34.571s)! For help, type "help" [18:17:01] [Server thread/INFO]: Done (34.571s)! For help, type "help"
``` ```
## Conclusion ## Conclusion
Well done you have successfully setup a Minecraft server, now go play !! Well done you have setup a Minecraft server, now go play !!
There is a lot of cool stuff you can do with a Minecraft server for
example installing mods or creating scripts to manage the server, this
will be covered in the next post so keep an eye out for it !!
There is a lot of cool stuff you can do from this point, for example installing
mods or creating scripts to manage the server.
[^1]: Hosting your own dedicated server allows you to modify every aspect of the server as you see fit. I.E you can modify the server-properties, you can implement a whitelist not to mention being able to add any mods you want [^1]:
Hosting your own dedicated server allows you to modify every aspect of the
server as you see fit. I.E you can modify the server-properties, you can
implement a whitelist not to mention being able to add any mods you want
[^2]: Requirements Gathered from here [https://minecraft.fandom.com/wiki/Server/Requirements/Dedicated#Unix\_.28Linux.2C\_BSD.2C\_macOS.29](https://minecraft.fandom.com/wiki/Server/Requirements/Dedicated#Unix_.28Linux.2C_BSD.2C_macOS.29) [^2]: Requirements Gathered from here [https://minecraft.fandom.com/wiki/Server/Requirements/Dedicated#Unix\_.28Linux.2C_BSD.2C_macOS.29](https://minecraft.fandom.com/wiki/Server/Requirements/Dedicated#Unix_.28Linux.2C_BSD.2C_macOS.29)
[^3]:
Yaml is very picky 😞 when it comes to formatting so if you encounter any
errors double check your formatting !!
[^3]: Yaml is very picky 😞 when it comes to formatting so if you encounter any errors double check your formatting !! [^4]:
I have left Forge out as it is a more involved process plus Fabric is
better 😜
[^4]: I have left Forge out as it is a more involved process plus Fabric is better 😜 [^5]:
Right click the green link that says something like minecraft_server.x.xx.x.jar and copy the link address
[^5]: Right click the green link that says something like minecraft_server.x.xx.x.jar and copy the link address `curl -o server.jar \<link you copied here\>`
curl -o server.jar \<link you copied here\> [^6]:
Select the Minecraft version, Fabric Loader Version and the Installer Version of your choice. I tend to go with the latest.
[^6]: Select the Minecraft version, Fabric Loader Version and the Installer Version of your choice. I tend to go with the latest. `Copy the curl command under CLI download`
Copy the curl command under CLI download
+155 -116
View File
@@ -17,43 +17,52 @@ cover:
showtoc: true showtoc: true
searchHidden: false searchHidden: false
--- ---
# **Introduction** # **Introduction**
SSH is a widely used protocol to access remote devices. The problem
with SSH is at the authentication stage, Brute force attacks are one of SSH is a widely used protocol to access remote devices. The problem with SSH is
the ways an SSH connection can be compromised. A malicious actor will at the authentication stage, Brute force attacks are one of the ways an SSH
constantly hammer the remote host with different passwords until it can connection is compromised. A malicious actor will constantly hammer the
gain access. With further configuration of SSH we can make the service remote host with different passwords until it can gain access. With further
a lot more secure. configuration of SSH we can make the service a lot more secure.
# **Configure SSH** # **Configure SSH**
{{< video label="this is fine" webm="/webm/this-is-fine.webm" >}} {{< video label="this is fine" webm="/webm/this-is-fine.webm" >}}
> **Famous last words:** Configuring SSH like many things in Linux is > **Famous last words:** Configuring SSH like many things in Linux is as simple
as simple as editing a few config files > as editing a few config files
Always be sure to **create a backup file** it's very easy to end up Always **create a backup file**, You can end up locking yourself out of a
locking yourself out of a device. device. Try this on a machine that is not critical.
I would recommend practising on a machine that is not critical.
## **Create SSH Keys** ## **Create SSH Keys**
SSH keys use public and private key encryption for authentication. SSH keys use public and private key encryption for authentication.
To create a set of keys, **on the client do:** To create a set of keys, **on the client do:**
``` bash
ssh-keygen ```bash
ssh-keygen -t ecdsa -C <username>@<hostname>
``` ```
You will be asked where you want to save the keys, **I recommend the \
default location** for less hair pulling later. - -t ecdsa - sets the key encryption type to _ecdsa_
``` bash - -C - Comment or name of the _SSH_ key. **Replace content in <>**
Where you want to save the keys, **I recommend the default location**
```bash
Enter file in which to save the key (/home/user/.ssh/id_rsa): Enter file in which to save the key (/home/user/.ssh/id_rsa):
``` ```
You will be asked to enter a password for the ssh keys, be sure to use
a strong password. Password for the ssh key, please use a strong password.
``` bash
```bash
Enter passphrase (empty for no passphrase): Enter passphrase (empty for no passphrase):
``` ```
Once that is done you will see a confirmation screen like the one below
Once done you will see a confirmation screen like the one below
``` ```
Output Output
Your identification has been saved in /home/user/.ssh/id_rsa Your identification has been saved in /home/user/.ssh/id_rsa
@@ -75,16 +84,16 @@ The key's randomart image is:
``` ```
## **Copy SSH Keys** ## **Copy SSH Keys**
> **Quick note:** user@host is the **username** on the **remeote host**
you would like to copy your public key to.
``` bash ```bash
ssh-copy-id user@host ssh-copy-id user@host
``` ```
> **Quick note:** user@host is the **username** on the **remeote host** you
> would like to copy your public key to.
**If asked to confirm the connection to the remote host answer yes**, this **If asked to confirm the connection to the remote host answer yes**, this
happens when a new machine with an unknown identity wants to connect to happens when a new machine with an unknown identity wants to connect.
the client.
``` ```
Output Output
@@ -93,8 +102,7 @@ ECDSA key fingerprint is xx:xx:xx:xx:xx:xx:xx:xx.
Are you sure you want to continue connecting (yes/no)? yes Are you sure you want to continue connecting (yes/no)? yes
``` ```
You will then be asked to **enter a password** for the user on the remote **Enter a password** for the user on the remote host
host
``` ```
Output Output
@@ -103,42 +111,48 @@ Output
user@host's password: user@host's password:
``` ```
If successful you should be able to access the device using the SSH key Access the remote device using the SSH key
To verify this, SSH to the device and **it should ask for the Keys's To verify this, SSH to the device and **it should ask for the Keys password not
password not the users** the users**
``` bash ```bash
Enter passphrase for key '/home/user/.ssh/id_rsa': Enter passphrase for key '/home/user/.ssh/id_rsa':
``` ```
## **Modify SSH Config** ## **Modify SSH Config**
create a backup create a backup
``` bash
```bash
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
``` ```
open the original file in a text editor open the original file in a text editor
``` bash
**NeoVim BTW!!**
```bash
sudo vim /etc/ssh/sshd_config sudo vim /etc/ssh/sshd_config
``` ```
For a new user this might be daunting. Take your time and you will be
For a new _Linux_ user this might be daunting. Take your time and you will be
fine 😊 fine 😊
{{< video label="thats a big one" webm="/webm/thats-a-big-one.webm" >}} {{< video label="thats a big one" webm="/webm/thats-a-big-one.webm" >}}
**Lines we want to modify** **Lines we want to modify**
> **Quick note:** you may need to uncomment some lines as well as add a > **Note:** uncomment lines as well as add missing lines
few
* Protocol 2 - add to line 15 - Protocol 2
* Port 2222 - modify line 17 - Port 2222
* PermitRootLogin no - modify line 36 - PermitRootLogin no
* Max Auth Tries 5 - modify line 38 - Max Auth Tries 5
* PasswordAuthentication no - modify line 60 - PasswordAuthentication no
* PermitEmptyPasswords no -modify line 61 - PermitEmptyPasswords no
* AllowUsers ahmza - add line 67 - AllowUsers <user>
* ClientAliveInterval 180 - modify line 104 - ClientAliveInterval 180
``` ```
# $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $ # $OpenBSD: sshd_config,v 1.103 2018/04/09 20:41:22 tj Exp $
@@ -203,7 +217,7 @@ MaxAuthTries 5
PasswordAuthentication no PasswordAuthentication no
PermitEmptyPasswords no PermitEmptyPasswords no
AllowUsers ahmza AllowUsers <user>
# Change to yes to enable challenge-response passwords (beware issues with # Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads) # some PAM modules and threads)
@@ -273,65 +287,74 @@ Subsystem sftp /usr/lib/openssh/sftp-server
{{< video label="not so bad" webm="/webm/wasnt-so-bad.webm" >}} {{< video label="not so bad" webm="/webm/wasnt-so-bad.webm" >}}
**Now lets explain what we just did** **Now lets explain what we just did**
* **Protocol 2** - released in 2006, SSH2 introduced improved
encryption algorithms.
* **Port 2222** - The port number can be whatever number you want.
Choose something other than 22 this will help hide your device from malicious actors
* **PermitRootLogin no** - If the root account were to be compromised
then the attacker has full control of the system so we stop it from being able to log in.
* **MaxAuthTries 5** - After 5 failed attempts the remote host blocks
requests from that IP for a period of time.
* **PasswordAuthentication no** - We have the SSH key installed so we
no longer need to have password authentication.
* **PermitEmptyPasswords no** - We don't want to allow empty passwords
to be used as authentication for obvious reasons.
* **AllowUsers username** - Add the usernames of users you want to be
able to connect to the remote host and other users trying to connect
will be dropped.
* **Client Alive Interval 180** - Drop the connection after a certain
period of inactivity
## **Check were able to connect** - **Protocol 2** - released in 2006, SSH2 introduced improved encryption
algorithms.
- **Port 2222** - The port number can be whatever number you want. Choose
something other than 22 this will help hide your device from malicious actors
- **PermitRootLogin no** - If the root account gets compromised then the
attacker has full control so we stop root from logging in over ssh.
- **MaxAuthTries 5** - After 5 failed attempts the remote host blocks requests
from that IP for some of time.
- **PasswordAuthentication no** - The SSH key is installed, no need to have
password authentication.
- **PermitEmptyPasswords no** - Don't allow empty passwords
- **AllowUsers username** - Add the users you want to connect to the remote
host, others will be dropped.
- **Client Alive Interval 180** - Drop the connection after 180s of inactivity
## **Check ability to connect**
restart sshd service restart sshd service
``` bash
```bash
sudo systemctl restart sshd sudo systemctl restart sshd
``` ```
**Keep the current SSH connection open** and create a new session. **Keep the current SSH connection open** and create a new session.
If you are able to connect to the remote hosts then you are all set. If If you connect to the remote host then you're set. If not then you still have
not then you still have the initial connection to the remote host to the initial connection to the remote host to roll back the changes and
roll back the changes and troubleshoot. troubleshoot.
# **Success** # **Success**
{{< video label="clap" webm="/webm/clap.webm" >}} {{< video label="clap" webm="/webm/clap.webm" >}}
# **Setting up** ***Fail2Ban*** # **Setting up** **_Fail2Ban_**
_Fail2Ban_ is an intrusion prevention tool. Although we are slowing
bots down with MaxAuthTries the attacker is still able to carry on _Fail2Ban_ is an intrusion prevention tool. Although we slow down attackers with
brute forcing. Which is what Fail2Ban is for, it actually blocks the with MaxAuthTries they can still carry on brute forcing. Which is what Fail2Ban
connections from that IP. does, it actually blocks the connections from that IP.
## **Install** **_Fail2Ban_**
## **Install** ***Fail2Ban***
**We will install Fail2Ban on the remote host** **We will install Fail2Ban on the remote host**
First upgrade any packages, then **install** ***Fail2Ban*** First upgrade any packages, then **install** **_Fail2Ban_**
``` bash
```bash
sudo apt update && sudo apt upgrade sudo apt update && sudo apt upgrade
sudo apt install fail2ban sudo apt install fail2ban
``` ```
Now we need to enable the service so it starts when the remote host Now we need to enable the service so it starts when the remote host
starts starts
``` bash
```bash
sudo systemctl enable --now fail2ban sudo systemctl enable --now fail2ban
``` ```
## **Configure** ***Fail2Ban***
The Fail2Ban config file we want to edit is called **jail.local** located in **/etc/fail2ban/** ## **Configure** **_Fail2Ban_**
The config file we want to edit is **jail.local** located in **/etc/fail2ban/**
open jail.local in your editor of choice open jail.local in your editor of choice
``` bash
```bash
sudo vim /etc/fail2ban/jail.local sudo vim /etc/fail2ban/jail.local
``` ```
The config for _Fail2Ban_ is a lot shorter than sshd so this should be
quick The config for _Fail2Ban_ is nice and short
``` ```
[DEFAULT] [DEFAULT]
bantime = 8h bantime = 8h
@@ -349,80 +372,96 @@ quick
**[Default]** - Settings in here apply to all jails **[Default]** - Settings in here apply to all jails
* **bantime** - how long the ban will last - **bantime** - how long the ban will last
* **ignoreip** - IP addresses to ignore - **ignoreip** - IP addresses to ignore
* **ignoreself** - stops from locking itself out - **ignoreself** - stops from locking itself out
**[sshd]** - this is the jail for sshd **[sshd]** - this is the jail for sshd
* **enabled** - decides weather the jail is active or not - **enabled** - decides weather the jail is active or not
* **port** - the port number the service - **port** - the port number the service
* **filter** - tells the jail which filter to use from /etc/fail2ban/filter.d - **filter** - tells the jail which filter to use from /etc/fail2ban/filter.d
* **logpath** - where the log you want fail2ban to read is - **logpath** - where the log you want fail2ban to read is
* **maxretry** - Times the client can attempt a login before being banned - **maxretry** - Times the client can attempt a login before being banned
* **findtime** - An amount of time which maxretry must occur to trigger a - **findtime** - An amount of time which maxretry must occur to trigger a ban
ban for example in 10 minutes if 3 failed login attempts are made the for example in 10 minutes if 3 login attempts fail ban the IP
ban the IP
**Restart** ***Fail2Ban*** to load the configuration **Restart** **_Fail2Ban_** to load the configuration
``` bash
```bash
sudo systemctl restart fail2ban sudo systemctl restart fail2ban
``` ```
## **Testing** ***Fail2Ban*** ## **Testing** **_Fail2Ban_**
To test Fail2Ban lets create a test user and set a password for the To test Fail2Ban lets create a test user and set a password for the
user user
``` bash
```bash
sudo useradd test sudo useradd test
sudo passwd test sudo passwd test
``` ```
**open the sshd config** **open the sshd config**
``` bash
```bash
sudo vim /etc/ssh/sshd_config sudo vim /etc/ssh/sshd_config
``` ```
modify the line **PasswordAuthentication** to say **yes** and add the test user to **AllowUsers**
``` bash Modify the line **PasswordAuthentication** to say **yes** and add the test user
to **AllowUsers**
```bash
PasswordAuthentication yes PasswordAuthentication yes
AllowUsers user test AllowUsers user test
``` ```
**restart the sshd service** **restart the sshd service**
``` bash
```bash
sudo systemctl restart sshd sudo systemctl restart sshd
``` ```
Attempt to login to the remote host using the test account using an
incorrect password. After 3 failed attempts it should say connection Attempt to login to the remote host using the test account using an incorrect
refused. password. After 3 failed attempts it should say connection refused.
``` bash
```bash
ssh test@host -p 2222 ssh test@host -p 2222
``` ```
_Fail2Ban_ should do something along the lines of ... _Fail2Ban_ should do something along the lines of ...
{{< video label="you shall not pass" webm="/webm/you-shall-not-pass.webm" >}} {{< video label="you shall not pass" webm="/webm/you-shall-not-pass.webm" >}}
log back in as your normal user, remove the test user and restore the log back in as your normal user, remove the test user and restore the sshd
sshd config. config.
**To remove the user** **To remove the user**
``` bash
```bash
sudo userdel test sudo userdel test
``` ```
**restore the /etc/ssh/sshd_config file** **restore the /etc/ssh/sshd_config file**
``` bash
```bash
sudo vim /etc/ssh/sshd_config sudo vim /etc/ssh/sshd_config
``` ```
Set **PasswordAuthentication** back to **no** and remove test from **AllowUsers** Set **PasswordAuthentication** back to **no** and remove test from **AllowUsers**
``` bash
```bash
PasswordAuthentication no PasswordAuthentication no
AllowUsers user AllowUsers user
``` ```
# **Conclusion** # **Conclusion**
well done, you managed to make it through all that !! At least now you
can be reassured that if them pesky brute-force attackers decide to well done, you managed to make it through all that !! At least now you can be
target your machine they wont have a fun time being in Jail 🤣 sorry reassured that if them pesky brute-force attackers decide to target your machine
bad joke. they can have a fun time in Jail 🤣 sorry bad joke.
By now you have managed to setup an ssh key for a client and copy it to By now you have managed to setup an ssh key for a client and copy it to
a remote host, re-configure the sshd config to lockdown authentication a remote host, re-configure the sshd config to lockdown authentication
and last but not least install and configure Fail2Ban to block pesky and install and configure Fail2Ban to block pesky attackers.
attackers.
{{< video label="proud" webm="/webm/proud.webm" >}} {{< video label="proud" webm="/webm/proud.webm" >}}
+65 -41
View File
@@ -5,7 +5,7 @@ author: "ahmza"
draft: false draft: false
weight: weight:
tags: ["blog","website","web development","HUGO"] tags: ["blog", "website", "web development", "HUGO"]
description: "Always wanted to setup a static website. Look no further !! In this post we go over the basics of setting up a HUGO site" description: "Always wanted to setup a static website. Look no further !! In this post we go over the basics of setting up a HUGO site"
canonicalURL: "https://blog.ahmza.com/Page%28/posts/setting-up-a-hugo-site.md%29" canonicalURL: "https://blog.ahmza.com/Page%28/posts/setting-up-a-hugo-site.md%29"
@@ -14,46 +14,55 @@ cover:
alt: "HUGO Logo" # alt text alt: "HUGO Logo" # alt text
caption: "The HUGO logo" # display caption under cover caption: "The HUGO logo" # display caption under cover
relative: false # when using page bundles set this to true relative: false # when using page bundles set this to true
--- ---
## **Introduction** ## **Introduction**
Hugo is a static site generator, a tool that allows us to pre-compile our website into static HTML, CSS and JS. _HUGO_ is a static site generator, a tool that allows us to pre-compile our
The main benefit of using such methods is speed. website into static HTML, CSS and JS. The main benefit of an _ssg_ is speed. A
A Static site takes a lot less time to load than a site that uses databases. Static site takes a lot less time to load than a site that uses databases.
For more information on HUGO read my other post [Hugo Static Site Generator](https://blog.ahmza.com/posts/hugo-static-site-generator/) For more information on HUGO read my other post [Hugo Static Site
Generator](https://blog.ahmza.com/posts/hugo-static-site-generator/)
## **Prerequisites** ## **Prerequisites**
- Git - Git
## **Installing HUGO** ## **Installing HUGO**
[Official steps](https://gohugo.io/installation/) [Official steps](https://gohugo.io/installation/)
The HUGO binary is what we will use throughout the creation of our project to initially setup our site then create posts etc... The _HUGO_ binary is used to initialize our site then create posts etc... Below
This step will vary depending on your operating system and distribution. are the steps for _MacOS_ and _Arch_ based _Linux_ distros.
I will show the steps for MacOS and Arch based Linux distros.
### _MacOS_
### MacOS
- Install [homebrew](https://brew.sh/) - Install [homebrew](https://brew.sh/)
``` bash
```bash
brew install hugo brew install hugo
``` ```
### Arch ### _Arch_
``` bash
```bash
sudo pacman -S hugo sudo pacman -S hugo
``` ```
### Confirm Installation ### Confirm Installation
``` bash
```bash
hugo version hugo version
``` ```
## Create your site ## Create your site
This assumes a few steps for you, i.e the theme used. The settings in this guide will mimic the base config of my site
``` bash This assumes choices for you, i.e the theme used.
> The settings in this guide will mimic the base config of my site
```bash
hugo new site -f yml <your-sitename> hugo new site -f yml <your-sitename>
cd <your-sitename> cd <your-sitename>
git init git init
@@ -62,20 +71,21 @@ echo "theme: 'PaperMod'" >> config.yml
``` ```
## Create Content ## Create Content
We will now begin adding new content to our website. Lets create our first post. We will now begin adding new content to our website. Lets create our first post.
Lets start by creating a template for our posts. Lets start by creating a template for our posts.
``` bash ```bash
vim archetypes/posts.md vim archetypes/posts.md
``` ```
Paste the following base template Paste the following base template
``` markdown ```markdown
--- ---
title: {{ replace .TranslationBaseName "-" " " | title }} title: { { replace .TranslationBaseName "-" " " | title } }
date: {{ .Date }} date: { { .Date } }
author: "<author>" author: "<author>"
draft: true draft: true
weight: weight:
@@ -89,7 +99,6 @@ cover:
alt: "<alt text>" # alt text alt: "<alt text>" # alt text
caption: "<text>" # display caption under cover caption: "<text>" # display caption under cover
relative: false # when using page bundles set this to true relative: false # when using page bundles set this to true
--- ---
## **Introduction** ## **Introduction**
@@ -98,27 +107,32 @@ cover:
``` ```
If the posts folder does not exist, create it If the posts folder does not exist, create it
``` bash
```bash
mkdir content/posts mkdir content/posts
``` ```
Create and edit a post Create and edit a post
``` bash
> pick an editor of your choice. **I use NVIM BTW**
```bash
hugo new posts/<post-name>.md hugo new posts/<post-name>.md
vim content/posts/<post-name>.md vim content/posts/<post-name>.md
``` ```
## Start the server ## Start the server
Now that we have created our site, installed a theme and created a post lets start the server. Now that we have created our site, installed a theme and created a post lets
start the server.
``` bash ```bash
hugo server -D hugo server -D
``` ```
*The -D flag tells hugo server to build drafts. (notice how we have a draft: option in our posts template.)*
*Of course once you have finished a post you set draft to false like so draft: false*
You will be shown something like the following: _The -D flag tells hugo server to build drafts. (notice how we have a draft:
option in our posts template.) Of course once you have finished a post you set
draft to false like so draft: false_
``` ```
➜ hugo server -D ➜ hugo server -D
@@ -146,22 +160,25 @@ Web Server is available at http://localhost:1313/ (bind address 127.0.0.1)
Press Ctrl+C to stop Press Ctrl+C to stop
``` ```
*Notice the second line to the bottom. Web Server... This line gives you a localhost url that you can use in your browser to view your site locally.* _Notice the second line to the bottom. Web Server... This line gives you a
localhost URL that you can use in your browser to view your site locally._
## Configure Site ## Configure Site
Open the config.yml file in a text editor. Open the config.yml file in a text editor.
``` bash ```bash
vim config.yml vim config.yml
``` ```
**Important changes you need to make** **Important changes you need to make**
- baseURL - this is the URL your site will be accessed externally. In my case. https://blog.ahmza.com
- title - is the title of your page. - baseURL - External URL. In my case. https://blog.ahmza.com
- title - Title of your site.
Here is my config.yml with bits redacted so you can fill them in Here is my config.yml with bits redacted so you can fill them in
``` yaml
```yaml
baseURL: "<your sites URL>" baseURL: "<your sites URL>"
title: <your site title> title: <your site title>
paginate: 5 paginate: 5
@@ -305,23 +322,30 @@ markup:
``` ```
## Run the server again ## Run the server again
Run the server and check out your hard work. Change settings make posts etc. Have fun !!
``` bash Run the server and check out your hard work. Change settings make posts etc.
Have fun !!
```bash
hugo server -D hugo server -D
``` ```
## Publish your site ## Publish your site
Once you are happy with your site, you may want to publish it to the internet. Once you are happy with your site, you may want to publish it to the internet.
In the next post [Publishing your HUGO site](https://blog.ahmza.com/posts/publishing-your-hugo-site/) In the next post [Publishing your HUGO
I will cover a basic method of publishing your site as well as a more complicated but automated workflow that I use. site](https://blog.ahmza.com/posts/publishing-your-hugo-site/) I will cover a
basic method of publishing your site as well as a more complicated but automated
workflow that I use.
## **Conclusion** ## **Conclusion**
Through this post you have learned to create your own HUGO site as well as create and edit posts. Through this post you have learned to create your own HUGO site as well as
We also learned about create and edit posts. We also learned about
- archetypes - archetypes
- Mark posts as drafts (expand on this - Mark posts as drafts
- The hugo built in server (still need to add this)) - The _HUGO_ built in server
- webp + webm (still need to add this) - webp + webm (still need to add this)
- shortcodes (still need to add this) - shortcodes (still need to add this)
+27 -20
View File
@@ -19,53 +19,60 @@ searchHidden: false
--- ---
## **Introduction** ## **Introduction**
WSL stands for *Windows Subsystem for Linux* which means we have the
Linux kernel inside of windows. This is huge news for developers or people WSL stands for _Windows Subsystem for Linux_ which means we have the Linux
who just want to try Linux. kernel inside of windows. This is huge news for developers or people who just
want to try Linux.
## **Prerequisites** ## **Prerequisites**
* Enable virtualisation in BIOS
- Enable virtualisation in BIOS
## **Setup** ## **Setup**
Open Powershell in Administrator mode Open Powershell in Administrator mode
``` powershell
```powershell
wsl --install wsl --install
``` ```
> You may be required to restart the device, I Highly recommend you do
> You may have to restart the device, I Highly recommend you do
Go to the Microsoft store and search for a Linux distribution. I prefer Go to the Microsoft store and search for a Linux distribution. I prefer
to use the "Ubuntu" distro. to use the "Ubuntu" distribution.
![Microsoft Store](/img/WSL/ubuntu.webp) ![Microsoft Store](/img/WSL/ubuntu.webp)
Once that is installed, go ahead and run the distribution, after it Once installed, go ahead and run the distribution, after it finishes setting
finishes setting itself up it will ask you for a username and password. itself up it will ask you for a username and password. These credentials are
These credentials are separate from the host system so you can make them separate from the host system so you can make them whatever you want.
whatever you want.
And that's it you have WSL and a Linux distribution setup, now go and do And that's it you have WSL and a Linux distribution setup, now go and do
something awesome. something awesome.
## **Optional** ## **Optional**
I use the windows terminal app to run the Ubuntu distribution, it makes I use the windows terminal app to run the Ubuntu distribution, it makes
customising the environment a lot easier. To download it head over to the customising the environment a lot easier. To download it head over to the
Microsoft store and search for Windows Terminal and download it. Microsoft store and search for Windows Terminal and download it.
![Microsoft Store](/img/WSL/winterm.webp) ![Microsoft Store](/img/WSL/winterm.webp)
When you login to WSL it will not default to your home directory which gets When you login to WSL it will not default to your home directory. To fix that go
very annoying. So to fix that go to Windows Terminal Settings (Be sure to to the Windows Terminal Settings look for Ubuntu or your distributions name and
look around there are some cool features) look for Ubuntu or your change the Starting directory to
distributions name and change the Starting directory to
``` powershell
\\wsl$\Ubuntu\home\ahmza
```
> Be sure to change "Ubuntu" to your distributions name
> Be sure to change "ahmza" to your username ```powershell
\\wsl$\<distro>\home\<username>
```
> Be sure to change "<distro>" to your distributions name
> Be sure to change "<username>" to your username
![winterm-settings](/img/WSL/winterm-settings.webp) ![winterm-settings](/img/WSL/winterm-settings.webp)
## **Conclusion** ## **Conclusion**
Well done you have managed to setup WSL and use Linux inside of windows. Well done you have managed to setup WSL and use Linux inside of windows.
No go and enjoy the freedom of Linux !! No go and enjoy the freedom of Linux !!
+5 -2
View File
@@ -5,7 +5,7 @@ author: "ahmza"
draft: true draft: true
weight: weight:
tags: ["career","twitch"] tags: ["career", "twitch"]
description: "" description: ""
canonicalURL: "https://blog.local.ahmza.com/Page%28/posts/twitch-layoffs.md%29" canonicalURL: "https://blog.local.ahmza.com/Page%28/posts/twitch-layoffs.md%29"
@@ -14,15 +14,16 @@ cover:
alt: "Bleed Purple" # alt text alt: "Bleed Purple" # alt text
caption: "Bleed Purple" # display caption undercover caption: "Bleed Purple" # display caption undercover
relative: false # when using page bundles set this to true relative: false # when using page bundles set this to true
--- ---
# Mon 20 Mar 2023 # Mon 20 Mar 2023
The news was broken to all Twitch employees that there was going to be a mass layoff that would nuke 1/5th of Twitch's workforce, The news was broken to all Twitch employees that there was going to be a mass layoff that would nuke 1/5th of Twitch's workforce,
Just over 400 employees. We were not given a date that this would happen we were just told that it would be by the end of the week Just over 400 employees. We were not given a date that this would happen we were just told that it would be by the end of the week
or early the next week. or early the next week.
# Fri 24 Mar 2023 # Fri 24 Mar 2023
The day started with an announcement that Twitch would layoff 1/5th of its workforce. The anticipation of this moment through the The day started with an announcement that Twitch would layoff 1/5th of its workforce. The anticipation of this moment through the
whole week left hundreds of us with a sick feeling in our stomachs. They had split the layoffs up between APAC, EMEA, And AMER. whole week left hundreds of us with a sick feeling in our stomachs. They had split the layoffs up between APAC, EMEA, And AMER.
APAC on the chopping block first. We saw people loose access and numbers from our #general Slack channel dither. Each Region had APAC on the chopping block first. We saw people loose access and numbers from our #general Slack channel dither. Each Region had
@@ -40,8 +41,10 @@ it comes to work will we miss these people, The two Technicians that I worked wi
interactions. interactions.
# Conclusion # Conclusion
If you're reading this, and you are a recruiter then please take into account ex-twitch employees effected by this tragic event. If you're reading this, and you are a recruiter then please take into account ex-twitch employees effected by this tragic event.
Shout outs to: Shout outs to:
- [Anastasia Limantzakis](https://www.linkedin.com/in/anastasia-limantzakis/) - [Anastasia Limantzakis](https://www.linkedin.com/in/anastasia-limantzakis/)
- [Viktoria (Viki) Bagley](https://www.linkedin.com/in/viktoria-bagley-97a669206/) - [Viktoria (Viki) Bagley](https://www.linkedin.com/in/viktoria-bagley-97a669206/)
+15 -13
View File
@@ -25,20 +25,22 @@ I'd like to say thank you for visiting this site.
### A bit about me ### A bit about me
I'm based in the UK, and like most people -- probably you -- I'm As a tinkerer, I'm always looking to expand my knowledge. My passion for
interested in learning new technologies and techniques. learning leads me down many paths, including this website, giving me the
opportunity to learn how web servers work and the intricacies of neighboring
systems.
I get bored, so to keep myself busy I learn new stuff. This site exists because I'm eager to share my knowledge with others and see them succeed in their own
I wanted to learn how web servers work and along the way I learned a lot about pursuits.
neighboring moving parts.
I'm enthusiastic about learning and love when people sharing my findings. Tinkering began watching programs like "How it's Made" and "Myth Busters". This
I am slowly building my network of people whom I can share my progress with and sparked curiosity and led me to experiment with breaking things myself. As I got
collaborate. older, I chased the white rabbit further and further.
I have always tinkered and naturally gained an interest for technology, I don't I also enjoy nurturing my creative side which allows me to step away from the
limit myself to one part of tech I try to dabble in a bit of everything. one mechanical aspects of technology. And pottery is my medium. Throwing at the
hobby that has stuck with me is photography where you have to understand the wheel is a form of meditation that allows me to connect with my own creativity.
camera and its limits to adapt to different situations.
You can see some of my photography on my Instagram. My goal is to use my passion for sharing and learning to make a positive impact.
To keep looking for new challenges and opportunities to grow, and inspire others
to do the same.
+36 -31
View File
@@ -20,10 +20,10 @@ searchHidden: false
## **Introduction** ## **Introduction**
**You need to learn *Linux*** !! **You need to learn _Linux_** !!
Without a doubt you will come across *Linux* at some point in your IT career and Without a doubt you will come across _Linux_ at some point in your IT career and
having baseline knowledge is helpful. *Linux* can seem daunting, it's having baseline knowledge is helpful. _Linux_ can seem daunting, it's
fundamentally different compared to windows. but with a bit of time you can fundamentally different compared to windows. but with a bit of time you can
master the basics and unlock its true power. master the basics and unlock its true power.
@@ -31,27 +31,28 @@ master the basics and unlock its true power.
## **But Why** ## **But Why**
- ***Linux* is everywhere**, from data centres to your smart fridge. A lot of - **_Linux_ is everywhere**, from data centres to your smart fridge. A lot of
developers at Google use *Linux*. In fact access to the full codebase is given developers at Google use _Linux_. In fact access to the full codebase is given
on *Linux*. on _Linux_.
- **Power user?** The ability to personalise all aspects of the system **make it - **Power user?** The ability to personalise all aspects of the system **make it
your** system. This can result in you chasing the white rabbit, but the feeling your** system. This can result in you chasing the white rabbit, but the feeling
of booting into a system that's yours from start to finish is something else. of booting into a system that's yours from start to finish is something else.
- **Make it pretty** - You can create something that's **functional and beautiful** - **Make it pretty** - You can create something that's **functional and beautiful**
[r/unixporn](https://www.reddit.com/r/unixporn/) [r/unixporn](https://www.reddit.com/r/unixporn/)
**Lightweight and extensible** limiting the fluff. Making *Linux* by default a **Lightweight and extensible** limiting the fluff. Making _Linux_ by default a
lot faster than other operating systems. lot faster than other operating systems.
## **Ok but what about ...** ## **Ok but what about ...**
- **Application Support** - Some popular applications you use may not be
available e.g Microsoft Office and the Adobe suite. All is not lost though,
there are alternatives if you can spend the time learning new software.
- **Drivers** - More often than not *Linux* just works. Edge cases could rise - **Application Support** - Some popular applications you use may not be
that you might struggle with, don't give up Google it and dig in !! available e.g Microsoft Office and the Adobe suite. All is not lost though,
there are alternatives if you can spend the time learning new software.
- **Drivers** - More often than not _Linux_ just works. Edge cases could rise
that you might struggle with, don't give up Google it and dig in !!
## **How can you start** ## **How can you start**
@@ -61,54 +62,58 @@ that you might struggle with, don't give up Google it and dig in !!
**This is the full send option.** It may take you a while to acclimate but I feel **This is the full send option.** It may take you a while to acclimate but I feel
this is the fastest option to success as you force yourself into learning. this is the fastest option to success as you force yourself into learning.
*Linux* Distributions I have enjoyed using: _Linux_ Distributions I have enjoyed using:
- [Ubuntu](https://ubuntu.com/download/desktop) - Beginner friendly - [Ubuntu](https://ubuntu.com/download/desktop) - Beginner friendly
- [Manjaro](https://manjaro.org) - OS Basics set up, provides more flexibility - [Manjaro](https://manjaro.org) - OS Basics set up, provides more flexibility
- [Arch Linux](https://wiki.archlinux.org/title/installation_guide) - Jump in the deep end, go from start to finish and learn all about *Linux's* moving parts - [Arch Linux](https://wiki.archlinux.org/title/installation_guide) - Jump in the deep end, go from start to finish and learn all about _Linux's_ moving parts
### ***MacOS* Terminal** ### **_MacOS_ Terminal**
**If you do not own a *MacBook* skip this due to cost 💸** **If you do not own a _MacBook_ skip this due to cost 💸**
*MacOS* is *UNIX* based, **if you own a *MacBook* download a Terminal Emulator** _MacOS_ is _UNIX_ based, **if you own a _MacBook_ download a Terminal Emulator**
-- [iterm2](https://iterm2.com/) or [kitty](https://sw.kovidgoyal.net/kitty/binary/) -- [iterm2](https://iterm2.com/) or [kitty](https://sw.kovidgoyal.net/kitty/binary/)
both great options -- install [Homebrew](https://brew.sh/) and get going. both great options -- install [Homebrew](https://brew.sh/) and get going.
### ***Windows WSL***
*WSL* installs the *Linux Kernel* and allows you to use the *Linux* terminal ### **_Windows WSL_**
within *Windows*. This does have its limitations but a low bar to entry.
_WSL_ installs the _Linux Kernel_ and allows you to use the _Linux_ terminal
within _Windows_. This does have its limitations but a low bar to entry.
### **Virtual machines** ### **Virtual machines**
Virtualising *Linux* is another great option. VMs are quick to spin up and remove Virtualising _Linux_ is another great option. VMs are quick to spin up and remove
providing the ability to try out a handful of distributions with ease. This does providing the ability to try out a handful of distributions with ease. This does
come with the condition of having a device that can handle virtual machines come with the condition of having a device that can handle virtual machines
meaning: meaning:
- A CPU capable of virtualization - A CPU capable of virtualization
- enough free RAM for the VMs - enough free RAM for the VMs
### **Buy a secondary device** ### **Buy a secondary device**
Have another cheap laptop or desktop to run *Linux*. This will cost you a bit Have another cheap laptop or desktop to run _Linux_. This will cost you a bit
more than the options above. If you're considering a second device then look more than the options above. If you're considering a second device then look
at the Thinkpad lineup. These laptops are rugged and highly upgradeable. at the Thinkpad lineup. These laptops are rugged and highly upgradeable.
Two Thinkpad Models I own: Two Thinkpad Models I own:
- T440P - T440P
- T480 *(Non S model)* - T480 _(Non S model)_
## Conclusion ## Conclusion
**Why are you still reading go and get stuck in with *Linux* 💨** **Why are you still reading go and get stuck in with _Linux_ 💨**
{{< video label="do it" webm="/webm/do-it.webm" >}} {{< video label="do it" webm="/webm/do-it.webm" >}}
**Learning *Linux* is a journey that will take time. Enjoy the experience of **Learning _Linux_ is a journey that will take time. Enjoy the experience of
learning and uncovering it's hidden powers.** learning and uncovering it's hidden powers.**
I have linked some great resources for other great *Linux* related content that I have linked some great resources for other great _Linux_ related content that
helped me: helped me:
- [DT YouTube Channel](https://www.youtube.com/channel/UCVls1GmFKf6WlTraIb_IaJg) - - [DT YouTube Channel](https://www.youtube.com/channel/UCVls1GmFKf6WlTraIb_IaJg) -
Covers *Linux* related topics Covers _Linux_ related topics
- [r/unixporn](https://www.reddit.com/r/unixporn/) - Get inspired and make *Linux* pretty - [r/unixporn](https://www.reddit.com/r/unixporn/) - Get inspired and make _Linux_ pretty
- [Arch Wiki](https://wiki.archlinux.org/) - Although specific to Arch, it's a great knowledge base - [Arch Wiki](https://wiki.archlinux.org/) - Although specific to Arch, it's a great knowledge base
+1 -1
View File
@@ -15,7 +15,7 @@ spec:
spec: spec:
containers: containers:
- name: blog-app - name: blog-app
image: registry.gitlab.com/ahmza/blog:1.0.6 image: registry.gitlab.com/ahmza/blog:1.2.3
imagePullPolicy: Always imagePullPolicy: Always
ports: ports:
- name: web - name: web