Compare commits

...
3 Commits
Author SHA1 Message Date
jonas 6707364251 ci: add docker jobs
Build docker images. / build-wordle-solver-image (push) Failing after 12m1s
Build docker images. / build-wordle-solver-web-image (push) Failing after 14m6s
2026-09-08 17:46:03 +02:00
jonas 9b34a045fa build: add docker images 2026-09-08 17:34:07 +02:00
jonas 5ea156c181 build(flake): split into flake modules 2026-09-06 16:39:29 +02:00
13 changed files with 402 additions and 189 deletions
+22
View File
@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -euo pipefail
REGISTRY="${REGISTRY#https://}"
REGISTRY="${REGISTRY#http://}"
REGISTRY="${REGISTRY%/}"
IMAGE="${REGISTRY}/${REPOSITORY}:${TAG}"
echo "Pushing ${IMAGE}"
skopeo copy \
--dest-creds "${USERNAME}:${PASSWORD}" \
"docker-archive:result" \
"docker://${IMAGE}"
if [ "${GITEA_REF_TYPE:-}" = "branch" ] && [ "${GITEA_REF_NAME:-}" = "main" ]; then
skopeo copy \
--dest-creds "${USERNAME}:${PASSWORD}" \
"docker-archive:result" \
"docker://${REGISTRY}/${REPOSITORY}:latest"
fi
+45
View File
@@ -0,0 +1,45 @@
name: Build docker images.
on:
push:
jobs:
build-wordle-solver-image:
runs-on: nixos
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Build wordle-solver image
run: |
nix build .#wordle-solver-docker
- name: Push image
env:
REGISTRY: "${{ gitea.server_url }}"
REPOSITORY: "${{ gitea.repository }}"
USERNAME: "${{ secrets.REGISTRY_USER }}"
PASSWORD: "${{ secrets.REGISTRY_TOKEN }}"
TAG: "${{ gitea.sha }}"
run: .gitea/scripts/push-image.sh
build-wordle-solver-web-image:
runs-on: nixos
steps:
- name: Check out repository code
uses: actions/checkout@v4
- name: Build wordle-solver-web image
run: |
nix build .#wordle-solver-web-docker
- name: Push image
env:
REGISTRY: "${{ gitea.server_url }}"
REPOSITORY: "${{ gitea.repository }}-web"
USERNAME: "${{ secrets.REGISTRY_USER }}"
PASSWORD: "${{ secrets.REGISTRY_TOKEN }}"
TAG: "${{ gitea.sha }}"
run: .gitea/scripts/push-image.sh
+14 -33
View File
@@ -16,7 +16,6 @@
outputs = inputs @ {
flake-parts,
crate2nix,
rust-overlay,
...
}:
@@ -28,33 +27,24 @@
"x86_64-linux"
];
imports = [
./nix/wasm-bindgen.nix
./nix/wordle-solver-docker.nix
./nix/wordle-solver-wasm-pkg.nix
./nix/wordle-solver-wasm.nix
./nix/wordle-solver-web-docker.nix
./nix/wordle-solver-web.nix
./nix/wordle-solver.nix
];
perSystem = {
pkgs,
system,
self',
...
}: let
# Use rust-bin to generate the toolchain from rust-toolchain.toml
rust-toolchain = pkgs.rust-bin.fromRustupToolchainFile ./rust-toolchain.toml;
cross-pkgs = pkgs.pkgsCross.wasm32-unknown-none;
toolchain = pkgs.callPackage ./nix/with-toolchain.nix {
cargo = rust-toolchain;
rustc = rust-toolchain;
};
crossToolchain = cross-pkgs.callPackage ./nix/with-toolchain.nix {
cargo = rust-toolchain;
rustc = rust-toolchain;
};
wasm-bindgen = toolchain.pkgs.callPackage ./nix/wasm-bindgen.nix {};
root-crate = pkgs.callPackage ./nix/root-crate.nix {
cargo = rust-toolchain;
rustc = rust-toolchain;
inherit crate2nix;
};
utils = import ./nix/utils.nix;
rust-toolchain = utils.rust-toolchain pkgs;
in {
# Overlay pkgs with rust-bin
_module.args.pkgs = import inputs.nixpkgs {
@@ -63,22 +53,13 @@
config.allowUnsupportedSystem = true;
};
packages = {
wordle-solver-web = pkgs.callPackage ./nix/wordle-solver-web.nix {inherit (self'.packages) wordle-solver-wasm-pkg;};
wordle-solver-wasm = crossToolchain.pkgs.callPackage ./nix/wordle-solver-wasm.nix {};
wordle-solver-wasm-pkg = pkgs.callPackage ./nix/wordle-solver-wasm-pkg.nix {
inherit wasm-bindgen root-crate;
inherit (self'.packages) wordle-solver-wasm;
};
wordle-solver = root-crate.build;
default = self'.packages.wordle-solver;
};
packages.default = self'.packages.wordle-solver;
devShells.default = pkgs.mkShell {
RA_LOG = "rust_analyzer=info";
buildInputs = [
rust-toolchain
wasm-bindgen
self'.packages.wasm-bindgen
pkgs.nodejs
pkgs.svelte-language-server
pkgs.typescript-language-server
-23
View File
@@ -1,23 +0,0 @@
{
crate2nix,
rustc,
cargo,
pkgs,
...
}: let
buildRustCrateForPkgs = _:
pkgs.buildRustCrate.override {
inherit cargo rustc;
};
# Cargo.nix for IFD
generatedCargoNix = crate2nix.tools.${pkgs.hostPlatform.system}.generatedCargoNix {
name = "rustnix";
src = ../.;
};
cargoNix = import generatedCargoNix {
inherit pkgs buildRustCrateForPkgs;
};
in
cargoNix.rootCrate
+21
View File
@@ -0,0 +1,21 @@
rec {
rust-toolchain = pkgs: pkgs.rust-bin.fromRustupToolchainFile ../rust-toolchain.toml;
toolchain-pkgs = pkgs:
pkgs.extend (_: _: {
rustPlatform = pkgs.makeRustPlatform {
cargo = rust-toolchain pkgs;
rustc = rust-toolchain pkgs;
};
});
toolchain-crosspkgs = pkgs: let
crossPkgs = pkgs.pkgsCross.wasm32-unknown-none;
in
crossPkgs.extend (_: _: {
rustPlatform = crossPkgs.makeRustPlatform {
cargo = rust-toolchain pkgs;
rustc = rust-toolchain pkgs;
};
});
}
+9 -1
View File
@@ -1,4 +1,5 @@
{
let
drv = {
fetchCrate,
buildWasmBindgenCli,
rustPlatform,
@@ -16,4 +17,11 @@ buildWasmBindgenCli rec {
inherit (src) pname version;
hash = "sha256-FTv2GZIAQs0ePdIZXIXil7JbZ6kIT05VG6vqC1qNFxQ=";
};
};
utils = import ./utils.nix;
in {
perSystem = {pkgs, ...}: {
packages.wasm-bindgen = (utils.toolchain-pkgs pkgs).callPackage drv {};
};
}
-16
View File
@@ -1,16 +0,0 @@
{
makeRustPlatform,
cargo,
rustc,
pkgs,
...
}: let
p = pkgs;
in rec {
rustPlatform = makeRustPlatform {
inherit cargo rustc;
};
pkgs = p.extend (_: _: {
inherit rustPlatform;
});
}
+39
View File
@@ -0,0 +1,39 @@
let
drv = {
buildEnv,
dockerTools,
wordle-solver,
runCommand,
...
}:
dockerTools.buildImage {
name = "wordle-solver";
created = "now";
copyToRoot = buildEnv {
name = "image-root";
paths = [
wordle-solver
(runCommand "wordle-data" {} ''
mkdir -p $out/pwd
cp ${../valid-words.txt} $out/pwd/valid-words.txt
cp ${../answers.txt} $out/pwd/answers.txt
'')
];
pathsToLink = ["/bin" "/pwd"];
};
config = {
Cmd = ["/bin/wordle-solver"];
WorkingDir = "/pwd";
};
};
in {
perSystem = {
pkgs,
self',
...
}: {
packages.wordle-solver-docker = pkgs.callPackage drv {
inherit (self'.packages) wordle-solver;
};
};
}
+13 -2
View File
@@ -1,8 +1,13 @@
{
perSystem = {
pkgs,
self',
...
}: let
drv = {
stdenvNoCC,
wasm-bindgen,
wordle-solver-wasm,
root-crate,
...
}: let
snake_name = "wordle_solver";
@@ -10,7 +15,7 @@
name = "wordle-solver";
type = "module";
description = "module";
version = root-crate.build.crateVersion;
version = "0.1.0";
files = [
"${snake_name}_bg.wasm"
"${snake_name}.js"
@@ -36,4 +41,10 @@ in
${package-json}
EOF
'';
};
in {
packages.wordle-solver-wasm-pkg = pkgs.callPackage drv {
inherit (self'.packages) wordle-solver-wasm wasm-bindgen;
};
};
}
+20 -3
View File
@@ -1,8 +1,14 @@
{
perSystem = {pkgs, ...}: let
utils = import ./utils.nix;
rust-toolchain = utils.rust-toolchain pkgs;
toolchain-crosspkgs = utils.toolchain-crosspkgs pkgs;
drv = {
rustPlatform,
buildPackages,
lld,
name ? "wordle-solver",
removeReferencesTo,
...
}:
rustPlatform.buildRustPackage {
@@ -19,6 +25,7 @@ rustPlatform.buildRustPackage {
buildPackages.stdenv.cc
lld # Needed for wasm-ld
];
nativeBuildInputs = [removeReferencesTo];
cargoBuildFlags = [
"--lib"
@@ -27,13 +34,23 @@ rustPlatform.buildRustPackage {
];
# Configure rustc for WASM
env = {
RUSTFLAGS = ''--cfg=web_sys_unstable_apis -C linker=wasm-ld'';
};
RUSTFLAGS = ''--cfg=web_sys_unstable_apis -C linker=wasm-ld -C strip=debuginfo -C debuginfo=0'';
# Copy the WASM file to the output
installPhase = ''
mkdir -p $out/lib
cp target/wasm32-unknown-unknown/release/*.wasm $out/lib/
runHook postInstall
'';
# Remove toolchain from closure (store paths are debug artifacts)
postInstall = ''
remove-references-to -t ${rust-toolchain} $out/lib/*.wasm
'';
};
in {
packages.toolchain = rust-toolchain;
packages.wordle-solver-wasm = toolchain-crosspkgs.callPackage drv {};
};
}
+69
View File
@@ -0,0 +1,69 @@
let
drv = {
buildEnv,
dockerTools,
fakeNss,
nginx,
runCommand,
wordle-solver-web,
writeShellScriptBin,
...
}:
dockerTools.buildImage {
name = "wordle-solver-web";
created = "now";
copyToRoot = buildEnv {
name = "image-root";
paths = [
nginx
(fakeNss.override {
extraGroupLines = [
"nogroup:x:65534:"
];
})
(writeShellScriptBin "start" ''
echo "Start serving worlde-solver at port 80..."
/bin/nginx -c /etc/nginx.conf
'')
(runCommand "nginx-conf" {} ''
mkdir -p $out/etc
cat <<EOF > $out/etc/nginx.conf
events {}
error_log /dev/stderr;
http {
include ${nginx}/conf/mime.types;
server {
listen 80;
root ${wordle-solver-web};
access_log /dev/stdout;
}
}
daemon off;
EOF
'')
];
pathsToLink = ["/bin" "/etc"];
};
runAsRoot = ''
mkdir -p /var/log/nginx
'';
config = {
Cmd = ["/bin/start"];
};
};
in {
perSystem = {
pkgs,
self',
...
}: {
packages.wordle-solver-web-docker = pkgs.callPackage drv {
inherit (self'.packages) wordle-solver-web;
};
};
}
+13 -1
View File
@@ -1,4 +1,10 @@
{
perSystem = {
pkgs,
self',
...
}: let
drv = {
stdenv,
fetchYarnDeps,
yarnConfigHook,
@@ -34,4 +40,10 @@ stdenv.mkDerivation (finalAttrs: {
# Needed for executing package.json scripts
nodejs
];
})
});
in {
packages.wordle-solver-web = pkgs.callPackage drv {
inherit (self'.packages) wordle-solver-wasm-pkg;
};
};
}
+27
View File
@@ -0,0 +1,27 @@
{inputs, ...}: {
perSystem = {pkgs, ...}: let
# Cargo.nix for IFD
generatedCargoNix = inputs.crate2nix.tools.${pkgs.hostPlatform.system}.generatedCargoNix {
name = "rustnix";
src = ../.;
};
utils = import ./utils.nix;
rust-toolchain = utils.rust-toolchain pkgs;
toolchain-pkgs = utils.toolchain-pkgs pkgs;
buildRustCrateForPkgs = _:
pkgs.buildRustCrate.override {
cargo = rust-toolchain;
rustc = rust-toolchain;
};
cargoNix = import generatedCargoNix {
pkgs = toolchain-pkgs;
inherit buildRustCrateForPkgs;
};
in {
packages.wordle-solver = cargoNix.rootCrate.build;
};
}