diff --git a/templates/projects.html b/templates/projects.html index ffecc5d..c74313d 100644 --- a/templates/projects.html +++ b/templates/projects.html @@ -5,12 +5,7 @@
- The majority of the process to set up this server was followed from here. - Here I will outline where I deviated and use workarounds to make all this work on Arch Linux. -
- -pacman -Syu instead of syspatchuseradd -m <UserName> will automatically fill out all the defaultspasswd <UserName> to set the users password.usermod -aG wheel,wheelnpw <UserName> to allow executing as root without passworddoas in command with sudorcctl in command with systemctl- Here I deviated much more from the steps so I will write out the steps used without referring to Derek's original document. -
-ssh <UserName>@yourdomain.namesudo sufdisk -l will list the disks available, look for the one with the size of the blockstorage you added to your server.
- cryptsetup -y -v --type luks2 luksFormat /dev/vdb
- dd if=/dev/zero of=/dev/mapper/blockstorage status=progress
- mkfs.ext4 /dev/mapper/blockstorage will create the filesystem on the diskmkdir /mnt/blockstorage to create the mountpoint chown /mnt/blockstorage <UserName>:<UserName> to set ownership to your usersudo mount /dev/mapper/blockstorage /mnt/blockstoragesudo cryptsetup luksOpen /dev/vdb blockstoragesudo cryptsetup luksClose blockstoragesudo umount /mnt/blockstorage- We don't need to deal with these complex commands each time. We can use aliasing to substitute much simpler commands to remember instead. -
-echo "alias mntblk='sudo mount /dev/mapper/blockstorage /mnt/blockstorage' >> .bashrc" will set the mounting command to mntblkecho "alias unlkblk='sudo cryptsetup luksOpen /dev/vdb blockstorage' >> .bashrc" will set the unlocking command to unlkblkecho "alias lkblk='sudo cryptsetup luksClose blockstorage' >> .bashrc" will set the locking command to lkblkecho "alias umntblk='sudo umount /mnt/blockstorage' >> .bashrc" will set the unmounting command to umntblk- This will still need 2 commands to mount, and 2 more to unmount. - I like having these aliased separately just in case I want to run one without the other for some reason. - To bring this to 1 command for each I will make 2 more aliases using the ones I just created. - You could make each of these 2 using the expanded commands above, but I find this way simpler to read. -
-echo "alias m='mntblk && unlkblk' >> .bashrc" will make m mount the system and unlock itecho "alias m-x='lkblk && umntblk' >> .bashrc" will make m-x lock the filesystem and unmount itsource .bashrc
- Ports are not open externally by defaul on Arch.
- sudo ufw 80 will open the port for the web server.
- Do not open unnecessary ports.
- Arch is fully capable of hosting an apache server like is used in the guide.
- I prefer Nginx and so used that.
- The configuration is a little more complex than apache but I am more familiar with it and it works well for single site hosting.
-
sudo pacman -S nginxsudo systemctl enable nginx.servicesudo systemctl start nginx.service- When I was testing I was serving static content from /srv/http/domain.com/public_html. - In the /etc/nginx/nginx.conf file in the http block I added: -
-
- server {:
- server_name yourdomain www.yourdomain
- location / {:
- root /srv/http/yourdomain/public_html
- }
- }
-
-
- Run nginx -s reload to reload the configuration file.
-
- Then the html files to be served can be put in whatever folder specified in root and will be served from there. - In the end I have my website built and served using SvelteKit and Nginx is working as a proxy for that program. - I will go into Svelte in the future. -
-- To have a secure webserver (https) I need a certificate. -
-sudo pacman -S certbot certbot-nginx to install the certbot package and nginx pluginsudo certbot --nginx will scan for nginx sites and create certificatessudo certbot renew will renew all certificates on the machine managed by certbot.- To run this renewal periodically I made certref file in bin containing: -
-
- #!/bin/bash
- sudo certbot renew
-
-
- Set permissions to 700 with sudo chmod 700 bin/certref, then added a cronjob to run the refresh once a month.
-
- Can use exactly what is in the guide here. - Just make sure the files are located in the root you specified in the Nginx configuration above. -
- -- Did not set this up with Nginx yet. - If I do will update this. -
- -
- This is very similar for both Arch and OpenBSD so will list changes
- Arch does not have htpasswd by default.
- Install with sudo pacman -S apache then continue.
-
- I decided to use an external email provider (FastMail) instead of setting up the email verification myself. - This was before the explanation for this was published in this article. - May try again in the future but for now I am happy with my own email for a few dollars a month that I can move to a different provider if needed -
- -- I use git extensively in my coding projects, configurations, and notes so I wanted to be able to host my own git server. -
-sudo supacman -S gitsystemctl enable git-daemon.socketsystemctl start git-daemon.socket
- To make a new project I navigate to /srv/git and make a new project with git -bare init <projectName>.git.
- Set ownership to git user with chown <projectName>.git git:git.
- To set the remote origin for a project that is already initialized git remote add origin git@url:/srv/git/<projectName>
- To clone a project from remote to local git clone git://url/<projectName> localName
-
- This project is slowly but constantly evolving. - The above state is how it is running currently and that may change. - I will endeavor to update it when things do. - Slowly grow from something mostly taken from Derek's guide (thank you so much for that) to something uniquely my own and serving the my exact needs. -
-- This was a project that I did with two classmates for a parallel programming class. - Source code here. - The programming was done in C except for a python script for image pre-processing (it was just much faster to write). -
-- Edge detection is usually done with convolutions. - A convolution is a matrix of values (kernel) that detects the difference in colour density of pixels in an image. - The kernel is overlayed on the pixel values in the image and each pixel value is multiplied by the value in the kernel above it. - All the resulting values are added together into a single value. - The design of the kernel dictates what sort of feature will be detected. - A large resulting value indicates the presence of the desired feature. -
-- This is the sample input image we used for some of the testing. -
-
- - This image has a lot of both horizontal and vertical lines for detection. - The image gets converted into grayscale during preprocessing for ease of use. -
-- We used Sobel Kernels as opposed to designing our own. - These are very commonly used for edge detection. - The larger the dimensions of the kernel the larger an area of the image it inspect. - A smaller kernel will only find very well defined edges. - 3×3 was the smallest kernel that we used. -
-
-
- - These kernels found the very defined edges on the sides of the trees and branches. - This includes their reflections in the water below, though the reflection did dampen the edges a fair bit. -
-
- - As you can see it picked up almost nothing from the sky in the image. - We also tested kernels of size 5×5, 7×7, and 9×9. - Here are the 9×9 kernels we used. -
-
-
- - These large kernels will detect differences in gradient across a much larger portion of the image at once. - This results in a much more textured image. -
-
- - As you can see the trees are almost a uniform mass of edges. - The reflections less so but still very dense. - It did also manage to pick up the texture of the clouds. - Different kernels are good at detecting different types of edges. - A smaller kernel will be much better for sharp edges and will ignore the rest. - A larger kernel will get much less well defined edges. -
-- There is also a large difference in the speed of the program, a larger kernel has significantly more operations that need to be performed. - After the application of the convolutions the rest of the project was parallelizing this process in an effort to speed it up. - We used both Message Passing Interface (MPI) and CUDA for parallelization in order to compare them. - MPI uses the CPU and so is limited by the number of cores the CPU of the device has. - CUDA uses the graphics card so has many more cores to work with but has more overhead. -
-
- - Unless you have access to a large number of CPU cores CUDA is almost always better. - For a general application as long as you have access to a graphics card CUDA is the way to go. -
-- This project was very enlightening as to how the underlying processes for image recognition work. - I have done a little bit of machine learning with convolutional neural networks, but for most libraries this portion is already done for you. - Understanding what is going on under the hood was very interesting. -
-- One of my favourite fantasy book series is the Kingkiller Chronicles by Patrick Rothfuss. - In the second book The Wise Man’s Fear there is a board game that they play that sounded fascinating. - I have always like abstract strategy games and this was his worlds “Chess”; the game that had been around forever, simple rules but deep strategy etc. -
-- I was so excited when I found out that it was being made into a full game by Cheapass Games. - The rules are available for free on their website. - I bought myself a copy and it is a lot of fun. - They did an amazing job getting the feel of the game right and it is now for sale on WorldBuilders Market. - Proceeds from WorldBuilders go to charity so if you try out the game and enjoy it please consider buying a copy. -
-- As a project I made a digital copy of the game. - Source code here. - It is written in python 3 and the only extra library it needs to run is pygame. - If you want to run the tests you will need pytest as well. -
-- Here is the program interface. -
-
- - The game was a very interesting challenge to implement for a few reasons. -
-- The board size is flexible. - It ranges from 3×3 to 8×8 (skipping 7×7 but I am not quite sure why). - The rules for victory are the same regardless of board size but the number of pieces each player has access to changes. - The board had to be housed in a flexible object that would also dictate the number of pieces. -
-- While there are only two types of pieces (regular and capstones), the standard pieces can be played in 2 different orientations. - Flat placement is the default. - It contributes to win conditions and can make stacks. - Placing a normal piece as a wall blocks other pieces but does not contribute to your win condition and can only be at the top of a stack. - The capstone has the best characteristics of both and can squish walls to flat if it lands on them alone. -
-
- - Rather than make an object for each piece I built the piece specific rules into the move action. - The move is the same at its core for each piece and the only difference is the interaction when one piece lands on top of another. - Storing the pieces as integers in a 2d array makes this far simpler. - As the interactions depend on both pieces, using an integer makes that comparison very easy. -
-- The game has an interesting 3 dimensional component. - The pieces can be stacked on top of one another and a stack can move as far as the stack is high (in a straight line controlled by the player whose piece is at the top) dropping one piece at a minimum on each square along the way. - This means that each square in the 2d array needs to contain a stack where new pieces are added to the top. - When pieces are lifted off a stack your hand acts like a second stack. - Pieces are popped off the top of the square and added to the stack in your hand. - Then they are dropped from the “bottom” of this inverted stack as you move. -
-
-
- - The comparison needs to be done from the “bottom” of the inverted stack in your hand to the top of the stack that the piece will land on. -
-- That is the main challenge of the game play. - The victory conditions were also challenging. - The game has 3 different ways that it can end and 2 possible ways to calculate who won. - -
-- The game ends when one player builds a connected line of pieces from one of the sides of the board to the opposite side. - The line does not need to be straight but squares do not connect on the diagonal. - The victor in this case is the player who has the “road”. - If a move creates a road for both players the active player wins. -
-
- - The game also ends if either player runs out of pieces or there are no more open spaces on the board. - In that case the winner is the player with the control of the most squares of the board. -
-- Both of these need to be checked after each turn and when a winner is found the points are calculated based on the size of the board and the number of pieces left. -
-- Compared to Chess or Go, Tak is a little bit more complicated. - This is not through having a significantly large number of rules but the systems intertwine more and are more flexible. - This does not mean that it is a better game just different, but it has a similar feeling of depth and timelessness. -
-- The board being stored as an array of integers means that it takes very little memory. - That made it simple to store past boards in a stack and implement an undo function. - Both to take back moves and even go back to a previous game from the same session. -
-- I am pleased with how the game turned out. - I am working on other things at the moment but in the future I would like to do two more things with this game. - I want to implement it online so that I can play with friends over the internet. - I would also like to try and develop an A.I. - agent to play the game. - I had this in mind when I was writing it so made sure that the GUI was disconnected from the actual mechanics behind the game. - This will hopefully make it easier to connect to an agent for training. -
-