Compare commits
38 Commits
6b94076d04
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| fb23b004ce | |||
| ce0edf6060 | |||
| 53b19fdd9b | |||
| 463553e347 | |||
| 9b4b5193c6 | |||
| da0726f22f | |||
| 83e6dc7ccc | |||
| 96c1840d31 | |||
| 3e0850fc99 | |||
| 06c4c9f5f7 | |||
| 7f3b1f08e3 | |||
| d67456b9d7 | |||
| 47b8acf976 | |||
| 55f7315816 | |||
| d6ef911f20 | |||
| 000661ef3d | |||
| 94c07109ce | |||
| 970a249775 | |||
| ecfd1b0e8d | |||
| 35257bb6e0 | |||
| 62348a5571 | |||
| 2d14dd2b93 | |||
| 1ec966a9a1 | |||
| 99e391fe91 | |||
| 84d1e3e9c7 | |||
| 3a44e7c4cd | |||
| eb5cc3c3b0 | |||
| f9d268b3e5 | |||
| ca37894e8b | |||
| e04f0a3712 | |||
| 2e01a32802 | |||
| 51e2e1eea4 | |||
| 351dfc2734 | |||
| 36a4af39f7 | |||
| ea1ee244e2 | |||
| 18023732d4 | |||
| 7251f68b6f | |||
| 94b6609ea4 |
@@ -1,4 +1,4 @@
|
||||
name: Build and Test
|
||||
name: Build
|
||||
|
||||
on:
|
||||
push:
|
||||
@@ -8,18 +8,21 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: production-runner
|
||||
runs-on: self-hosted
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Kill existing process
|
||||
run: |
|
||||
pkill site || true
|
||||
|
||||
- name: Pull
|
||||
working-directory: /opt/site
|
||||
run: git pull origin main
|
||||
|
||||
- name: Build
|
||||
working-directory: /opt/site
|
||||
run: cargo build --release
|
||||
|
||||
- name: Start Application
|
||||
- name: Restart site
|
||||
working-directory: /opt/site
|
||||
run: |
|
||||
nohup ./target/release/site > server.log 2>&1 &
|
||||
pkill site || true
|
||||
export RUNNER_TRACKING_ID=self-managed
|
||||
nohup ./target/release/site > server.log 2>&1 &
|
||||
sleep 1
|
||||
pgrep site && echo "Site is running!"
|
||||
|
||||
19
src/main.rs
19
src/main.rs
@@ -27,28 +27,28 @@ fn load_posts() -> Result<HashMap<String, Post>, Error> {
|
||||
let typst = fs::read_to_string(typst_path).expect("Failed reading post");
|
||||
let title = re_title.captures(&typst)
|
||||
.expect(format!("Post title not found in {}", dir_path.to_str().unwrap()).as_str())
|
||||
.get(1).unwrap().as_str().trim().to_string() ;
|
||||
println!("{}", title);
|
||||
.get(1).unwrap().as_str().trim().to_string();
|
||||
let slug = re_slug.captures(&typst)
|
||||
.expect("Post slug not found")
|
||||
.get(1).unwrap().as_str().trim().to_string();
|
||||
let summary = re_summary.captures(&typst)
|
||||
.expect("Post summary not found")
|
||||
.get(1).unwrap().as_str().trim().to_string();
|
||||
let img_path = dir?.path().join(
|
||||
let img_path = "/".to_string() + dir?.path().join(
|
||||
re_img.captures(&typst)
|
||||
.expect("Post preview image not found")
|
||||
.get(1).unwrap().as_str().trim().to_string()
|
||||
).to_str().expect("Failed converting path to string").to_string();
|
||||
).to_str().expect("Failed converting path to string");
|
||||
posts.insert(
|
||||
slug.clone(),
|
||||
Post {
|
||||
slug: slug,
|
||||
title: title,
|
||||
preview_image: img_path,
|
||||
preview_image: img_path.clone(),
|
||||
summary: summary,
|
||||
render: Html(PostTemplate {
|
||||
content: typst_to_html(typst),
|
||||
image: img_path
|
||||
}.render().expect("Failed rendering post")),
|
||||
}
|
||||
);
|
||||
@@ -59,6 +59,7 @@ fn load_posts() -> Result<HashMap<String, Post>, Error> {
|
||||
#[derive(Template)]
|
||||
#[template(path = "post.html")]
|
||||
struct PostTemplate {
|
||||
image: String,
|
||||
content: String,
|
||||
}
|
||||
|
||||
@@ -68,8 +69,8 @@ struct Post {
|
||||
title: String,
|
||||
preview_image: String,
|
||||
summary: String,
|
||||
slug: String,
|
||||
render: Html<String>
|
||||
render: Html<String>,
|
||||
slug: String
|
||||
}
|
||||
|
||||
|
||||
@@ -138,7 +139,7 @@ async fn main() {
|
||||
.route("/posts/{slug}", get(|slug| get_post(slug, posts)))
|
||||
.nest_service("/static", ServeDir::new("static"));
|
||||
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
|
||||
println!("Running on http://127.0.0.1:3000");
|
||||
let listener = tokio::net::TcpListener::bind("0.0.0.0:42069").await.unwrap();
|
||||
println!("Running on http://127.0.0.1:42069");
|
||||
axum::serve(listener, site).await.unwrap();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
= About me
|
||||
I enjoy competeing in capture the flag competitions (cybersecurity and the backyard game), working with robotics, automating tasks and thinking about problems.
|
||||
I enjoy competeing in capture the flag competitions (cybersecurity and the backyard game), working with robotics, automating tasks and thinking through problems.
|
||||
|
||||
I've competed in a few hackathons which are cool, but I prefer spending large time frames incrementally understand solutions to much larger problems, and attempting solutions to those.
|
||||
|
||||
@@ -7,7 +7,7 @@ I think automation is one of the most powerful abilities we have. As a species w
|
||||
|
||||
An odd and maybe abstract thing I enjoy is design philosphy. Some examples are creating software to building moral structures through logic to methods of learning new skills.
|
||||
|
||||
NixOS has to be my favourite distribution of Linux. My attraction to its design philosphy is that if something works, it will always work anywhere, and can still be worked on long after everything around it has moved on. Its hard to put into words but this feels like debian level stability with arch-like freedom to explore software.
|
||||
NixOS has to be my favourite distribution of Linux. My attraction to its design philosophy is that if something works, it will always work anywhere, and can still be worked on long after everything around it has moved on. Its hard to put into words but this feels like debian level stability with arch-like freedom to explore software.
|
||||
|
||||
When I'm not nerding out on math, software, ethics, and optimal ways of learning things, I manage to get outdoors. I like mountain biking through trails, snowboarding, hiking through scenic areas, swimming, and basketball. The next thing I'll be getting into is likely SCUBA diving.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#let post_slug = "building-a-drone"
|
||||
#let post_preview_image = "top.jpg"
|
||||
#let post_summary = "Using a raspberry pi and 3d printer to build a drone from scratch"
|
||||
#let post_summary = "Arduino & Pi powered 3D printed drone"
|
||||
|
||||
= Building a Drone
|
||||
|
||||
@@ -21,7 +21,6 @@ wires. I went with the Elegoo Neptune 3 as the printer was open-source
|
||||
and had a much better cost-to-utility than proprietary printers such as
|
||||
the Ender series. I am not sponsored I just really like the printer.
|
||||
|
||||
|
||||
The flight computer was the most difficult part to program. Using an
|
||||
ultrasonic distance sensor, gyroscope, and accelerometer the drone has
|
||||
enough information to probably never crash. The autopilot is implemented
|
||||
@@ -35,6 +34,9 @@ Pi Pico. There is also a 2.4GHz line of sight receiver for manual control.
|
||||
A future upgrade may contain a SIM card for near-infinite remote control
|
||||
connection, but drone regulations would make this difficult.
|
||||
|
||||
#image("/static/posts/drone/graphing.jpg")
|
||||
Testing the remote controller
|
||||
|
||||
The power system is the most physically challenging portion of the
|
||||
drone. The motors took 14.6 Volts, while the UNO microcontroller took 5
|
||||
Volts, and the Pico and most sensors run at 3.3 Volts. All of the power
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#let post_slug = "gamedev"
|
||||
#let post_preview_image = "flying.webp"
|
||||
#let post_summary = "Creating an open world multiplayer terrain destruction game in Godot and Rust"
|
||||
#let post_summary = "Coding an open world multiplayer terrain destruction game in Godot and Rust"
|
||||
|
||||
= Game Development
|
||||
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
#let post_slug = "selfhosting-nextcloud"
|
||||
#let post_preview_image = "logo.svg"
|
||||
#let post_summary = "Why and how I host a fileserver locally, on an old laptop"
|
||||
#let post_summary = "Selfhosting a file server on an old laptop"
|
||||
|
||||
= Selfhosting Nextcloud
|
||||
Access it #link("nextcloud.jeremyjanella.com")[here]. Obviously you'd need a username and password first, good luck getting that!
|
||||
#link("https://nextcloud.jeremyjanella.com")[My Nextcloud]
|
||||
|
||||
=== Why I selfhost Nextcloud
|
||||
== Why I selfhost Nextcloud
|
||||
I'm a constantly-commuting university student. I primarily work on my desktop, take notes and attend lectures and events with my laptop, and review, access, and share documents from my phone. I need the same files to be accessible on all devices at all times.
|
||||
|
||||
Nextcloud is a self-hosted, batteries included file server primarily. It also has a working office suite for editing documents on the cloud through your browser, and numerous other extensions.
|
||||
|
||||
Mega, Google Drive, and OneDrive all do this. Why would I bother using nextcloud? Isn't that reinventing the wheel? Yes and no.
|
||||
|
||||
===== Do tech giants respect privacy? Nextcloud does.
|
||||
=== Do tech giants respect privacy? Nextcloud does.
|
||||
With remotely managed cloud providers, you're trusting large corporations not to look at your data. You are, for free, letting profit-driven entities, to store your data. Of course they could claim to be implementing end-to-end encryption, or that the free tier is a trail of their paid subscription services. As far as I know none of this is open source either, so you're just trusting big-data to hold your data for free without looking at your data. I just don't trust them not to look at my assignments I guess.
|
||||
|
||||
I'm not a fan of subscription services. If I can at moderate difficulty not depend on a corporation to keep their subscription prices sane, I will. I'm not sure how much I save by selfhosting nextcloud, but I also have the piece of mind that that price will never change (excluding buying additional drives or electricity price fluctuations).
|
||||
|
||||
|
||||
=== How I selfhost Nextcloud
|
||||
== How I selfhost Nextcloud
|
||||
|
||||
===== Network and server configurations
|
||||
I already had an old laptop kicking around, a domain name, and reverse proxy on a static IP. A domain name isn't even really nessecary, unless you want a polished experience.
|
||||
=== Network and server configurations
|
||||
I already had an old laptop kicking around, a domain name, and reverse proxy on a static IP. A domain name isn't even really necessary, unless you want a polished experience.
|
||||
|
||||
My laptop already runs linux with docker installed, which would only take a few hours to set up otherwise.
|
||||
From there I used docker compose to start the #link("https://github.com/nextcloud/all-in-one")[nextcloud all in one].
|
||||
@@ -29,7 +29,7 @@ From there I used docker compose to start the #link("https://github.com/nextclou
|
||||
On my reverse proxy I pointed the `nextcloud` subnet at my home IP in its Caddy file. Caddy is a lot like NGINX except its easier to set up for my use case. My IP doesn't change enough to warrent setting up DDNS, however thats always an option. After the ports are opened the hard part is opening the firewall. The reason this is hard is because I always forget the firewall and spend a solid chunk of time debugging why nothing works. In the end, if nothing is working, tools like `traceroute`, `dig` and `ping` are varying degrees of useful for testing accessibility.
|
||||
|
||||
|
||||
===== Can I get five nines?
|
||||
=== Can I get five nines?
|
||||
No. 99.999% uptime won't happen. Power and network outages happen. Roommates unplug your server or brick the router or close your network ports. The thing is that when these things happen, I still have my files on any device. They just stop syncing temporarily, to resume and correct conflicts when the network is back up.
|
||||
|
||||
With recent cloud outages in mind, I want it to be my own fault if I can't access my files. If tech giants side against Canada in some idiocratic war, I don't want to lose data. I don't care enough to implement RAID (yet), but if the server dies or the drive does get corrupted, I can reach into my server drawr, take out the drive, and load up ddrescue on my desktop. Also, the files are already syncing to atleast 3 other devices, data loss doesn't scare me. (Knocks on wood)
|
||||
@@ -1,6 +1,6 @@
|
||||
#let post_slug = "assembly-game"
|
||||
#let post_preview_image = "phobos.png"
|
||||
#let post_summary = "Making a rocket platformer in assembly"
|
||||
#let post_summary = "Coding a game in raw assembly"
|
||||
|
||||
= Phobos
|
||||
|
||||
|
||||
@@ -111,14 +111,21 @@ a {
|
||||
.content {
|
||||
width: 90%;
|
||||
display: inline-block;
|
||||
margin-top: 3.5rem;
|
||||
}
|
||||
|
||||
.content p {
|
||||
.post a {
|
||||
text-decoration: underline;
|
||||
color:orangered;
|
||||
}
|
||||
|
||||
.post * {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.content li {
|
||||
text-align: left;
|
||||
.top-image {
|
||||
max-height: 40vh;
|
||||
max-width: 1000px;
|
||||
}
|
||||
|
||||
nav ul {
|
||||
@@ -141,8 +148,8 @@ nav ul {
|
||||
}
|
||||
|
||||
#name {
|
||||
font-size: 5rem;
|
||||
margin: 20px;
|
||||
font-size: clamp(3.5rem, 12vw , 5rem);
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
animation: nameShadow 5s linear infinite;
|
||||
letter-spacing: 2px;
|
||||
@@ -152,6 +159,7 @@ nav ul {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
body {
|
||||
min-height: 100vh;
|
||||
background-image: linear-gradient(330deg, #222, #040404);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
<div style="padding-top: 3rem" class="content">
|
||||
<div class="content">
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
|
||||
<p id="name">Jeremy Janella</p>
|
||||
|
||||
{{ content|safe }}
|
||||
|
||||
<div class="post">
|
||||
{{ content|safe }}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
|
||||
{% block body %}
|
||||
|
||||
{{ content|safe }}
|
||||
<div class="post">
|
||||
<img src="{{ image }}" class="top-image">
|
||||
{{ content|safe }}
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
Reference in New Issue
Block a user