How to set up your portfolio website with exactly my setup

Maxim has been pestering me to write blog content and so I thought writing this would be tactical in case I ever have to nuke my setup again.


Intro

So last year I was trying to install a cockatrice (mtg tabletop sim) server on my webserver hosted with digitalocean and I managed to blunder the operating system install to such epic proportions it was actually easier to just stop paying for that server and get a new one that was cheaper anyway.

I got the new one with hetzner and I realised that I couldn't remember anything about setting up the webserver again. Maxim has been pestering me to write blog content and so I thought writing this would be tactical in case I ever have to nuke my setup again.


NGINX

I will probably pass over buying a domain and pointing it at the server in detail because it is relatively trivial. I believe I used a digitalocean guide for setting up nginx on Ubuntu (which is what my server is) and so you will obviously need to do:

sudo apt install nginx
sudo ufw allow "Nginx Full" # to open up port 80 and port 430 for web traffic

Helpfully the install automatically sets nginx up as a service and runs it in the background, and it should start up immediately on computer startup too. If you are doing classic static website making you will need to set up a folder for the content. I think by default nginx serves /var/www/html but if you have multiple sites you'll want to set up a folder for each. My folder at /var/www/barold.dev/html only contains one folder called "uploads" which serves up some files publicly.

You will now also need to add a config file to your /etc/nginx/sites-available/ folder. Mine is somewhat cursed due to my setup so I will post the default one from the digitalocean tutorial for now.

server {
    listen 80;
    listen [::]:80;

    root /var/www/your_domain/html;
    index index.html index.htm index.nginx-debian.html;

    server_name your_domain www.your_domain;

    location / {
        try_files $uri $uri/ =404;
    }
}

Then you need to enable it by setting up a link to it from the sites-enabled directory. This I think is because nginx tracks what sites are enabled from that folder. Using a symlink lets you edit the config and update both files, but if you remove it from sites-enabled to disable the site you still have the config available.

sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

So once that's done you can probably start making the actual website.


PORTFOLIO

So I went to an arts college and they were big on portfolios there, mostly using website builders like wix or the adobe one I can't remember the name of. Since I wanted to go to uni for computer science I figured making my own website would be a trivial way to flex my programming prowess and show them I didn't need "real" A levels to be academic (it wasn't). It used to look completely garbage back in the 2018ish era (raw html and css written in nano) but in the current iteration it only looks slightly garbage, a significant improvement. This is primarily due to an increase in my understanding of colour and layout (don't choose bad ones).

This current site was made in React.js. It was still fairly homemade css but I use react-bootstrap to do the structure of it to make laying out the actual elements a bit easier. They also have cool and good functionality like buttons and cards and carousels that I have made use of. I only used react initially so I could use routing to stop the pages reloading fully white when you followed links but it did mean I had more options for easy customising too.

I was then told the use of javascript was breaking a friend's anti-javascript extension. I can't remember if there was another reason for it but mostly because of this I swapped to next.js - a server-side rendering react library. This wasn't particularly difficult and I can't remember what the differences are between it and regular react in terms of actually developing - maybe the pages system? But it's all still components really. The structure of the website is essentially the same as the tutorial.

npx create-next-app@latest
npm run dev

When actually deploying it you do:

npm run build
npm start

Also edit package.json so that the start script has the port that you want - it might be 3000 by default but you can just set it yourself.

"scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start -p 3001",
    "lint": "next lint"
}

NGINX AGAIN

Ok so now that you are running your website with npm run start you now want to be able to see it from your domain. If you do a regular react website you can just build it and put it in your /var/www/domain/html but if you are using next.js you'll need to use Proxy Passes.

Go back to your sites-available config file and make it look like this instead:

server {
    root /var/www/barold.dev/html;

    server_name barold.dev;

    location /uploads {

    }

    location / {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;

        }
}

This means any traffic to http://barold.dev is actually routed to the internally running site shown on port 3001. This means port 3001 doesn't need to be allowed through the firewall or anything either. Catching the "uploads" location means that any files on that path are served as normal. You can catch other paths or patterns to change the behaviour too, which helps if you have multiple apps running on the domain and don't want to figure out subdomains.

The example nginx file was a bit misleading because my website doesn't actually listen on port 80 as the domain can only handle https requests. Luckily getting your own ssl is diabolically simple thanks to certbot.

Install it using sudo apt install certbot python3-certbot-nginx. There is a non-zero chance this isn't how I installed it (I might have used pip?) and their website also says to use snap. But basically install it in some fashion.

When you run certbot it will show you something like this:

Saving debug log to /var/log/letsencrypt/letsencrypt.log

Which names would you like to activate HTTPS for?
We recommend selecting either all domains, or all domains in a VirtualHost/server block.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: barold.dev
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):

Follow the instructions and you will magically have ssl enabled. Some things complain when you have a self-signed ssl certificate and says its untrustworthy but you're not here to run enterprise level services so I don't think it matters. A similar process is used to renew the certificates which expire after 90 days.


OUTRO

Ok this has been a good talk thanks for coming. Hopefully next time I blow up my server the fallout won't require me to figure out how to do all this a second time anyway, but if it does I now have documentation availabile for the recovery.