-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
346 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -36,3 +36,5 @@ yarn-error.log* | |
|
||
.idea | ||
.vscode/ | ||
|
||
result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ lib | ||
, buildGoModule | ||
}: | ||
|
||
buildGoModule rec { | ||
pname = "exam-poll-backend"; | ||
version = "0.0.0"; | ||
|
||
src = ./.; | ||
|
||
vendorHash = "sha256-1QmLYg+1GQwqexz1eFzsWt+H9t1CCN7fMialc07UWrg="; | ||
|
||
postInstall = '' | ||
mv $out/bin/exam-poll{,-backend} | ||
''; | ||
|
||
meta = { | ||
license = lib.licenses.gpl3Plus; | ||
maintainers = with lib.maintainers; [ fugi ]; | ||
mainProgram = pname; | ||
}; | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
{ | ||
inputs = { | ||
nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; | ||
flake-utils.url = "github:numtide/flake-utils"; | ||
}; | ||
|
||
outputs = { self, nixpkgs, flake-utils }: | ||
(flake-utils.lib.eachDefaultSystem (system: | ||
let pkgs = nixpkgs.legacyPackages.${system}; | ||
in { | ||
packages = { | ||
exam-poll-frontend = pkgs.callPackage ./frontend { }; | ||
exam-poll-backend = pkgs.callPackage ./backend { }; | ||
}; | ||
|
||
formatter = pkgs.nixpkgs-fmt; | ||
}) | ||
) // { | ||
overlays.default = (_: prev: { | ||
inherit (self.packages.${prev.system}) | ||
exam-poll-frontend exam-poll-backend; | ||
}); | ||
|
||
nixosModules.default = { | ||
imports = [ ./module.nix ]; | ||
|
||
nixpkgs.overlays = [ self.overlays.default ]; | ||
}; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
{ lib | ||
, fetchYarnDeps | ||
, mkYarnPackage | ||
, nodejs | ||
, makeWrapper | ||
, localApiBaseUrl ? null | ||
, publicApiBaseUrl ? null | ||
}: | ||
|
||
mkYarnPackage rec { | ||
pname = "exam-poll-frontend"; | ||
version = "0.1.0"; | ||
src = ./.; | ||
|
||
yarnLock = ./yarn.lock; | ||
packageJSON = ./package.json; | ||
|
||
offlineCache = fetchYarnDeps { | ||
inherit yarnLock; | ||
hash = "sha256-qyo62/Apld/JslCshF6iSwegbfBl41zpYHabj5/0ARs="; | ||
}; | ||
|
||
NODE_ENV = "production"; | ||
API_BASEURL = localApiBaseUrl; | ||
NEXT_PUBLIC_API_BASEURL = publicApiBaseUrl; | ||
|
||
nativeBuildInputs = [ makeWrapper ]; | ||
|
||
configurePhase = '' | ||
runHook preConfigure | ||
ln -s $node_modules node_modules | ||
runHook postConfigure | ||
''; | ||
|
||
buildPhase = '' | ||
runHook preBuild | ||
export HOME=$(mktemp -d) | ||
# pipe to cat to disable fancy progress indicators cluttering the log | ||
yarn --offline run build | cat | ||
runHook postBuild | ||
''; | ||
|
||
installPhase = '' | ||
runHook preInstall | ||
export OUT_LIBEXEC="$out/libexec/${pname}" | ||
mkdir -p $out $OUT_LIBEXEC | ||
# copy compiled files | ||
cp -r .next/standalone/. $OUT_LIBEXEC | ||
# copy static files too | ||
cp -r .next/static $OUT_LIBEXEC/.next/static | ||
cp -r public $OUT_LIBEXEC/public | ||
# server wrapper | ||
makeWrapper '${nodejs}/bin/node' "$out/bin/${pname}" \ | ||
--add-flags "$OUT_LIBEXEC/server.js" | ||
runHook postInstall | ||
''; | ||
|
||
dontFixup = true; | ||
doDist = false; | ||
|
||
meta = { | ||
license = lib.licenses.gpl3Plus; | ||
maintainers = with lib.maintainers; [ fugi ]; | ||
mainProgram = pname; | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,158 @@ | ||
{ config, lib, pkgs, ... }: | ||
let | ||
cfg = config.services.exam-poll; | ||
|
||
mkService = service: lib.mkMerge [ | ||
{ | ||
after = [ "network.target" ]; | ||
wantedBy = [ "multi-user.target" ]; | ||
serviceConfig = { | ||
Type = "exec"; | ||
Restart = "on-failure"; | ||
DynamicUser = true; | ||
UMask = "0077"; | ||
WorkingDirectory = /tmp; | ||
# Hardening | ||
CapabilityBoundingSet = [ "" ]; | ||
DeviceAllow = [ "" ]; | ||
LockPersonality = true; | ||
NoNewPrivileges = true; | ||
PrivateDevices = true; | ||
PrivateMounts = true; | ||
PrivateTmp = true; | ||
ProtectClock = true; | ||
ProtectControlGroups = true; | ||
ProtectHome = true; | ||
ProtectHostname = true; | ||
ProtectKernelLogs = true; | ||
ProtectKernelModules = true; | ||
ProtectKernelTunables = true; | ||
ProtectSystem = "strict"; | ||
RemoveIPC = true; | ||
RestrictAddressFamilies = [ "AF_INET" "AF_INET6" ]; | ||
RestrictNamespaces = true; | ||
RestrictRealtime = true; | ||
RestrictSUIDSGID = true; | ||
SystemCallArchitectures = "native"; | ||
}; | ||
} | ||
service | ||
]; | ||
in | ||
{ | ||
options.services.exam-poll = with lib; { | ||
enable = mkEnableOption "Exam Poll"; | ||
|
||
configureNginx = mkOption { | ||
type = types.bool; | ||
default = true; | ||
description = "Whether to configure nginx as reverse proxy."; | ||
}; | ||
|
||
frontend = { | ||
package = mkOption { | ||
type = types.package; | ||
default = pkgs.exam-poll-frontend; | ||
description = "The package to use."; | ||
}; | ||
|
||
port = mkOption { | ||
type = types.port; | ||
default = 3000; | ||
description = "The port to listen on."; | ||
}; | ||
|
||
hostName = mkOption { | ||
type = types.str; | ||
example = "exam-poll.example.com"; | ||
description = "The hostname the application will be served on."; | ||
}; | ||
}; | ||
|
||
backend = { | ||
package = mkOption { | ||
type = types.package; | ||
default = pkgs.exam-poll-backend; | ||
description = "The package to use."; | ||
}; | ||
|
||
port = mkOption { | ||
type = types.port; | ||
default = 8000; | ||
description = "The port to listen on."; | ||
}; | ||
|
||
hostName = mkOption { | ||
type = types.str; | ||
example = "exam-poll-api.example.com"; | ||
description = "The hostname the api will be served on."; | ||
}; | ||
}; | ||
|
||
mongodb = { | ||
uri = mkOption { | ||
type = types.str; | ||
example = "mongodb://localhost:27017"; | ||
description = "MongoDB connection string."; | ||
}; | ||
|
||
database = mkOption { | ||
type = types.str; | ||
description = "The database name."; | ||
}; | ||
|
||
collection = mkOption { | ||
type = types.str; | ||
description = "The collection name."; | ||
}; | ||
}; | ||
}; | ||
|
||
config = lib.mkIf cfg.enable { | ||
systemd.services = { | ||
exam-poll-frontend = mkService { | ||
description = "Exam Poll frontend"; | ||
environment = { | ||
PORT = toString cfg.frontend.port; | ||
}; | ||
serviceConfig = { | ||
ExecStart = lib.getExe (cfg.frontend.package.override { | ||
localApiBaseUrl = "http://localhost:${toString cfg.backend.port}"; | ||
publicApiBaseUrl = "https://${cfg.backend.hostName}"; | ||
}); | ||
}; | ||
}; | ||
|
||
exam-poll-backend = mkService { | ||
description = "Exam Poll backend"; | ||
environment = { | ||
EXAM_POLL_HTTP_LISTEN = "localhost:${toString cfg.backend.port}"; | ||
EXAM_POLL_CORS_LIST = "https://${cfg.frontend.hostName},localhost"; | ||
EXAM_POLL_MONGODB = cfg.mongodb.uri; | ||
EXAM_POLL_DATABASE = cfg.mongodb.database; | ||
EXAM_POLL_COLLECTION = cfg.mongodb.collection; | ||
}; | ||
serviceConfig = { | ||
ExecStart = lib.getExe pkgs.exam-poll-backend; | ||
}; | ||
}; | ||
}; | ||
|
||
services.nginx = lib.mkIf cfg.configureNginx { | ||
enable = true; | ||
recommendedProxySettings = true; | ||
virtualHosts = { | ||
${cfg.frontend.hostName} = { | ||
forceSSL = lib.mkDefault true; | ||
enableACME = lib.mkDefault true; | ||
locations."/".proxyPass = "http://localhost:${toString cfg.frontend.port}"; | ||
}; | ||
${cfg.backend.hostName} = { | ||
forceSSL = lib.mkDefault true; | ||
enableACME = lib.mkDefault true; | ||
locations."/".proxyPass = "http://localhost:${toString cfg.backend.port}"; | ||
}; | ||
}; | ||
}; | ||
}; | ||
} |