300 lines
8.3 KiB
Rust
300 lines
8.3 KiB
Rust
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
pub struct Author {
|
|
pub id: u8,
|
|
pub image_url: &'static str,
|
|
pub name: &'static str,
|
|
pub keywords: &'static [&'static str],
|
|
pub about: &'static str,
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
|
pub struct Post {
|
|
pub id: u8,
|
|
pub authors: &'static [u8],
|
|
pub title: &'static str,
|
|
pub utcdate: &'static str,
|
|
pub content: &'static str,
|
|
}
|
|
|
|
impl BlogEntry for Author {
|
|
fn from_entry(entry: &mut Entry) -> Self {
|
|
*Self::AUTHORS
|
|
.get(entry.id as usize)
|
|
.cloned()
|
|
.unwrap_or(&Self {
|
|
id: u8::MAX,
|
|
image_url: "",
|
|
name: "not found",
|
|
keywords: [].as_slice(),
|
|
about: "",
|
|
})
|
|
}
|
|
}
|
|
|
|
impl BlogEntry for Post {
|
|
fn from_entry(entry: &mut Entry) -> Self {
|
|
*Self::POSTS
|
|
.get(entry.id as usize)
|
|
.cloned()
|
|
.unwrap_or(&Self {
|
|
id: u8::MAX,
|
|
authors: &[u8::MAX],
|
|
title: "not found",
|
|
utcdate: "1970-01-01",
|
|
content: "",
|
|
})
|
|
}
|
|
}
|
|
|
|
pub struct Entry {
|
|
pub id: u8,
|
|
}
|
|
|
|
impl Entry {
|
|
pub fn from_id(seed: u8) -> Self {
|
|
Self { id: seed }
|
|
}
|
|
}
|
|
pub trait BlogEntry: Sized {
|
|
fn from_entry(entry: &mut Entry) -> Self;
|
|
fn from_id(id: u8) -> Self {
|
|
Self::from_entry(&mut Entry::from_id(id))
|
|
}
|
|
|
|
const AUTHORS: [&'static Author; 2] = [
|
|
&Author {
|
|
id: 0,
|
|
image_url: "profile.avif",
|
|
name: "lia",
|
|
keywords: &[
|
|
"certified catgirl™",
|
|
"software engineer",
|
|
"professional yapper",
|
|
"neurospicy and disabled",
|
|
],
|
|
about: "",
|
|
},
|
|
&Author {
|
|
id: 1,
|
|
image_url: "",
|
|
name: "mreowww",
|
|
keywords: &["meow", "mrrp", "mew"],
|
|
about: "",
|
|
},
|
|
];
|
|
|
|
const POSTS: [&'static Post; 2] = [
|
|
&Post {
|
|
id: 0,
|
|
authors: &[0],
|
|
title: "haj, world!",
|
|
utcdate: "2025-08-24",
|
|
content: r#"
|
|
### my first blogpost
|
|
haj! and welcome to my first blogpost.
|
|
this blogpost won't have that much content.
|
|
fun fact: this post becomes html from markdown :3
|
|
pretty cool, ain't it? we think so too.
|
|
it's for including images, formatted text, code and content much easier.
|
|
i also added a too overcomplicated blog backend that allows authors and posts by u8::MAX, cause why not.
|
|
won't post that much either way, so why bother with higher values.
|
|
nonetheless... have a great day, evening, whatever daytime it's for you rn and stay safe. ♡
|
|
you may take a look at my other blogposts. this one was basically practially just a test.
|
|
"#,
|
|
},
|
|
&Post {
|
|
id: 1,
|
|
authors: &[0],
|
|
title: "sweet little poison",
|
|
utcdate: "2025-08-25",
|
|
content: r#"
|
|
### > setting up iocaine with docker and caddy. ~
|
|
sup, today we're going to give ya a crash course on how to homebrew poison for ai. ^.^
|
|
we'll be utilizing docker for containerization and caddy as a reverse-proxy.
|
|
|
|
#### > preparing docker and files ~
|
|
first, we're going to create a new external network and recreate our file struct.
|
|
in this example we're going to name it "caddy". very creative, i know.
|
|
we achieve this by running following pile of commands:
|
|
```sh
|
|
docker network create caddy && \
|
|
mkdir -p ./caddy/pages/example.com ./iocaine ./socks && \
|
|
touch ./docker-compose.yml ./caddy/proxy ./iocaine/config.toml && \
|
|
touch ./caddy/pages/example.com/index.html && \
|
|
printf '<html><body><h1>hellow body consisting of blood and flesh</h1></body></html>' \
|
|
> ./caddy/pages/example.com/index.html
|
|
```
|
|
|
|
after running that we should be set and ready for the next few steps.
|
|
if you're curious, this is how it should look like right now:
|
|
```sh
|
|
Documents/example » tree .
|
|
.
|
|
├── caddy
|
|
│ ├── pages
|
|
│ │ └── example.com
|
|
│ │ └── index.html
|
|
│ └── proxy
|
|
├── docker-compose.yml
|
|
├── iocaine
|
|
│ └── config.toml
|
|
└── socks
|
|
```
|
|
|
|
#### > downloading data and configuring iocaine ~
|
|
|
|
next things next: we're going to download a robots.json, some markov-chain-stuffies and a words.txt.
|
|
for now, we will be using the default stuff from the official docs cause why not:
|
|
```sh
|
|
curl --proto '=https' --tlsv1.3 \
|
|
-L https://archive.org/download/GeorgeOrwells1984/1984_djvu.txt \
|
|
-o ./iocaine/1984.txt && \
|
|
curl --proto '=https' --tlsv1.3 \
|
|
-L https://archive.org/download/ost-english-brave_new_world_aldous_huxley/Brave_New_World_Aldous_Huxley_djvu.txt \
|
|
-o ./iocaine/brave-new-world.txt && \
|
|
curl --proto '=https' --tlsv1.2 \
|
|
-L https://git.savannah.gnu.org/cgit/miscfiles.git/plain/web2 \
|
|
-o ./iocaine/words.txt && \
|
|
curl --proto '=https' --tlsv1.3 \
|
|
-L https://github.com/ai-robots-txt/ai.robots.txt/raw/refs/heads/main/robots.json \
|
|
-o ./iocaine/robots.json
|
|
```
|
|
|
|
most importantly, we have to scrape nam-shub-of-enki from gergely's git.
|
|
here's a way to curl and extract it automatically in the correct folder:
|
|
```sh
|
|
curl --proto '=https' --tlsv1.3 \
|
|
-L https://git.madhouse-project.org/api/packages/iocaine/generic/nam-shub-of-enki/20250711.0/nam-shub-of-enki-20250711.0.tar.zst \
|
|
-o ./iocaine/nam-shub-of-enki.tar.zst && \
|
|
sudo tar -xvf ./iocaine/nam-shub-of-enki.tar.zst -C ./iocaine
|
|
```
|
|
|
|
now, we're going to prepare our iocaine/config.toml like this:
|
|
```sh
|
|
cat > ./iocaine/config.toml <<'YAML'
|
|
[server]
|
|
bind = "/run/iocaine/waow.socket"
|
|
unix_listen_access = "everybody"
|
|
|
|
[server.control]
|
|
bind = "/run/iocaine/listen.socket"
|
|
unix_listen_access = "owner"
|
|
|
|
[server.request-handler]
|
|
path = "/data"
|
|
language = "roto"
|
|
|
|
[sources]
|
|
words = "/data/words.txt"
|
|
markov = [ "/data/1984.txt", "/data/brave-new-world.txt" ]
|
|
|
|
[metrics]
|
|
enable = false
|
|
YAML
|
|
```
|
|
|
|
#### > cooking up our docker compose file for deployment ~
|
|
|
|
i have fucked around with docker a little while to make this somehow work.
|
|
here's a command which will insert needed content into our docker-compose.yml:
|
|
```sh
|
|
cat > ./docker-compose.yml <<'YAML'
|
|
services:
|
|
caddy:
|
|
image: caddy:alpine
|
|
container_name: proxy.caddy
|
|
hostname: proxy.caddy
|
|
restart: unless-stopped
|
|
cap_add:
|
|
- NET_ADMIN
|
|
ports:
|
|
- "80:80"
|
|
- "443:443"
|
|
- "443:443/udp"
|
|
networks:
|
|
- caddy
|
|
volumes:
|
|
- ./socks:/run/iocaine:ro
|
|
- ./caddy/pages:/var/www/html
|
|
- ./caddy/data:/data
|
|
- ./caddy/config:/config
|
|
- ./caddy/proxy:/etc/caddy/Caddyfile:ro
|
|
depends_on:
|
|
- iocaine
|
|
iocaine:
|
|
image: git.madhouse-project.org/iocaine/iocaine:2
|
|
container_name: proxy.iocaine
|
|
hostname: proxy.iocaine
|
|
restart: unless-stopped
|
|
ports:
|
|
- "127.0.0.1:42069:42069"
|
|
networks:
|
|
- caddy
|
|
volumes:
|
|
- ./socks:/run/iocaine:rw
|
|
- ./iocaine:/data
|
|
environment:
|
|
- IOCAINE__SERVER__BIND="/run/iocaine/waow.socket"
|
|
- IOCAINE__SERVER__UNIX_LISTEN_ACCESS="everybody"
|
|
- IOCAINE__SERVER__REQUEST_HANDLER__PATH="/data"
|
|
- IOCAINE__SERVER__REQUEST_HANDLER__LANGUAGE="roto"
|
|
- IOCAINE__SERVER__CONTROL__BIND="/run/iocaine/listen.socket"
|
|
- IOCAINE__SERVER__CONTROL__UNIX_LISTEN_ACCESS="owner"
|
|
- IOCAINE__SOURCES__WORDS="/data/words.txt"
|
|
- IOCAINE__SOURCES__MARKOV=["/data/1984.txt", "/data/brave-new-world.txt"]
|
|
- IOCAINE__METRICS__ENABLE=false
|
|
- NSOE__AI_ROBOTS_TXT_PATH=/data/robots.json
|
|
command: --config-file /data/config.toml start
|
|
networks:
|
|
caddy:
|
|
external: true
|
|
YAML
|
|
```
|
|
|
|
#### > finishing up with caddy and deploying ~
|
|
our caddyfile needs some love to work.
|
|
here's what i ripped from the official docs:
|
|
```sh
|
|
cat > ./iocaine/proxy <<'TXT'
|
|
(iocaine) {
|
|
@read method GET HEAD
|
|
@not-read not {
|
|
method GET HEAD
|
|
}
|
|
reverse_proxy @read unix//run/iocaine/waow.socket {
|
|
#reverse_proxy @read proxy.iocaine:42069 {
|
|
@fallback status 421
|
|
handle_response @fallback {
|
|
{blocks.handler}
|
|
}
|
|
}
|
|
handle @not-read {
|
|
{blocks.default}
|
|
}
|
|
}
|
|
|
|
example.com {
|
|
import iocaine {
|
|
handler {
|
|
reverse_proxy http://example:8080
|
|
}
|
|
default {
|
|
# this is the behaviour if neither a GET nor HEAD request comes in
|
|
reverse_proxy http://example:8080
|
|
}
|
|
}
|
|
}
|
|
TXT
|
|
```
|
|
now the last thing that's left is a plain and simple:
|
|
`docker compose up -d`
|
|
and we should be good to go!
|
|
|
|
i hope this post made it easier/helped you with setting up iocaine on your own server. ♡
|
|
it's good to have this set up just to fuck around with fucking parisitic generative ai stealing your things.
|
|
gatekeep your stuff from big corpos that are trying to make their business from your experience and skills.
|
|
"#,
|
|
},
|
|
];
|
|
}
|