Compare commits

..

11 Commits

Author SHA1 Message Date
e747f399ef swap out github for git host with selfhosted gitea link 2026-03-28 00:44:33 +01:00
c8f4ed4a1f Merge pull request #2 from gractwo/dependabot/cargo/bytes-1.11.1
Bump bytes from 1.10.1 to 1.11.1
2026-03-27 14:49:04 +01:00
0e23c812e3 Merge pull request #3 from gractwo/dependabot/cargo/time-0.3.47
Bump time from 0.3.41 to 0.3.47
2026-03-27 14:38:53 +01:00
dependabot[bot]
a87c4c1fb6 Bump time from 0.3.41 to 0.3.47
Bumps [time](https://github.com/time-rs/time) from 0.3.41 to 0.3.47.
- [Release notes](https://github.com/time-rs/time/releases)
- [Changelog](https://github.com/time-rs/time/blob/main/CHANGELOG.md)
- [Commits](https://github.com/time-rs/time/compare/v0.3.41...v0.3.47)

---
updated-dependencies:
- dependency-name: time
  dependency-version: 0.3.47
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-27 13:27:36 +00:00
dependabot[bot]
61c251876d Bump bytes from 1.10.1 to 1.11.1
Bumps [bytes](https://github.com/tokio-rs/bytes) from 1.10.1 to 1.11.1.
- [Release notes](https://github.com/tokio-rs/bytes/releases)
- [Changelog](https://github.com/tokio-rs/bytes/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/bytes/compare/v1.10.1...v1.11.1)

---
updated-dependencies:
- dependency-name: bytes
  dependency-version: 1.11.1
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-27 13:25:12 +00:00
07f6327404 discord broke how bot activities look :( 2025-12-03 12:11:10 +01:00
87361d6418 fix binary/artifact-in-docker errors and uncertainties 2025-11-27 17:59:17 +01:00
598bae7377 steal a lucide-style bsky icon 2025-11-26 21:57:45 +01:00
201415c600 dockerfile filepath shenanigans 2025-11-14 18:36:45 +01:00
fb9c946416 bundle assets dir in docker image; compose restart policy 2025-11-14 18:28:20 +01:00
f706cd74a6 dockerize 2025-11-14 16:59:47 +01:00
13 changed files with 197 additions and 61 deletions

26
.dockerignore Normal file
View File

@@ -0,0 +1,26 @@
**/.DS_Store
**/.classpath
**/.dockerignore
**/.env
**/.git
**/.gitignore
**/.project
**/.settings
**/.toolstarget
**/.vs
**/.vscode
**/*.*proj.user
**/*.dbmdl
**/*.jfm
**/charts
**/docker-compose*
**/compose.y*ml
**/Dockerfile*
**/node_modules
**/npm-debug.log
**/secrets.dev.yaml
**/values.dev.yaml
/bin
/target
LICENSE
README.md

1
.gitignore vendored
View File

@@ -1,4 +1,3 @@
/target /target
*.env *.env
.DS_Store .DS_Store
web/styles.css

46
Cargo.lock generated
View File

@@ -257,9 +257,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
[[package]] [[package]]
name = "bytes" name = "bytes"
version = "1.10.1" version = "1.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
[[package]] [[package]]
name = "camino" name = "camino"
@@ -435,12 +435,12 @@ checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476"
[[package]] [[package]]
name = "deranged" name = "deranged"
version = "0.4.0" version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" checksum = "7cd812cc2bc1d69d4764bd80df88b4317eaef9e773c75226407d9bc0876b211c"
dependencies = [ dependencies = [
"powerfmt", "powerfmt",
"serde", "serde_core",
] ]
[[package]] [[package]]
@@ -1162,9 +1162,9 @@ dependencies = [
[[package]] [[package]]
name = "num-conv" name = "num-conv"
version = "0.1.0" version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967"
[[package]] [[package]]
name = "num-traits" name = "num-traits"
@@ -1628,9 +1628,19 @@ dependencies = [
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.219" version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde_core"
version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
dependencies = [ dependencies = [
"serde_derive", "serde_derive",
] ]
@@ -1646,9 +1656,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_derive" name = "serde_derive"
version = "1.0.219" version = "1.0.228"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1942,30 +1952,30 @@ dependencies = [
[[package]] [[package]]
name = "time" name = "time"
version = "0.3.41" version = "0.3.47"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" checksum = "743bd48c283afc0388f9b8827b976905fb217ad9e647fae3a379a9283c4def2c"
dependencies = [ dependencies = [
"deranged", "deranged",
"itoa", "itoa",
"num-conv", "num-conv",
"powerfmt", "powerfmt",
"serde", "serde_core",
"time-core", "time-core",
"time-macros", "time-macros",
] ]
[[package]] [[package]]
name = "time-core" name = "time-core"
version = "0.1.4" version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" checksum = "7694e1cfe791f8d31026952abf09c69ca6f6fa4e1a1229e18988f06a04a12dca"
[[package]] [[package]]
name = "time-macros" name = "time-macros"
version = "0.2.22" version = "0.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" checksum = "2e70e4c5a0e0a8a4823ad65dfe1a6930e4f4d756dcd9dd7939022b5e8c501215"
dependencies = [ dependencies = [
"num-conv", "num-conv",
"time-core", "time-core",

75
Dockerfile Normal file
View File

@@ -0,0 +1,75 @@
ARG RUST_VERSION=1.90.0
ARG APP_NAME=arche
################################################################################
# Create a stage for building the application.
FROM rust:${RUST_VERSION}-alpine AS build
ARG APP_NAME
WORKDIR /app
ENV IN_DOCKER=true
# Install host build dependencies.
RUN apk add --no-cache clang lld musl-dev git
# Build the application.
# Leverage a cache mount to /usr/local/cargo/registry/
# for downloaded dependencies, a cache mount to /usr/local/cargo/git/db
# for git repository dependencies, and a cache mount to /app/target/ for
# compiled dependencies which will speed up subsequent builds.
# Leverage a bind mount to the src directory to avoid having to copy the
# source code into the container. Once built, copy the executable to an
# output directory before the cache mounted /app/target is unmounted.
RUN --mount=type=bind,source=src,target=src \
--mount=type=bind,source=web,target=web \
--mount=type=bind,source=assets,target=assets \
--mount=type=bind,source=askama.toml,target=askama.toml \
--mount=type=bind,source=Cargo.toml,target=Cargo.toml \
--mount=type=bind,source=Cargo.lock,target=Cargo.lock \
--mount=type=cache,target=/app/target/ \
--mount=type=cache,target=/usr/local/cargo/git/db \
--mount=type=cache,target=/usr/local/cargo/registry/ \
cargo build --locked --release && \
cp ./target/release/$APP_NAME /bin/server
################################################################################
# Create a new stage for running the application that contains the minimal
# runtime dependencies for the application. This often uses a different base
# image from the build stage where the necessary files are copied from the build
# stage.
#
# The example below uses the alpine image as the foundation for running the app.
# By specifying the "3.18" tag, it will use version 3.18 of alpine. If
# reproducibility is important, consider using a digest
# (e.g., alpine@sha256:664888ac9cfd28068e062c991ebcff4b4c7307dc8dd4df9e728bedde5c449d91).
FROM alpine:3.18 AS final
# Create a non-privileged user that the app will run under.
# See https://docs.docker.com/go/dockerfile-user-best-practices/
ARG UID=10001
RUN adduser \
--disabled-password \
--gecos "" \
--home "/nonexistent" \
--shell "/sbin/nologin" \
--no-create-home \
--uid "${UID}" \
appuser
RUN mkdir -p /app && chown appuser:appuser /app
USER appuser
WORKDIR /app
ENV IN_DOCKER=true
ENV DISCORD_BOT_TOKEN=""
ENV DISCORD_SERVER_ID=""
# Copy the executable from the "build" stage.
COPY --from=build /bin/server /app/server
COPY ./assets /app/assets
# Expose the port that the application listens on.
EXPOSE 2020
# What the container should run when it is started.
CMD ["/app/server"]

View File

@@ -7,30 +7,30 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("cargo:rerun-if-changed=build.rs"); println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=web"); println!("cargo:rerun-if-changed=web");
let os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_else(|_| String::from("unknown")); if std::env::var("IN_DOCKER").is_err() {
let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_else(|_| String::from("unknown")); let os = env::var("CARGO_CFG_TARGET_OS").unwrap_or_else(|_| String::from("unknown"));
let download_url = match (os.as_str(), arch.as_str()) { let arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap_or_else(|_| String::from("unknown"));
("macos", "aarch64") => { let download_url = match (os.as_str(), arch.as_str()) {
"https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-macos-arm64" ("macos", "aarch64") => {
} "https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-macos-arm64"
("linux", "x86_64") => { }
"https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64" ("linux", "x86_64") => {
} "https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64"
("linux", "aarch64") => { }
"https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-arm64" ("linux", "aarch64") => {
} "https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-arm64"
_ => return Err(format!("Unsupported platform: {} {}", os, arch).into()), }
}; _ => return Err(format!("Unsupported platform: {} {}", os, arch).into()),
};
let out_dir = PathBuf::from(env::var("OUT_DIR")?); let out_dir = PathBuf::from(env::var("OUT_DIR")?);
let tailwind_binary = out_dir.join("tailwind"); let tailwind_binary = out_dir.join("tailwind");
fs::create_dir_all(&out_dir)?; fs::create_dir_all(&out_dir)?;
download_tailwind(&download_url, &tailwind_binary)?; download_tailwind(&download_url, &tailwind_binary)?;
println!("cargo:rustc-env=TAILWIND_BIN={}", tailwind_binary.display());
println!("cargo:rustc-env=TAILWIND_BIN={}", tailwind_binary.display()); run_tailwind(&tailwind_binary)?;
}
run_tailwind(&tailwind_binary)?;
Ok(()) Ok(())
} }

11
compose.yaml Normal file
View File

@@ -0,0 +1,11 @@
services:
server:
build:
context: .
target: final
ports:
- 2020:2020
restart: unless-stopped
environment:
- DISCORD_BOT_TOKEN=${DISCORD_BOT_TOKEN}
- DISCORD_SERVER_ID=${DISCORD_SERVER_ID}

8
readme.txt Normal file
View File

@@ -0,0 +1,8 @@
arche
=====
Regarding /web/styles.css
The styles.css file, which is generated by a standalone Tailwind binary downloaded and executed automatically within build.rs, is to be committed any time it changes, as without it styling will be broken on the frontend part of the page.
This is in contrast to a perhaps expected approach of gitignoring them and just generating them every build; this is incompatible with building docker images in an efficient way, however, as docker exposes no way to mount directories while retaining ability to write files and execute binaries.

View File

@@ -4,23 +4,23 @@ use std::sync::LazyLock;
pub static LIST: LazyLock<Vec<ActivityData>> = LazyLock::new(|| { pub static LIST: LazyLock<Vec<ActivityData>> = LazyLock::new(|| {
use ActivityData as ACT; use ActivityData as ACT;
vec![ vec![
ACT::playing("Team Fortress 2"), ACT::custom("Playing Team Fortress 2"),
ACT::playing("Minecraft"), ACT::custom("Playing Minecraft"),
ACT::playing("PGTF Dating Sim"), ACT::custom("Playing PGTF Dating Sim"),
ACT::playing("Hades"), ACT::custom("Playing Hades"),
ACT::playing("Bloons TD 6"), ACT::custom("Playing Bloons TD 6"),
// // // // // // // // // // // // // // // // // // // // // //
ACT::listening("Lin-Manuel Miranda"), ACT::custom("Listening to Lin-Manuel Miranda"),
ACT::listening("Kendrick Lamar"), ACT::custom("Listening to Kendrick Lamar"),
ACT::listening("Pięć Dwa Dębiec"), ACT::custom("Listening to Pięć Dwa Dębiec"),
ACT::listening("Gimpson"), ACT::custom("Listening to Gimpson"),
// // // // // // // // // // // // // // // // // // // // // //
ACT::watching("Scooby Doo"), ACT::custom("Watching Scooby Doo"),
ACT::watching("Horimiya"), ACT::custom("Watching Horimiya"),
ACT::watching("My Deer Friend Nokotan"), ACT::custom("Watching My Deer Friend Nokotan"),
ACT::watching("Lycoris Recoil"), ACT::custom("Watching Lycoris Recoil"),
ACT::watching("Yuru Camp"), ACT::custom("Watching Yuru Camp"),
ACT::watching("DARLING in the FRANXX"), ACT::custom("Watching DARLING in the FRANXX"),
// // // // // // // // // // // // // // // // // // // // // //
ACT::custom("Formalizuje stowarzyszenie"), ACT::custom("Formalizuje stowarzyszenie"),
ACT::custom("Shipuje członków"), ACT::custom("Shipuje członków"),

View File

@@ -6,7 +6,10 @@ const REDIRECTS: &[(&[&str], &str)] = &[
&["/discord", "/dsc", "/dc"], &["/discord", "/dsc", "/dc"],
"https://discord.gg/NBXq95C" "https://discord.gg/NBXq95C"
),( ),(
&["/github", "/gh"], &["/git", "/gitea", "/git-host"],
"https://git.gractwo.pl"
),(
&["/github"],
"https://github.com/gractwo" "https://github.com/gractwo"
),( ),(
&["/youtube", "/yt"], &["/youtube", "/yt"],

1
web/icons/bsky.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5.704 3.675c2.537 1.88 5.168 5.638 6.202 7.706.94-2.068 3.665-5.826 6.202-7.706 1.785-1.315 4.698-2.443 4.698.94 0 .658-.376 5.544-.563 6.39-.752 2.819-3.571 3.477-6.108 3.1 4.416.752 5.544 3.196 3.1 5.733-4.604 4.698-6.577-1.222-7.141-2.725C12 16.83 12 16.737 12 16.83c0-.094 0 0-.094.282-.47 1.503-2.537 7.423-7.142 2.725-2.443-2.537-1.315-4.98 3.101-5.732-2.537.376-5.356-.282-6.108-3.101-.188-.846-.563-5.732-.563-6.39 0-3.383 2.913-2.255 4.698-.94z"></path></svg>

After

Width:  |  Height:  |  Size: 660 B

1
web/icons/git-fork.svg Normal file
View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-git-fork-icon lucide-git-fork"><circle cx="12" cy="18" r="3"/><circle cx="6" cy="6" r="3"/><circle cx="18" cy="6" r="3"/><path d="M18 9v2c0 .6-.4 1-1 1H7c-.6 0-1-.4-1-1V9"/><path d="M12 12v3"/></svg>

After

Width:  |  Height:  |  Size: 402 B

View File

@@ -35,15 +35,15 @@
class="flex flex-col sm:flex-row gap-2 mt-4 text-neutral-500 dark:text-neutral-400" class="flex flex-col sm:flex-row gap-2 mt-4 text-neutral-500 dark:text-neutral-400"
> >
<a <a
href="/github" href="/git"
class="flex gap-2 px-3 py-1 rounded-full hover:bg-neutral-300 dark:hover:bg-neutral-700 hover:text-black dark:hover:text-white transition" class="flex gap-2 px-3 py-1 rounded-full hover:bg-neutral-300 dark:hover:bg-neutral-700 hover:text-black dark:hover:text-white transition"
><span class="scale-[.75]">{% include "icons/github.svg" %}</span> ><span class="scale-[.75]">{% include "icons/git-fork.svg" %}</span>
GitHub</a Git host</a
> >
<a <a
href="/bsky" href="/bsky"
class="flex gap-2 px-3 py-1 rounded-full hover:bg-neutral-300 dark:hover:bg-neutral-700 hover:text-black dark:hover:text-white transition" class="flex gap-2 px-3 py-1 rounded-full hover:bg-neutral-300 dark:hover:bg-neutral-700 hover:text-black dark:hover:text-white transition"
><span class="scale-[.75]">{% include "icons/twitter.svg" %}</span> ><span class="scale-[.75]">{% include "icons/bsky.svg" %}</span>
Bluesky</a Bluesky</a
> >
<a <a

2
web/styles.css Normal file

File diff suppressed because one or more lines are too long