2024-10-09 11:05:41 +00:00
|
|
|
<script setup>
|
|
|
|
import NixCode from "./NixCode.vue"
|
|
|
|
import NixForm from "./NixForm.vue"
|
2024-10-23 15:51:43 +00:00
|
|
|
import NixPreview from "./NixPreview.vue"
|
2024-10-10 10:45:58 +00:00
|
|
|
import { provide, ref } from 'vue'
|
2024-10-23 10:32:12 +00:00
|
|
|
import { listTz, clientTz } from 'timezone-select-js';
|
2024-10-10 10:45:58 +00:00
|
|
|
|
2024-10-23 10:32:12 +00:00
|
|
|
const availableLanguages = {
|
|
|
|
'en_US.UTF-8': 'English',
|
|
|
|
'fr_FR.UTF-8': 'Francais'
|
|
|
|
}
|
|
|
|
const availableTimezones = listTz()
|
2024-10-10 10:45:58 +00:00
|
|
|
let nixin = {
|
|
|
|
netconf: 'autoconfig',
|
|
|
|
networkingHostname: '',
|
2024-10-11 10:23:21 +00:00
|
|
|
networkingDomain: 'nixin.local',
|
2024-10-10 10:45:58 +00:00
|
|
|
availableBundles: [
|
|
|
|
{
|
|
|
|
"id": "writeCollectively",
|
|
|
|
"name": "Write collectively : pads",
|
|
|
|
"services": [
|
|
|
|
'hedgedoc', 'nextcloud'
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "forge",
|
|
|
|
"name": "Forge : git repo, CI/CD workers, and NixiN",
|
|
|
|
"services": [
|
|
|
|
'forgejo', 'forgejorunner', 'nixin'
|
|
|
|
]
|
2024-10-09 11:05:41 +00:00
|
|
|
|
2024-10-10 10:45:58 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "socialMedia",
|
|
|
|
"name": "Social media: hosted social medias in activitypub web-apps",
|
|
|
|
"services": [
|
|
|
|
'gotosocial', 'peertube', 'lemmy'
|
|
|
|
]
|
|
|
|
|
|
|
|
}],
|
|
|
|
availableServices: [
|
|
|
|
{
|
|
|
|
"id": "hedgedoc",
|
|
|
|
"name": "Hedgedoc : realtime collaborative markdown editor"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "forgejo",
|
|
|
|
"name": "Forgejo : git hosting"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "forgejorunner",
|
|
|
|
"name": "Forgejo runner : CD/CI runner for Forgejo"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "gotosocial",
|
|
|
|
"name": "Gotosocial : personal light activityPub social media"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "peertube",
|
|
|
|
"name": "Peertube : video hosting platform with activityPub"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "lemmy",
|
|
|
|
"name": "Lemmy : reddit alternative with activityPub"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "nextcloud",
|
|
|
|
"name": "Nextcloud : personnal cloud"
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"id": "nixin",
|
|
|
|
"name": "NixiN : web ui for configurations"
|
|
|
|
}],
|
|
|
|
bundles: [],
|
|
|
|
services: [],
|
2024-10-23 10:32:12 +00:00
|
|
|
timezone: 'Europe/Belfast', // default to UTC but could be found with clientTz(),
|
2024-10-10 10:45:58 +00:00
|
|
|
locale: 'en_US.UTF-8',
|
2024-10-23 10:32:12 +00:00
|
|
|
operatingUser: 'operator',
|
|
|
|
operatingUserPassword: 'CHANGE ME !!!',
|
2024-10-10 10:45:58 +00:00
|
|
|
}
|
|
|
|
nixin.availableServices.forEach((s) => {
|
|
|
|
s.inBundle = []
|
|
|
|
})
|
|
|
|
nixin.availableBundles.forEach((b) => {
|
|
|
|
b.services.forEach((s) => {
|
|
|
|
nixin.availableServices.find(item => item.id === s).inBundle.push(b.id);
|
|
|
|
})
|
|
|
|
})
|
|
|
|
nixin=ref(nixin)
|
|
|
|
provide('nixin', nixin)
|
|
|
|
|
|
|
|
function netconfHasBeenChanged(val = '') {
|
|
|
|
if (val === 'autoconfig') {
|
2024-10-11 10:23:21 +00:00
|
|
|
nixin.networkingDomain = 'nixin.local'
|
2024-10-10 10:45:58 +00:00
|
|
|
} else {
|
|
|
|
nixin.networkingDomain = ''
|
|
|
|
}
|
|
|
|
}
|
2024-09-30 19:17:24 +00:00
|
|
|
|
2024-10-10 10:45:58 +00:00
|
|
|
function selectServices(bundleId, services) {
|
|
|
|
if (nixin.value.bundles.includes(bundleId)) {
|
|
|
|
services.forEach((s) => {
|
|
|
|
if (nixin.value.services.indexOf(s) === -1) {
|
|
|
|
nixin.value.services.push(s)
|
2024-09-24 10:46:27 +00:00
|
|
|
}
|
2024-10-10 10:45:58 +00:00
|
|
|
})
|
|
|
|
} else {
|
|
|
|
services.forEach((s) => {
|
|
|
|
const index = nixin.value.services.indexOf(s);
|
|
|
|
if (index > -1) {
|
|
|
|
nixin.value.services.splice(index, 1);
|
2024-10-02 10:52:33 +00:00
|
|
|
}
|
2024-10-10 10:45:58 +00:00
|
|
|
})
|
2024-09-24 10:46:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<template>
|
|
|
|
<h2>Networking</h2>
|
|
|
|
<div class="form-cell">
|
|
|
|
<strong>Choose your network configuration</strong>
|
2024-10-11 10:23:21 +00:00
|
|
|
<div>
|
2024-09-24 10:46:27 +00:00
|
|
|
<label>
|
2024-10-10 10:45:58 +00:00
|
|
|
<input type="radio" v-model="nixin.netconf" value="autoconfig"
|
2024-09-30 19:17:24 +00:00
|
|
|
@click="netconfHasBeenChanged('autoconfig')">I'm a noob in network config, I trust you to provide networking
|
|
|
|
for me (ipv6 only)</label>
|
2024-10-11 10:23:21 +00:00
|
|
|
</div>
|
|
|
|
<div>
|
2024-09-24 10:46:27 +00:00
|
|
|
<label>
|
2024-10-10 10:45:58 +00:00
|
|
|
<input type="radio" v-model="nixin.netconf" value="publicip" @click="netconfHasBeenChanged">My server
|
2024-09-30 19:17:24 +00:00
|
|
|
has a public ip that I can provide
|
2024-09-24 10:46:27 +00:00
|
|
|
</label>
|
2024-10-11 10:23:21 +00:00
|
|
|
</div>
|
|
|
|
<div>
|
2024-09-24 10:46:27 +00:00
|
|
|
<label>
|
2024-10-10 10:45:58 +00:00
|
|
|
<input type="radio" v-model="nixin.netconf" value="localnetwork" @click="netconfHasBeenChanged">My
|
2024-09-30 19:17:24 +00:00
|
|
|
router is set so that my local machine is accessible on the public network
|
2024-09-24 10:46:27 +00:00
|
|
|
</label>
|
2024-10-11 10:23:21 +00:00
|
|
|
</div>
|
|
|
|
<div>
|
2024-09-24 10:46:27 +00:00
|
|
|
<label>
|
2024-10-10 10:45:58 +00:00
|
|
|
<input type="radio" v-model="nixin.netconf" value="wireguard" @click="netconfHasBeenChanged">My server can use a wireguard server i can configure
|
2024-09-24 10:46:27 +00:00
|
|
|
</label>
|
|
|
|
</div>
|
2024-10-11 10:23:21 +00:00
|
|
|
</div>
|
2024-09-24 10:46:27 +00:00
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-cell">
|
|
|
|
<label>Machine network name</label>
|
2024-10-10 10:45:58 +00:00
|
|
|
<input required type="text" v-model="nixin.networkingHostname"
|
2024-09-24 10:46:27 +00:00
|
|
|
placeholder="Give your machine a name without spaces, ponctuation or accents" />
|
|
|
|
</div>
|
|
|
|
</div>
|
2024-10-10 10:45:58 +00:00
|
|
|
<input v-if="nixin.netconf === 'autoconfig'" type="hidden" value="distrilab.fr" />
|
|
|
|
<div class="form-row" v-if="nixin.netconf !== 'autoconfig'">
|
2024-09-24 10:46:27 +00:00
|
|
|
<div class="form-cell">
|
|
|
|
<label>Domain name</label>
|
2024-10-10 10:45:58 +00:00
|
|
|
<input required type="text" v-model="nixin.networkingDomain" placeholder="ex: distrilab.fr" />
|
2024-09-24 10:46:27 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
|
|
|
|
<h2>Usage bundles</h2>
|
2024-09-30 19:17:24 +00:00
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-cell">
|
|
|
|
<strong>Choose your usage bundles (multiple choices possible if your machine can handle it)</strong>
|
2024-10-10 10:45:58 +00:00
|
|
|
<div v-for="bundle in nixin.availableBundles" :key="bundle">
|
2024-09-30 19:17:24 +00:00
|
|
|
<label>
|
2024-10-10 10:45:58 +00:00
|
|
|
<input type="checkbox" v-model="nixin.bundles" :id="bundle.id" :value="bundle.id"
|
2024-10-02 10:52:33 +00:00
|
|
|
@change="selectServices(bundle.id, bundle.services)" />
|
2024-09-30 19:17:24 +00:00
|
|
|
{{ bundle.name }}
|
|
|
|
</label>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2024-09-24 10:46:27 +00:00
|
|
|
|
2024-09-30 19:17:24 +00:00
|
|
|
<h2>Services</h2>
|
2024-10-10 10:45:58 +00:00
|
|
|
<div v-if="nixin.bundles.length === 0">👆 Choose any upper bundle to make associated services appear.</div>
|
|
|
|
<div v-for="service in nixin.availableServices" :key="service">
|
|
|
|
<div v-if="service.inBundle && service.inBundle.some(ai => nixin.bundles.includes(ai))">
|
|
|
|
<NixForm :service="service" />
|
|
|
|
</div>
|
2024-09-30 19:17:24 +00:00
|
|
|
</div>
|
2024-09-24 10:46:27 +00:00
|
|
|
|
2024-09-30 19:17:24 +00:00
|
|
|
<h2>Other configuration</h2>
|
2024-10-23 10:32:12 +00:00
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-cell">
|
|
|
|
<label>Operating UNIX user name</label>
|
|
|
|
<input required type="text" v-model="nixin.operatingUser" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-cell">
|
|
|
|
<label>Operating UNIX user password</label>
|
|
|
|
<input required type="text" v-model="nixin.operatingUserPassword" />
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-cell">
|
|
|
|
<label>Timezone</label>
|
|
|
|
<select v-model="nixin.timezone">
|
|
|
|
<option v-for="tz in availableTimezones" :selected="nixin.timezone === tz.value" v-bind:value="tz.value">{{ tz.label }}</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div class="form-row">
|
|
|
|
<div class="form-cell">
|
|
|
|
<label>Locale</label>
|
|
|
|
<select v-model="nixin.locale">
|
|
|
|
<option v-for="(lang, k) in availableLanguages" :selected="nixin.locale === k" v-bind:value="k">{{ lang }}</option>
|
|
|
|
</select>
|
|
|
|
</div>
|
|
|
|
</div>
|
2024-09-24 10:46:27 +00:00
|
|
|
|
|
|
|
<h2>Auto-generated configuration.nix file</h2>
|
2024-10-23 15:51:43 +00:00
|
|
|
<NixPreview />
|
2024-10-11 10:51:41 +00:00
|
|
|
<pre class="nix-code">
|
2024-09-24 10:46:27 +00:00
|
|
|
<code>
|
2024-10-11 10:51:41 +00:00
|
|
|
{ pkgs, ... }:
|
2024-09-24 10:46:27 +00:00
|
|
|
|
2024-10-11 10:51:41 +00:00
|
|
|
{
|
|
|
|
networking.hosts = {
|
|
|
|
"127.0.0.1" = [ "{{ nixin.networkingHostname }}.{{nixin.networkingDomain}}" ];
|
|
|
|
};
|
2024-09-24 10:46:27 +00:00
|
|
|
|
2024-10-11 10:51:41 +00:00
|
|
|
networking.hostName = "{{ nixin.networkingHostname }}";
|
|
|
|
networking.domain = "{{ nixin.networkingDomain }}";
|
|
|
|
networking.firewall = {
|
|
|
|
allowedTCPPorts = [
|
|
|
|
80
|
|
|
|
443
|
|
|
|
];
|
|
|
|
};
|
2024-09-24 10:46:27 +00:00
|
|
|
|
2024-10-11 10:51:41 +00:00
|
|
|
time.timeZone = "{{ nixin.timezone }}";
|
|
|
|
i18n.defaultLocale = "{{ nixin.locale }}";
|
|
|
|
<div v-for="(service) in nixin.services" :key="service">
|
2024-10-15 08:29:50 +00:00
|
|
|
<NixCode :service="service"/>
|
2024-10-11 10:51:41 +00:00
|
|
|
</div>
|
|
|
|
|
2024-10-23 10:32:12 +00:00
|
|
|
users.users.{{ nixin.operatingUser }} = {
|
2024-09-24 10:46:27 +00:00
|
|
|
isNormalUser = true;
|
|
|
|
extraGroups = [ "wheel" ];
|
2024-10-23 10:32:12 +00:00
|
|
|
initialPassword = "{{ nixin.operatingUserPassword }}";
|
2024-10-11 10:51:41 +00:00
|
|
|
};
|
2024-09-24 10:46:27 +00:00
|
|
|
|
2024-10-11 10:51:41 +00:00
|
|
|
security.sudo.extraRules= [
|
|
|
|
{
|
2024-10-23 10:32:12 +00:00
|
|
|
users = [ "{{ nixin.operatingUser }}" ];
|
2024-09-24 10:46:27 +00:00
|
|
|
commands = [
|
2024-10-11 10:51:41 +00:00
|
|
|
{
|
|
|
|
command = "ALL" ;
|
2024-10-23 15:51:43 +00:00
|
|
|
options= [ "NOPASSWD" ];
|
2024-10-11 10:51:41 +00:00
|
|
|
}
|
2024-09-24 10:46:27 +00:00
|
|
|
];
|
2024-10-11 10:51:41 +00:00
|
|
|
}
|
|
|
|
];
|
2024-09-24 10:46:27 +00:00
|
|
|
|
2024-10-11 10:51:41 +00:00
|
|
|
security.acme.defaults.email = "contact@nixin.local";
|
|
|
|
security.acme.acceptTerms = true;
|
2024-09-24 10:46:27 +00:00
|
|
|
|
2024-10-11 10:51:41 +00:00
|
|
|
services.nginx = {
|
|
|
|
enable = true;
|
|
|
|
|
|
|
|
# Use recommended settings
|
|
|
|
recommendedGzipSettings = true;
|
|
|
|
recommendedOptimisation = true;
|
|
|
|
recommendedProxySettings = true;
|
|
|
|
recommendedTlsSettings = true;
|
|
|
|
|
|
|
|
# Only allow PFS-enabled ciphers with AES256
|
|
|
|
sslCiphers = "AES256+EECDH:AES256+EDH:!aNULL";
|
|
|
|
|
|
|
|
virtualHosts."hedgedoc.nixin.local" = {
|
|
|
|
forceSSL = true;
|
|
|
|
enableACME = true;
|
|
|
|
root = "/var/www/hedgedoc";
|
|
|
|
locations."/".proxyPass = "http://127.0.0.1:8001";
|
|
|
|
locations."/socket.io/" = {
|
|
|
|
proxyPass = "http://127.0.0.1:8001";
|
|
|
|
proxyWebsockets = true;
|
|
|
|
extraConfig = "proxy_ssl_server_name on;";
|
|
|
|
};
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
environment.systemPackages = with pkgs; [
|
|
|
|
git
|
|
|
|
wget
|
|
|
|
tmux
|
|
|
|
mosh
|
|
|
|
htop
|
|
|
|
];
|
|
|
|
|
|
|
|
system.stateVersion = "24.05";
|
|
|
|
}
|
2024-09-24 10:46:27 +00:00
|
|
|
</code>
|
|
|
|
</pre>
|
|
|
|
</template>
|