Compare commits
61
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
03c7277692 | ||
|
|
de16857570 | ||
|
|
f2f12a2688 | ||
|
|
e61a07f8d3 | ||
|
|
ea38d94178 | ||
|
|
81771725d0 | ||
|
|
06345cd04c | ||
|
|
9b622e6e3e | ||
|
|
8e0c6266af | ||
|
|
11049a04d8 | ||
|
|
483ea954b2 | ||
|
|
8fa1f674f9 | ||
|
|
2006b9733e | ||
|
|
0af355843d | ||
|
|
1b2227af24 | ||
|
|
85f2e87040 | ||
|
|
d400a4b0e7 | ||
|
|
9d148f5f9e | ||
|
|
836e49f772 | ||
|
|
9bd2f16dbb | ||
|
|
0510bf6e90 | ||
|
|
aadd803df0 | ||
|
|
c760b77bfe | ||
|
|
7e446f25eb | ||
|
|
21329ecabd | ||
|
|
06b673ec89 | ||
|
|
84bfeb5c32 | ||
|
|
083f93ec5f | ||
|
|
552a3c58a6 | ||
|
|
4060c7afba | ||
|
|
6c3bd0f1d4 | ||
|
|
41b3733482 | ||
|
|
e070e30a4d | ||
|
|
5df3b0ec08 | ||
|
|
92981e0ccf | ||
|
|
bae3028751 | ||
|
|
d4c58b8763 | ||
|
|
05bdddfed7 | ||
|
|
1b61394afd | ||
|
|
9f40b38886 | ||
|
|
a1cac6b8a3 | ||
|
|
3f3d619694 | ||
|
|
0061d7dbf0 | ||
|
|
7de9db5de0 | ||
|
|
206a43526a | ||
|
|
2f9af8621d | ||
|
|
60a455486c | ||
|
|
b4f6538ffe | ||
|
|
d91d332af9 | ||
|
|
e677effa5f | ||
|
|
885a41088d | ||
|
|
f47e4f5c36 | ||
|
|
797b276da4 | ||
|
|
404087a8b0 | ||
|
|
0a6cd8f866 | ||
|
|
f9af291df7 | ||
|
|
4dfc8af94b | ||
|
|
83dbdcea3e | ||
|
|
5474dbe720 | ||
|
|
2586773680 | ||
|
|
13e48a54c3 |
@@ -0,0 +1,4 @@
|
||||
---
|
||||
|
||||
profile: production
|
||||
offline: true
|
||||
-10
@@ -1,10 +0,0 @@
|
||||
---
|
||||
kind: pipeline
|
||||
type: docker
|
||||
name: ansible
|
||||
steps:
|
||||
- name: ansible-lint
|
||||
image: python:3.10.7
|
||||
commands:
|
||||
- pip install -r ansible/requirements.txt > /dev/null 2> /dev/null
|
||||
- ansible-lint ansible
|
||||
@@ -0,0 +1,15 @@
|
||||
name: Check
|
||||
on: [push]
|
||||
jobs:
|
||||
"Lint Ansible Files":
|
||||
runs-on: ubuntu-22.04
|
||||
steps:
|
||||
- run: apt-get update
|
||||
- run: apt-get install -y python3 python3-pip python3-venv
|
||||
- run: python3 --version
|
||||
- name: Check out repo
|
||||
uses: actions/checkout@v3
|
||||
- run: python3 -m venv venv
|
||||
- run: venv/bin/pip --disable-pip-version-check install ansible==7.2.0 ansible-lint==6.16.1 > /dev/null 2> /dev/null
|
||||
- run: venv/bin/ansible-lint -c .ansible-lint ansible
|
||||
# TODO: Reimplement ansible-play --check step from old drone config
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
*.env
|
||||
backups
|
||||
*.swp
|
||||
|
||||
@@ -4,21 +4,16 @@
|
||||
|
||||
| Prop | Value |
|
||||
| --- | --- |
|
||||
| Hostname | `h2954114` |
|
||||
| Domains | `{wiki.,codi.,git.,}pbrinkmeier.de`, `tichy.click`, `h2954114.stratoserver.net` |
|
||||
| Hostname | `shamash` |
|
||||
| Domains | `{,pad.,codi.,ci.,git.,jupyter.,plantuml.}pbrinkmeier.de`, `tichy.click`, `beany.club`, `vmd98928.contaboserver.net` |
|
||||
|
||||
### Personal Website
|
||||
## Linting
|
||||
|
||||
[pbrinkmeier.de](https://pbrinkmeier.de)
|
||||
Use `nix develop` to drop into a shell containing `ansible-lint`.
|
||||
Then run it using
|
||||
|
||||
### Personal Wiki
|
||||
```
|
||||
ansible-lint --offline
|
||||
```
|
||||
|
||||
[wiki.pbrinkmeier.de](https://wiki.pbrinkmeier.de)
|
||||
|
||||
### Collaborative Markdown Editing
|
||||
|
||||
[codi.pbrinkmeier.de](https://codi.pbrinkmeier.de)
|
||||
|
||||
### Tichy-Clicker
|
||||
|
||||
[tichy.click](https://tichy.click)
|
||||
to avoid checking for a new version every single run.
|
||||
|
||||
@@ -6,7 +6,13 @@
|
||||
- [x] Make it inaccessible to anyone but root (`-rw------`)
|
||||
- [x] Add [Drone runner](https://docs.drone.io/runner/docker/installation/linux/)
|
||||
- [ ] Figure out how to dependably store `.env` files (Ansible vault? Something else?)
|
||||
- [ ] In vault, seperate from other config
|
||||
- [x] Check out docker swarm and current best practices for Ansible
|
||||
- [x] Use Gitea instead of GitLab
|
||||
- [ ] Add drone exec runner for Nix builds with shared `/nix`
|
||||
- [ ] Lint caddy file, add gzip and disable admin interface
|
||||
- [ ] Lint caddy file, add gzip and disable admin interface
|
||||
- [x] Make Gitea display graphs in Notebooks (see https://docs.gitea.io/en-us/external-renderers/).
|
||||
- [x] Factorio server
|
||||
- [ ] Add flag for Gitea backups (after which Gitea will be up but no contain the sites source code)
|
||||
- [x] Add Gitea actions
|
||||
- [ ] Remove drone
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
venv
|
||||
+3
-2
@@ -2,10 +2,11 @@
|
||||
|
||||
## Ansible Control Node Setup
|
||||
|
||||
In a Python 3 environment (perhaps a venv), run:
|
||||
The root of this repo contains a `flake.nix` that defines a shell with all necessary tools.
|
||||
To drop into a shell with `ansible-*` commands, run:
|
||||
|
||||
```
|
||||
pip install -r requirements.txt
|
||||
nix develop
|
||||
```
|
||||
|
||||
## `misc.yaml`
|
||||
|
||||
+1
-1
@@ -1,2 +1,2 @@
|
||||
[misc]
|
||||
shamash
|
||||
vmd98928.contaboserver.net ansible_port=2309
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
ansible.builtin.user:
|
||||
name: "{{ item.name }}"
|
||||
uid: "{{ item.uid }}"
|
||||
state: "{{ item.state }}"
|
||||
create_home: false
|
||||
state: present
|
||||
system: true
|
||||
loop:
|
||||
- name: jupyter
|
||||
uid: 42000
|
||||
@@ -16,24 +17,57 @@
|
||||
- name: gitea
|
||||
uid: 42001
|
||||
state: present
|
||||
- name: score
|
||||
uid: 42003
|
||||
state: present
|
||||
- name: factorio
|
||||
uid: 845
|
||||
state: present
|
||||
- name: hackmd
|
||||
uid: 1500
|
||||
state: present
|
||||
|
||||
- name: hedgedoc
|
||||
uid: 10000
|
||||
state: absent
|
||||
- name: bsa
|
||||
uid: 42002
|
||||
state: absent
|
||||
# All services that are behind Caddy need to be in this network
|
||||
- name: Create Caddy network
|
||||
become: true
|
||||
docker_network:
|
||||
community.docker.docker_network:
|
||||
name: caddy-network
|
||||
state: present
|
||||
- name: Upload docker configuration
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: ../../docker
|
||||
src: ../../docker/docker
|
||||
dest: /etc/pbri
|
||||
# Files should inaccessible to non-root users.
|
||||
mode: u=rw,g=,o=
|
||||
# Directories should be listable
|
||||
directory_mode: u=rwx,g=rx,o=rx
|
||||
- name: Upload and decrypt docker environment vars
|
||||
become: true
|
||||
ansible.builtin.copy:
|
||||
src: "../../docker/envs/{{ item.name }}/.env"
|
||||
dest: /etc/pbri/docker/{{ item.name }}/.env
|
||||
# Files should inaccessible to non-root users.
|
||||
mode: u=rw,g=,o=
|
||||
# This is true by default but I put it here anyways
|
||||
# to emphasize what's happening
|
||||
decrypt: true
|
||||
# Not quite happy with all the seperate loops yet.
|
||||
loop:
|
||||
- name: codi
|
||||
state: present
|
||||
- name: drone
|
||||
state: present
|
||||
- name: factorio
|
||||
state: present
|
||||
- name: gitea
|
||||
state: present
|
||||
- name: Create directory for docker volumes
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
@@ -41,9 +75,41 @@
|
||||
state: directory
|
||||
# Hide contents from non-root users
|
||||
mode: u=rwx,g=,o=
|
||||
- name: Set up docker stuff
|
||||
- name: Create jupyter folders
|
||||
become: true
|
||||
docker_compose:
|
||||
ansible.builtin.file:
|
||||
path: "/var/lib/pbri/docker/{{ item.name }}"
|
||||
owner: "{{ item.user }}"
|
||||
group: "{{ item.user }}"
|
||||
state: directory
|
||||
mode: u=rwx,g=,o=
|
||||
loop:
|
||||
- name: jupyter_data
|
||||
user: jupyter
|
||||
- name: jupyter_notebooks
|
||||
user: jupyter
|
||||
- name: Create Factorio data folder
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: /var/lib/pbri/docker/factorio
|
||||
state: directory
|
||||
owner: factorio
|
||||
group: factorio
|
||||
mode: u=rwx,g=,o=
|
||||
- name: Create score data folder
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: /var/lib/pbri/docker/score
|
||||
state: directory
|
||||
owner: score
|
||||
group: score
|
||||
mode: u=rwx,g=,o=
|
||||
# Since some docker-compose configuration might want to pull
|
||||
# images from the Gitea package repository, we need to ensure
|
||||
# that Gitea is reachable before those configurations are deployed.
|
||||
- name: Set up caddy and gitea containers
|
||||
become: true
|
||||
community.docker.docker_compose:
|
||||
project_src: "/etc/pbri/docker/{{ item.name }}"
|
||||
state: "{{ item.state }}"
|
||||
build: true
|
||||
@@ -53,15 +119,37 @@
|
||||
state: present
|
||||
- name: gitea
|
||||
state: present
|
||||
# Before deploying the remaining configs below, we check that
|
||||
# Gitea is reachable at git.pbrinkmeier.de
|
||||
- name: Wait for gitea to be reachable
|
||||
check_mode: false
|
||||
ansible.builtin.uri:
|
||||
method: GET
|
||||
url: https://git.pbrinkmeier.de/api/v1/version
|
||||
register: gitea_version_response
|
||||
until: gitea_version_response.status == 200
|
||||
retries: 10
|
||||
delay: 5 # Retry every 5 seconds
|
||||
- name: Set up other containers
|
||||
become: true
|
||||
community.docker.docker_compose:
|
||||
project_src: "/etc/pbri/docker/{{ item.name }}"
|
||||
state: "{{ item.state }}"
|
||||
build: true
|
||||
debug: true
|
||||
loop:
|
||||
- name: drone
|
||||
state: present
|
||||
- name: codi
|
||||
state: present
|
||||
- name: Add Notebooks folder
|
||||
become: true
|
||||
ansible.builtin.file:
|
||||
path: /home/jupyter/Notebooks
|
||||
owner: jupyter
|
||||
group: jupyter
|
||||
state: directory
|
||||
mode: 0755
|
||||
- name: jupyter
|
||||
state: present
|
||||
- name: utoy
|
||||
state: present
|
||||
- name: score
|
||||
state: present
|
||||
|
||||
- name: factorio
|
||||
state: absent
|
||||
- name: glebby
|
||||
state: absent
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
ansible==6.4.0
|
||||
ansible-lint==6.5.2
|
||||
@@ -12,6 +12,7 @@
|
||||
- lsb-release
|
||||
|
||||
- name: Retrieve Docker GPG key
|
||||
check_mode: false
|
||||
ansible.builtin.uri:
|
||||
url: https://download.docker.com/linux/debian/gpg
|
||||
return_content: true
|
||||
@@ -25,8 +26,9 @@
|
||||
creates: /usr/share/keyrings/docker-archive-keyring.gpg
|
||||
|
||||
- name: Retrieve dpkg architecture
|
||||
check_mode: false
|
||||
ansible.builtin.command: dpkg --print-architecture
|
||||
register: dpkg_architecture
|
||||
register: docker_dpkg_architecture
|
||||
changed_when: false
|
||||
|
||||
- name: Add Docker apt repository
|
||||
@@ -34,7 +36,7 @@
|
||||
ansible.builtin.template:
|
||||
src: docker.list.j2
|
||||
dest: /etc/apt/sources.list.d/docker.list
|
||||
mode: 0644
|
||||
mode: "u=rw,g=r,o=r"
|
||||
|
||||
- name: Install Docker
|
||||
become: true
|
||||
|
||||
@@ -1 +1 @@
|
||||
deb [arch={{ dpkg_architecture.stdout }} signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable
|
||||
deb [arch={{ docker_dpkg_architecture.stdout }} signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
## Folders
|
||||
|
||||
- `docker`: Contains `docker-compose` configurations for projects
|
||||
- `envs`: Contains `.env` files encrypted using `ansible-vault`. These files are decrypted and uploaded next to their corresponding `docker-compose.yaml` file.
|
||||
@@ -1,3 +1,7 @@
|
||||
{
|
||||
admin off
|
||||
}
|
||||
|
||||
pbrinkmeier.de {
|
||||
file_server {
|
||||
root /srv/pbrinkmeier.de
|
||||
@@ -11,6 +15,10 @@ tichy.click {
|
||||
}
|
||||
|
||||
codi.pbrinkmeier.de {
|
||||
redir https://pad.pbrinkmeier.de{uri} permanent
|
||||
}
|
||||
|
||||
pad.pbrinkmeier.de {
|
||||
reverse_proxy codi:3000
|
||||
}
|
||||
|
||||
@@ -32,3 +40,11 @@ jupyter.pbrinkmeier.de {
|
||||
plantuml.pbrinkmeier.de {
|
||||
reverse_proxy codi_plantuml:8080
|
||||
}
|
||||
|
||||
utoy.beany.club {
|
||||
reverse_proxy utoy:3000
|
||||
}
|
||||
|
||||
score.brocke.net {
|
||||
reverse_proxy score:8080
|
||||
}
|
||||
@@ -5,15 +5,33 @@ services:
|
||||
image: hackmdio/hackmd:2.4.2
|
||||
user: hackmd
|
||||
environment:
|
||||
CMD_USECDN: "false"
|
||||
CMD_DOMAIN: codi.pbrinkmeier.de
|
||||
CMD_PROTOCOL_USESSL: "true"
|
||||
CMD_EMAIL: "true"
|
||||
CMD_ALLOW_EMAIL_REGISTER: "false"
|
||||
CMD_ALLOW_ANONYMOUS_EDITS: "true"
|
||||
CMD_PLANTUML_SERVER: https://plantuml.pbrinkmeier.de
|
||||
# Admin stuff
|
||||
CMD_DB_URL: "postgres://${CODI_DB_USER}:${CODI_DB_PASSWORD}@codi_db/${CODI_DB_DB}"
|
||||
CMD_SESSION_SECRET: "${CODI_SESSION_SECRET}"
|
||||
CMD_USECDN: "false"
|
||||
CMD_DOMAIN: pad.pbrinkmeier.de
|
||||
CMD_PROTOCOL_USESSL: "true"
|
||||
CMD_ALLOW_GRAVATAR: "false"
|
||||
# Don't allow unauthenticated users to create notes
|
||||
CMD_ALLOW_ANONYMOUS: "false"
|
||||
# Allow unauthenticated users to edit "Freely" notes
|
||||
CMD_ALLOW_ANONYMOUS_EDITS: "true"
|
||||
# Misc
|
||||
CMD_ALLOW_FREEURL: "true"
|
||||
CMD_REQUIRE_FREEURL_AUTHENTICATION: "true"
|
||||
CMD_PLANTUML_SERVER: https://plantuml.pbrinkmeier.de
|
||||
# Authentication: Use Gitea OAuth2
|
||||
CMD_EMAIL: "false"
|
||||
CMD_ALLOW_EMAIL_REGISTER: "false"
|
||||
CMD_OAUTH2_CLIENT_ID: "${CODI_OAUTH2_CLIENT_ID}"
|
||||
CMD_OAUTH2_CLIENT_SECRET: "${CODI_OAUTH2_CLIENT_SECRET}"
|
||||
CMD_OAUTH2_AUTHORIZATION_URL: https://git.pbrinkmeier.de/login/oauth/authorize
|
||||
CMD_OAUTH2_TOKEN_URL: https://git.pbrinkmeier.de/login/oauth/access_token
|
||||
CMD_OAUTH2_USER_PROFILE_URL: https://git.pbrinkmeier.de/api/v1/user
|
||||
CMD_OAUTH2_USER_PROFILE_USERNAME_ATTR: login
|
||||
CMD_OAUTH2_USER_PROFILE_DISPLAY_NAME_ATTR: full_name
|
||||
CMD_OAUTH2_USER_PROFILE_EMAIL_ATTR: email
|
||||
|
||||
depends_on:
|
||||
- codi_db
|
||||
- codi_plantuml
|
||||
@@ -12,7 +12,7 @@ services:
|
||||
DRONE_SERVER_PROTO: https
|
||||
volumes:
|
||||
- /var/lib/pbri/docker/drone:/data
|
||||
restart: always
|
||||
restart: unless-stopped
|
||||
|
||||
drone_runner:
|
||||
image: drone/drone-runner-docker:1
|
||||
@@ -24,7 +24,7 @@ services:
|
||||
DRONE_RUNNER_NAME: shamash
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
restart: always
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
default:
|
||||
@@ -0,0 +1,4 @@
|
||||
FROM factoriotools/factorio:1.1.87
|
||||
|
||||
COPY server-settings.json /server-settings.json
|
||||
ENTRYPOINT [ "/bin/sh", "-c", "mkdir -p /factorio/config && envsubst < /server-settings.json > /factorio/config/server-settings.json && exec /docker-entrypoint.sh" ]
|
||||
@@ -0,0 +1,10 @@
|
||||
# factorio
|
||||
|
||||
Add a `.env` file like this:
|
||||
|
||||
```
|
||||
GAME_PASSWORD=...
|
||||
```
|
||||
|
||||
Environment variables are put into `server-settings.json` during startup using `envsubst`.
|
||||
See also: https://hub.docker.com/r/factoriotools/factorio.
|
||||
@@ -0,0 +1,14 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
gitea:
|
||||
image: pbrinkmeier/factorio
|
||||
build: .
|
||||
restart: always
|
||||
environment:
|
||||
GAME_PASSWORD: "${GAME_PASSWORD}"
|
||||
volumes:
|
||||
- /var/lib/pbri/docker/factorio:/factorio
|
||||
ports:
|
||||
- "34197:34197/udp"
|
||||
- "27015:27015/tcp"
|
||||
@@ -0,0 +1,72 @@
|
||||
{
|
||||
"name": "le epic factorio server",
|
||||
"description": "Description of the game that will appear in the listing",
|
||||
"tags": ["game", "tags"],
|
||||
|
||||
"_comment_max_players": "Maximum number of players allowed, admins can join even a full server. 0 means unlimited.",
|
||||
"max_players": 0,
|
||||
|
||||
"_comment_visibility": ["public: Game will be published on the official Factorio matching server",
|
||||
"lan: Game will be broadcast on LAN"],
|
||||
"visibility":
|
||||
{
|
||||
"public": false,
|
||||
"lan": false
|
||||
},
|
||||
|
||||
"_comment_credentials": "Your factorio.com login credentials. Required for games with visibility public",
|
||||
"username": "",
|
||||
"password": "",
|
||||
|
||||
"_comment_token": "Authentication token. May be used instead of 'password' above.",
|
||||
"token": "",
|
||||
|
||||
"game_password": "",
|
||||
|
||||
"_comment_require_user_verification": "When set to true, the server will only allow clients that have a valid Factorio.com account",
|
||||
"require_user_verification": false,
|
||||
|
||||
"_comment_max_upload_in_kilobytes_per_second" : "optional, default value is 0. 0 means unlimited.",
|
||||
"max_upload_in_kilobytes_per_second": 0,
|
||||
|
||||
"_comment_max_upload_slots" : "optional, default value is 5. 0 means unlimited.",
|
||||
"max_upload_slots": 5,
|
||||
|
||||
"_comment_minimum_latency_in_ticks": "optional one tick is 16ms in default speed, default value is 0. 0 means no minimum.",
|
||||
"minimum_latency_in_ticks": 0,
|
||||
|
||||
"_comment_max_heartbeats_per_second": "Network tick rate. Maximum rate game updates packets are sent at before bundling them together. Minimum value is 6, maximum value is 240.",
|
||||
"max_heartbeats_per_second": 60,
|
||||
|
||||
"_comment_ignore_player_limit_for_returning_players": "Players that played on this map already can join even when the max player limit was reached.",
|
||||
"ignore_player_limit_for_returning_players": false,
|
||||
|
||||
"_comment_allow_commands": "possible values are, true, false and admins-only",
|
||||
"allow_commands": "admins-only",
|
||||
|
||||
"_comment_autosave_interval": "Autosave interval in minutes",
|
||||
"autosave_interval": 10,
|
||||
|
||||
"_comment_autosave_slots": "server autosave slots, it is cycled through when the server autosaves.",
|
||||
"autosave_slots": 5,
|
||||
|
||||
"_comment_afk_autokick_interval": "How many minutes until someone is kicked when doing nothing, 0 for never.",
|
||||
"afk_autokick_interval": 5,
|
||||
|
||||
"_comment_auto_pause": "Whether should the server be paused when no players are present.",
|
||||
"auto_pause": true,
|
||||
|
||||
"only_admins_can_pause_the_game": true,
|
||||
|
||||
"_comment_autosave_only_on_server": "Whether autosaves should be saved only on server or also on all connected clients. Default is true.",
|
||||
"autosave_only_on_server": true,
|
||||
|
||||
"_comment_non_blocking_saving": "Highly experimental feature, enable only at your own risk of losing your saves. On UNIX systems, server will fork itself to create an autosave. Autosaving on connected Windows clients will be disabled regardless of autosave_only_on_server option.",
|
||||
"non_blocking_saving": false,
|
||||
|
||||
"_comment_segment_sizes": "Long network messages are split into segments that are sent over multiple ticks. Their size depends on the number of peers currently connected. Increasing the segment size will increase upload bandwidth requirement for the server and download bandwidth requirement for clients. This setting only affects server outbound messages. Changing these settings can have a negative impact on connection stability for some clients.",
|
||||
"minimum_segment_size": 25,
|
||||
"minimum_segment_size_peer_count": 20,
|
||||
"maximum_segment_size": 100,
|
||||
"maximum_segment_size_peer_count": 10
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
FROM gitea/act_runner:0.2.5
|
||||
|
||||
COPY runner-config.yaml /opt/runner-config.yaml
|
||||
@@ -0,0 +1,17 @@
|
||||
# gitea
|
||||
|
||||
Add a `.env` file like this:
|
||||
|
||||
```
|
||||
GITEA_DB_PASSWORD=...
|
||||
GITEA_SMTP_PASSWORD=...
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN=...
|
||||
```
|
||||
|
||||
You should keep an eye on `GITEA_RUNNER_REGISTRATION_TOKEN`. I suspect
|
||||
it might change over time, e.g. when restarting or updating Gitea.
|
||||
|
||||
## Files
|
||||
|
||||
- `runner-config.yaml`: Configuration for `gitea/act_runner`. Generated using `act_runner generate-config` then adjusted
|
||||
- `Dockerfile`: Creates an image based on `gitea/act_runner` that comes with `runner-config.yaml` in `/opt` (to avoid the extra mount)
|
||||
@@ -2,8 +2,8 @@ version: "3"
|
||||
|
||||
services:
|
||||
gitea:
|
||||
image: gitea/gitea:1.17.1
|
||||
restart: always
|
||||
image: gitea/gitea:1.20.3
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
# Ref: https://docs.gitea.io/en-us/config-cheat-sheet
|
||||
# User is created by misc-docker.yaml
|
||||
@@ -35,12 +35,17 @@ services:
|
||||
GITEA__service__DEFAULT_ENABLE_TIMETRACKING: "false"
|
||||
GITEA__service__DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME: "false"
|
||||
GITEA__mailer__ENABLED: "true"
|
||||
GITEA__mailer__HOST: smtp.mailbox.org:465
|
||||
GITEA__mailer__PROTOCOL: smtps
|
||||
GITEA__mailer__SMTP_ADDR: smtp.mailbox.org
|
||||
GITEA__mailer__SMTP_HOST: 465
|
||||
GITEA__mailer__FROM: git@pbrinkmeier.de
|
||||
GITEA__mailer__USER: hallo@pbrinkmeier.de
|
||||
GITEA__mailer__PASSWD: "${GITEA_SMTP_PASSWORD}"
|
||||
GITEA__openid__ENABLE_OPENID_SIGNIN: "false"
|
||||
GITEA__openid__ENABLE_OPENID_SIGNUP: "false"
|
||||
# Enable Gitea actions
|
||||
# Ref: https://docs.gitea.com/usage/actions/quickstart
|
||||
GITEA__actions__ENABLED: "true"
|
||||
volumes:
|
||||
- /var/lib/pbri/docker/gitea:/data
|
||||
- /etc/timezone:/etc/timezone:ro
|
||||
@@ -52,7 +57,7 @@ services:
|
||||
|
||||
gitea_db:
|
||||
image: postgres:14.5-alpine
|
||||
restart: always
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
POSTGRES_DB: gitea
|
||||
POSTGRES_USER: gitea
|
||||
@@ -60,6 +65,21 @@ services:
|
||||
volumes:
|
||||
- /var/lib/pbri/docker/gitea_db:/var/lib/postgresql/data
|
||||
|
||||
gitea_runner:
|
||||
image: pbrinkmeier/act_runner:0.2.5
|
||||
build: .
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
CONFIG_FILE: /opt/runner-config.yaml
|
||||
GITEA_INSTANCE_URL: "https://git.pbrinkmeier.de"
|
||||
GITEA_RUNNER_REGISTRATION_TOKEN: "${GITEA_RUNNER_REGISTRATION_TOKEN}"
|
||||
GITEA_RUNNER_NAME: "basic-bitchboy"
|
||||
volumes:
|
||||
- /var/lib/pbri/docker/gitea_runner_data:/data
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
depends_on:
|
||||
- gitea
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: caddy-network
|
||||
@@ -0,0 +1,85 @@
|
||||
log:
|
||||
# The level of logging, can be trace, debug, info, warn, error, fatal
|
||||
level: info
|
||||
|
||||
runner:
|
||||
# Where to store the registration result.
|
||||
file: .runner
|
||||
# Execute how many tasks concurrently at the same time.
|
||||
capacity: 1
|
||||
# Extra environment variables to run jobs.
|
||||
# envs:
|
||||
# A_TEST_ENV_NAME_1: a_test_env_value_1
|
||||
# A_TEST_ENV_NAME_2: a_test_env_value_2
|
||||
# Extra environment variables to run jobs from a file.
|
||||
# It will be ignored if it's empty or the file doesn't exist.
|
||||
# env_file: .env
|
||||
# The timeout for a job to be finished.
|
||||
# Please note that the Gitea instance also has a timeout (3h by default) for the job.
|
||||
# So the job could be stopped by the Gitea instance if it's timeout is shorter than this.
|
||||
timeout: 3h
|
||||
# Whether skip verifying the TLS certificate of the Gitea instance.
|
||||
insecure: false
|
||||
# The timeout for fetching the job from the Gitea instance.
|
||||
fetch_timeout: 5s
|
||||
# The interval for fetching the job from the Gitea instance.
|
||||
fetch_interval: 2s
|
||||
# The labels of a runner are used to determine which jobs the runner can run, and how to run them.
|
||||
# Like: ["macos-arm64:host", "ubuntu-latest:docker://node:16-bullseye", "ubuntu-22.04:docker://node:16-bullseye"]
|
||||
# If it's empty when registering, it will ask for inputting labels.
|
||||
# If it's empty when execute `deamon`, will use labels in `.runner` file.
|
||||
# Some (most?) GitHub actions use node for scripting, so just using
|
||||
# ubuntu:22.04 here is not enough.
|
||||
labels:
|
||||
- "ubuntu-22.04:docker://node:16-bullseye"
|
||||
|
||||
cache:
|
||||
# Enable cache server to use actions/cache.
|
||||
enabled: false
|
||||
# The directory to store the cache data.
|
||||
# If it's empty, the cache data will be stored in $HOME/.cache/actcache.
|
||||
dir: ""
|
||||
# The host of the cache server.
|
||||
# It's not for the address to listen, but the address to connect from job containers.
|
||||
# So 0.0.0.0 is a bad choice, leave it empty to detect automatically.
|
||||
host: ""
|
||||
# The port of the cache server.
|
||||
# 0 means to use a random available port.
|
||||
port: 0
|
||||
# The external cache server URL. Valid only when enable is true.
|
||||
# If it's specified, act_runner will use this URL as the ACTIONS_CACHE_URL rather than start a server by itself.
|
||||
# The URL should generally end with "/".
|
||||
external_server: ""
|
||||
|
||||
container:
|
||||
# Specifies the network to which the container will connect.
|
||||
# Could be host, bridge or the name of a custom network.
|
||||
# If it's empty, act_runner will create a network automatically.
|
||||
network: ""
|
||||
# Whether to use privileged mode or not when launching task containers (privileged mode is required for Docker-in-Docker).
|
||||
privileged: false
|
||||
# And other options to be used when the container is started (eg, --add-host=my.gitea.url:host-gateway).
|
||||
options:
|
||||
# The parent directory of a job's working directory.
|
||||
# If it's empty, /workspace will be used.
|
||||
workdir_parent:
|
||||
# Volumes (including bind mounts) can be mounted to containers. Glob syntax is supported, see https://github.com/gobwas/glob
|
||||
# You can specify multiple volumes. If the sequence is empty, no volumes can be mounted.
|
||||
# For example, if you only allow containers to mount the `data` volume and all the json files in `/src`, you should change the config to:
|
||||
# valid_volumes:
|
||||
# - data
|
||||
# - /src/*.json
|
||||
# If you want to allow any volume, please use the following configuration:
|
||||
# valid_volumes:
|
||||
# - '**'
|
||||
valid_volumes: []
|
||||
# overrides the docker client host with the specified one.
|
||||
# If it's empty, act_runner will find an available docker host automatically.
|
||||
# If it's "-", act_runner will find an available docker host automatically, but the docker host won't be mounted to the job containers and service containers.
|
||||
# If it's not empty or "-", the specified docker host will be used. An error will be returned if it doesn't work.
|
||||
docker_host: ""
|
||||
|
||||
host:
|
||||
# The parent directory of a job's working directory.
|
||||
# If it's empty, $HOME/.cache/act/ will be used.
|
||||
workdir_parent:
|
||||
@@ -0,0 +1,11 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
glebby:
|
||||
image: git.pbrinkmeier.de/paul/glebby:1.1-prod
|
||||
restart: always
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: caddy-network
|
||||
external: true
|
||||
@@ -0,0 +1,15 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
jupyter:
|
||||
image: git.pbrinkmeier.de/paul/jup:1.5
|
||||
user: "42000"
|
||||
volumes:
|
||||
- /var/lib/pbri/docker/jupyter_data:/data
|
||||
- /var/lib/pbri/docker/jupyter_notebooks:/notebooks
|
||||
restart: always
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: caddy-network
|
||||
external: true
|
||||
@@ -0,0 +1,16 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
score:
|
||||
image: ghcr.io/lbrocke/score:v1.0.2
|
||||
user: "42003:42003"
|
||||
environment:
|
||||
SCORE_LISTEN: 0.0.0.0:8080
|
||||
volumes:
|
||||
- /var/lib/pbri/docker/score:/data
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: caddy-network
|
||||
external: true
|
||||
@@ -0,0 +1,11 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
utoy:
|
||||
image: git.pbrinkmeier.de/paul/utoy:0.6
|
||||
restart: always
|
||||
|
||||
networks:
|
||||
default:
|
||||
name: caddy-network
|
||||
external: true
|
||||
@@ -0,0 +1,20 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
35633339346331336263653239623234333765623065313466373635353662306632663063323138
|
||||
3138333732376665636531396335393235653538393438660a326664656462383737383735386262
|
||||
34646634653631613333656132663536653337386362303536626634363239663064383564633663
|
||||
3563383663383266610a613938376665353936643361366465393765313666636531663837383036
|
||||
34373064616662363839396233623232643134366361313130636433356237323565636338306435
|
||||
36333139356635376366643538303736306364383764393365663365643137383439376636376561
|
||||
65343036363538393235333434316632393562613735313165636165666662326462663063356532
|
||||
34343936356364643536313230383633396438363638623963643239643638633435353164623635
|
||||
35646631353364663261633862666331636532663762636164663861303262373630643265623239
|
||||
62333737393562376235373430363662613032623436303865613634636436376565363130366532
|
||||
36303834343439333865313037336233323036373833663837303332393330306434373431363961
|
||||
30323134373666376563316661303131306566393830633732313664653039313263613761346262
|
||||
34393738376434313663336231656132386163663665393133363465366230383537656630313563
|
||||
66373633333663653837336439646363646233326233303062643635396531356438363433633131
|
||||
36353561366265343036386533373563613836663831613836643432386633643535396536376362
|
||||
65306335313363316236363362316533663433656531366331336132303965373230623330313636
|
||||
38623361623934303663333631306330333434343833336132333333313939616261666461346333
|
||||
34343935663165303665373735646636326364393336626462363732353739366161366164333465
|
||||
643034323233333535376461313834663132
|
||||
@@ -0,0 +1,14 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
31333834393366333930346366373931333930646233383664643463393965303238613430646638
|
||||
6461373434616433353337643131396462326537346434380a386562633335346436303662336362
|
||||
62333739626237323334333666633162616338313932393261303231353539623237383638643030
|
||||
3364393934653232310a383065386530373433393635313665353532666361303436613337316565
|
||||
32306233336134383531633232393862303466373331373764376462653736663861663366323762
|
||||
65666263366461396362386264613830336435346234386234333562616131653938386439336566
|
||||
34386461343433346363336161373038303434383563303564653533623939613937323030636362
|
||||
66636639643963613236366138646335393831366432333637333065326162646237643561336666
|
||||
61323833333337633861646462393930663733333266336233663630396532366566303835653431
|
||||
38363365383166393765343735363030363562313837643837313864373735643264663264643633
|
||||
66306261633666616363666562306632613032373231633730313638383033633761653661383738
|
||||
39623630643766663438656635653530626664313765633430646330356333306239653437373839
|
||||
3933
|
||||
@@ -0,0 +1,7 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
32356463313330336636636363646138393236636233326132623165353962623565356364396530
|
||||
3636336532396665333637653432353332643434643962390a313162343836306435383536313937
|
||||
36656632356366303561366536373535383538303730386239386437323466346533353634306436
|
||||
3930633464353235360a653936333734353137313363316261366666353238366566613865366463
|
||||
32393431343439383733343766323831643561663938376264336331306139646337343633346536
|
||||
3236343538323032636666366639303539316236393535323661
|
||||
@@ -0,0 +1,14 @@
|
||||
$ANSIBLE_VAULT;1.1;AES256
|
||||
35623364633833623964623536646534373634663736613561333561343136333965306638396532
|
||||
6162393239383936386338666565306132646230383066630a336337613636383431623738343663
|
||||
61343262363631376665383035323139313863626331666439336134613035663439376231343863
|
||||
3032353139643138640a383365356630323835383538393734643134343133653033383663333464
|
||||
62386361633435633664306531623835353665326432393932336163316561653866343137323030
|
||||
63643262323436356166373533363235366238393633336631336266373837373932313134303563
|
||||
65633337393938623134636538653561356565333831356638373862376333336163363438626438
|
||||
39343436383732313561396236656530303064363961663636353538346264633532633866333162
|
||||
35303032303662646166333537373566316462633536333463323433353539623363323036643763
|
||||
34376365613932303133366236613235636238643139666663356436326532616437383432303437
|
||||
39376535656266383465373837643634383937656431323265386163373138336164383666383962
|
||||
64623762613332363731323739666238613634646237396331666463363663313461313966356233
|
||||
30653362353061333739303234336461373337346632646433623462623765353330
|
||||
@@ -1,6 +0,0 @@
|
||||
Add a `.env` file like this:
|
||||
|
||||
```
|
||||
GITEA_DB_PASSWORD=...
|
||||
GITEA_SMTP_PASSWORD=...
|
||||
```
|
||||
Generated
+140
@@ -0,0 +1,140 @@
|
||||
{
|
||||
"nodes": {
|
||||
"agenix": {
|
||||
"inputs": {
|
||||
"darwin": "darwin",
|
||||
"home-manager": "home-manager",
|
||||
"nixpkgs": "nixpkgs"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1696775529,
|
||||
"narHash": "sha256-TYlE4B0ktPtlJJF9IFxTWrEeq+XKG8Ny0gc2FGEAdj0=",
|
||||
"owner": "ryantm",
|
||||
"repo": "agenix",
|
||||
"rev": "daf42cb35b2dc614d1551e37f96406e4c4a2d3e4",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "ryantm",
|
||||
"repo": "agenix",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"darwin": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"agenix",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1673295039,
|
||||
"narHash": "sha256-AsdYgE8/GPwcelGgrntlijMg4t3hLFJFCRF3tL5WVjA=",
|
||||
"owner": "lnl7",
|
||||
"repo": "nix-darwin",
|
||||
"rev": "87b9d090ad39b25b2400029c64825fc2a8868943",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "lnl7",
|
||||
"ref": "master",
|
||||
"repo": "nix-darwin",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"flake-utils": {
|
||||
"inputs": {
|
||||
"systems": "systems"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1685518550,
|
||||
"narHash": "sha256-o2d0KcvaXzTrPRIo0kOLV0/QXHhDQ5DTi+OxcjO8xqY=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "a1720a10a6cfe8234c0e93907ffe81be440f4cef",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"home-manager": {
|
||||
"inputs": {
|
||||
"nixpkgs": [
|
||||
"agenix",
|
||||
"nixpkgs"
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1682203081,
|
||||
"narHash": "sha256-kRL4ejWDhi0zph/FpebFYhzqlOBrk0Pl3dzGEKSAlEw=",
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"rev": "32d3e39c491e2f91152c84f8ad8b003420eab0a1",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-community",
|
||||
"repo": "home-manager",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1677676435,
|
||||
"narHash": "sha256-6FxdcmQr5JeZqsQvfinIMr0XcTyTuR7EXX0H3ANShpQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "a08d6979dd7c82c4cef0dcc6ac45ab16051c1169",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "NixOS",
|
||||
"ref": "nixos-unstable",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"nixpkgs_2": {
|
||||
"locked": {
|
||||
"lastModified": 1686259070,
|
||||
"narHash": "sha256-bJ2TqJHMdU27o3+AlYzsDooUzneFHwvK5LaRv5JYit4=",
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "8a7d5c039cacc83bd1926aaabc04d541e04a1460",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nixos",
|
||||
"repo": "nixpkgs",
|
||||
"type": "github"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"agenix": "agenix",
|
||||
"flake-utils": "flake-utils",
|
||||
"nixpkgs": "nixpkgs_2"
|
||||
}
|
||||
},
|
||||
"systems": {
|
||||
"locked": {
|
||||
"lastModified": 1681028828,
|
||||
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "nix-systems",
|
||||
"repo": "default",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
description = "infrastructure environment";
|
||||
|
||||
inputs = {
|
||||
# lib
|
||||
nixpkgs.url = github:nixos/nixpkgs;
|
||||
flake-utils.url = github:numtide/flake-utils;
|
||||
agenix.url = github:ryantm/agenix;
|
||||
};
|
||||
|
||||
outputs = { self, nixpkgs, flake-utils, agenix }: flake-utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
in
|
||||
{
|
||||
devShells.default = pkgs.mkShell {
|
||||
buildInputs = [
|
||||
pkgs.ansible
|
||||
pkgs.ansible-lint
|
||||
agenix.packages.${system}.default
|
||||
];
|
||||
|
||||
shellHook = ''
|
||||
PS1="(infra) $PS1"
|
||||
'';
|
||||
};
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
# `gilgamesh`
|
||||
|
||||
> Old Thinkpad running a Minecraft server.
|
||||
|
||||
## TODO
|
||||
|
||||
- Figure out if there's some more powersaving options
|
||||
- Add some doc for initial setup
|
||||
- Install NixOS according to the official guide
|
||||
- Check out this repo, build this `configuration.nix`
|
||||
- Afterwards: Just build it locally then deploy
|
||||
- Use Flakes, add doc for `./deploy.sh`
|
||||
@@ -0,0 +1,146 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
agenix = builtins.fetchTarball {
|
||||
url = "https://github.com/ryantm/agenix/archive/daf42cb35b2dc614d1551e37f96406e4c4a2d3e4.tar.gz";
|
||||
sha256 = "0gbn01hi8dh7s9rc66yawnmixcasadf20zci4ijzpd143ph492ad";
|
||||
};
|
||||
in {
|
||||
imports =
|
||||
[ # Include the results of the hardware scan.
|
||||
./hardware-configuration.nix
|
||||
"${agenix}/modules/age.nix"
|
||||
../modules/spigot-server.nix
|
||||
../modules/ionos-dyndns.nix
|
||||
];
|
||||
|
||||
# Use the GRUB 2 boot loader.
|
||||
boot.loader.grub.enable = true;
|
||||
# boot.loader.grub.efiSupport = true;
|
||||
# boot.loader.grub.efiInstallAsRemovable = true;
|
||||
# boot.loader.efi.efiSysMountPoint = "/boot/efi";
|
||||
# Define on which hard drive you want to install Grub.
|
||||
boot.loader.grub.device = "/dev/sda";
|
||||
|
||||
networking.hostName = "gilgamesh"; # Define your hostname.
|
||||
# Pick only one of the below networking options.
|
||||
# networking.wireless.enable = true; # Enables wireless support via wpa_supplicant.
|
||||
# networking.networkmanager.enable = true; # Easiest to use and most distros use this by default.
|
||||
|
||||
# Set your time zone.
|
||||
time.timeZone = "Europe/Berlin";
|
||||
|
||||
# Configure network proxy if necessary
|
||||
# networking.proxy.default = "http://user:password@proxy:port/";
|
||||
# networking.proxy.noProxy = "127.0.0.1,localhost,internal.domain";
|
||||
|
||||
# Select internationalisation properties.
|
||||
i18n.defaultLocale = "en_US.UTF-8";
|
||||
console = {
|
||||
font = "Lat2-Terminus16";
|
||||
keyMap = "de-latin1";
|
||||
};
|
||||
|
||||
# Define a user account. Don't forget to set a password with ‘passwd’.
|
||||
users.users.paul = {
|
||||
isNormalUser = true;
|
||||
extraGroups = [ "wheel" ]; # Enable ‘sudo’ for the user.
|
||||
openssh.authorizedKeys.keys = [
|
||||
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIMFqREiw3EareYXntIrm1/numKDo113zx1WMOFO69LJ paul"
|
||||
];
|
||||
# packages = with pkgs; [];
|
||||
};
|
||||
|
||||
# Users in group wheel may sudo without password
|
||||
security.sudo.wheelNeedsPassword = false;
|
||||
|
||||
# Users in group wheel are special friends of the Nix daemon
|
||||
nix.settings.trusted-users = [
|
||||
"@wheel"
|
||||
];
|
||||
|
||||
# List packages installed in system profile. To search, run:
|
||||
# $ nix search wget
|
||||
environment.systemPackages = with pkgs; [
|
||||
vim
|
||||
tmux
|
||||
bottom
|
||||
(pkgs.callPackage ../packages/ionos-dyndns.nix {})
|
||||
];
|
||||
|
||||
# List services that you want to enable:
|
||||
|
||||
# Enable the OpenSSH daemon.
|
||||
services.openssh = {
|
||||
enable = true;
|
||||
settings = {
|
||||
PasswordAuthentication = false;
|
||||
KbdInteractiveAuthentication = false;
|
||||
};
|
||||
};
|
||||
|
||||
# Enable Avahi for mDNS (advertise hostname in LAN)
|
||||
services.avahi = {
|
||||
enable = true;
|
||||
nssmdns = true;
|
||||
};
|
||||
|
||||
services.spigot-server = {
|
||||
enable = true;
|
||||
user = "spigot";
|
||||
};
|
||||
|
||||
# Secrets management
|
||||
age.secrets = {
|
||||
ionos-prefix = {
|
||||
file = ../secrets/ionos-prefix.age;
|
||||
owner = "ionos-dyndns";
|
||||
group = "ionos-dyndns";
|
||||
};
|
||||
ionos-secret = {
|
||||
file = ../secrets/ionos-secret.age;
|
||||
owner = "ionos-dyndns";
|
||||
group = "ionos-dyndns";
|
||||
};
|
||||
};
|
||||
|
||||
# DynDNS stuff. IONOS has a (proprietary?) API for this,
|
||||
# so we're using a Python script from the interwebs :shrug:
|
||||
services.ionos-dyndns = {
|
||||
enable = true;
|
||||
# Must match the user owning the secrets below. See agenix config
|
||||
# above for more details.
|
||||
user = "ionos-dyndns";
|
||||
apiPrefixPath = config.age.secrets.ionos-prefix.path;
|
||||
apiSecretPath = config.age.secrets.ionos-secret.path;
|
||||
aaaa = true;
|
||||
fqdn = "blocks.beany.club";
|
||||
interface = "enp0s25";
|
||||
};
|
||||
|
||||
# Open ports in the firewall.
|
||||
networking.firewall.allowedTCPPorts = [ 25565 ];
|
||||
networking.firewall.allowedUDPPorts = [ 25565 ];
|
||||
# Or disable the firewall altogether.
|
||||
# networking.firewall.enable = false;
|
||||
|
||||
# TODO: Backups
|
||||
|
||||
# Practical hardware options
|
||||
services.logind.lidSwitch = "ignore";
|
||||
powerManagement.cpuFreqGovernor = lib.mkDefault "powersave";
|
||||
|
||||
# Copy the NixOS configuration file and link it from the resulting system
|
||||
# (/run/current-system/configuration.nix). This is useful in case you
|
||||
# accidentally delete configuration.nix.
|
||||
# system.copySystemConfiguration = true;
|
||||
|
||||
# This value determines the NixOS release from which the default
|
||||
# settings for stateful data, like file locations and database versions
|
||||
# on your system were taken. It's perfectly fine and recommended to leave
|
||||
# this value at the release version of the first install of this system.
|
||||
# Before changing this value read the documentation for this option
|
||||
# (e.g. man configuration.nix or on https://nixos.org/nixos/options.html).
|
||||
system.stateVersion = "23.05"; # Did you read the comment?
|
||||
|
||||
}
|
||||
|
||||
Executable
+3
@@ -0,0 +1,3 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
nixos-rebuild -I nixos-config=configuration.nix --target-host gilgamesh --use-remote-sudo switch
|
||||
@@ -0,0 +1,33 @@
|
||||
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||
# and may be overwritten by future invocations. Please make changes
|
||||
# to /etc/nixos/configuration.nix instead.
|
||||
{ config, lib, pkgs, modulesPath, ... }:
|
||||
|
||||
{
|
||||
imports =
|
||||
[ (modulesPath + "/installer/scan/not-detected.nix")
|
||||
];
|
||||
|
||||
boot.initrd.availableKernelModules = [ "ehci_pci" "ahci" "usb_storage" "sd_mod" "sdhci_pci" ];
|
||||
boot.initrd.kernelModules = [ ];
|
||||
boot.kernelModules = [ "kvm-intel" ];
|
||||
boot.extraModulePackages = [ ];
|
||||
|
||||
fileSystems."/" =
|
||||
{ device = "/dev/disk/by-label/NIXROOT";
|
||||
fsType = "ext4";
|
||||
};
|
||||
|
||||
swapDevices = [ ];
|
||||
|
||||
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||
# still possible to use this option, but it's recommended to use it in conjunction
|
||||
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||
networking.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.enp0s25.useDHCP = lib.mkDefault true;
|
||||
# networking.interfaces.wlp3s0.useDHCP = lib.mkDefault true;
|
||||
|
||||
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||
hardware.cpu.intel.updateMicrocode = lib.mkDefault config.hardware.enableRedistributableFirmware;
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
cfg = config.services.ionos-dyndns;
|
||||
ionos-dyndns = pkgs.callPackage ../packages/ionos-dyndns.nix {};
|
||||
|
||||
command = lib.concatStringsSep " " (
|
||||
[
|
||||
"${ionos-dyndns}/bin/ionos-dyndns"
|
||||
"--api-prefix"
|
||||
"$(cat ${cfg.apiPrefixPath})"
|
||||
"--api-secret"
|
||||
"$(cat ${cfg.apiSecretPath})"
|
||||
"--fqdn"
|
||||
cfg.fqdn
|
||||
"--interface"
|
||||
cfg.interface
|
||||
]
|
||||
++ lib.optionals cfg.a [ "--A" ]
|
||||
++ lib.optionals cfg.aaaa [ "--AAAA" ]
|
||||
);
|
||||
in {
|
||||
options = {
|
||||
services.ionos-dyndns = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to turn on the IONOS DynDNS timer.
|
||||
'';
|
||||
};
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "ionos-dyndns";
|
||||
};
|
||||
apiPrefixPath = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path of a file holding the API prefix.
|
||||
'';
|
||||
};
|
||||
apiSecretPath = mkOption {
|
||||
type = types.path;
|
||||
description = ''
|
||||
Path of a file holding the API secret.
|
||||
'';
|
||||
};
|
||||
a = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to set the A record (IPv4).
|
||||
'';
|
||||
};
|
||||
aaaa = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to set the AAAA record (IPv6).
|
||||
'';
|
||||
};
|
||||
fqdn = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Fully qualified domain name for this host.
|
||||
'';
|
||||
};
|
||||
interface = mkOption {
|
||||
type = types.str;
|
||||
description = ''
|
||||
Interface to get the IP address from.
|
||||
'';
|
||||
};
|
||||
interval = mkOption {
|
||||
type = types.str;
|
||||
default = "14min";
|
||||
description = "How often to run the update script in systemd.timers notation.";
|
||||
};
|
||||
serviceName = mkOption {
|
||||
type = types.str;
|
||||
default = "ionos-dyndns";
|
||||
};
|
||||
};
|
||||
};
|
||||
config = mkIf cfg.enable {
|
||||
users = {
|
||||
users = {
|
||||
${cfg.user} = {
|
||||
isSystemUser = true;
|
||||
group = cfg.user;
|
||||
description = "IONOS DynDNS user.";
|
||||
};
|
||||
};
|
||||
groups = {
|
||||
${cfg.user} = {
|
||||
};
|
||||
};
|
||||
};
|
||||
systemd = {
|
||||
services.${cfg.serviceName} = {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = cfg.user;
|
||||
# We assume that command doesn't contain any single quotes
|
||||
ExecStart = "${pkgs.bash}/bin/bash -c '${command}'";
|
||||
};
|
||||
};
|
||||
timers.${cfg.serviceName} = {
|
||||
wantedBy = [ "timers.target" ];
|
||||
timerConfig = {
|
||||
Unit = "${cfg.serviceName}.service";
|
||||
OnBootSec = "30s";
|
||||
OnActiveSec = cfg.interval;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
with lib;
|
||||
let
|
||||
spigot-server = pkgs.callPackage ../packages/spigot-server.nix {};
|
||||
cfg = config.services.spigot-server;
|
||||
StateDirectory = "spigot-server";
|
||||
in {
|
||||
options = {
|
||||
services.spigot-server = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Whether to turn on the Spigot Minecraft server.
|
||||
'';
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "spigot-server";
|
||||
description = ''
|
||||
The user account and group that Spigot runs as.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
users.users = {
|
||||
${cfg.user} = {
|
||||
isSystemUser = true;
|
||||
group = cfg.user;
|
||||
description = "Spigot Minecraft server user";
|
||||
};
|
||||
};
|
||||
users.groups = {
|
||||
${cfg.user} = {
|
||||
};
|
||||
};
|
||||
|
||||
systemd = {
|
||||
services.spigot-server = {
|
||||
description = "Spigot Minecraft server";
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
after = [ "network.target" ];
|
||||
serviceConfig = {
|
||||
User = "${cfg.user}";
|
||||
|
||||
Sockets = "spigot-server.socket";
|
||||
StandardInput = "socket";
|
||||
StandardOutput = "journal";
|
||||
StandardError = "journal";
|
||||
|
||||
inherit StateDirectory;
|
||||
WorkingDirectory = "/var/lib/${StateDirectory}";
|
||||
ExecStart = "${spigot-server}/bin/spigot-server -nogui";
|
||||
ExecStop = [
|
||||
"${pkgs.bash}/bin/bash -c '${pkgs.coreutils}/bin/echo save-all > /run/spigot-server.stdin'"
|
||||
"${pkgs.bash}/bin/bash -c '${pkgs.coreutils}/bin/echo stop > /run/spigot-server.stdin'"
|
||||
# Wait for the main process to exit
|
||||
# If we don't do this systemd tries to nudge Java to stop, causing a race condition
|
||||
# that leads to an ungraceful shutdown
|
||||
"${pkgs.coreutils}/bin/echo \"Waiting for \${MAINPID} to exit...\""
|
||||
"${pkgs.bash}/bin/bash -c 'while ${pkgs.coreutils}/bin/kill -s 0 $MAINPID 2>/dev/null; do sleep 0.5; done'"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
sockets.spigot-server = {
|
||||
description = "Spigot Minecraft server socket for commands and stuff";
|
||||
unitConfig = {
|
||||
# Automatically start and stop socket along with the service
|
||||
PartOf = "spigot-server.service";
|
||||
};
|
||||
socketConfig = {
|
||||
ListenFIFO = "/run/spigot-server.stdin";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
spigot-1.20.1.jar
|
||||
@@ -0,0 +1,11 @@
|
||||
# Packages
|
||||
|
||||
## `spigot-server`
|
||||
|
||||
In order to build `spigot-server.nix` you'll need a copy of the Spigot JAR.
|
||||
For licensing reasons I won't check it into Git.
|
||||
Just drop `spigot-${version}.jar` into this folder and change the `version = ` line in `spigot-server.nix` accordingly.
|
||||
|
||||
## TODO
|
||||
|
||||
- Make some more stuff in `spigot-server.nix` configurable
|
||||
@@ -0,0 +1,37 @@
|
||||
{
|
||||
fetchFromGitHub,
|
||||
lib,
|
||||
makeWrapper,
|
||||
stdenv,
|
||||
# Runtime Dependencies
|
||||
python3,
|
||||
# grep
|
||||
gnugrep,
|
||||
# ip
|
||||
iproute2,
|
||||
# hostname
|
||||
hostname
|
||||
}:
|
||||
let
|
||||
pythonWithDeps = python3.withPackages (p: [p.requests]);
|
||||
in stdenv.mkDerivation rec {
|
||||
pname = "ionos-dyndns";
|
||||
# Packaging time, not commit time
|
||||
version = "20231118";
|
||||
src = fetchFromGitHub {
|
||||
owner = "lazaroblanc";
|
||||
repo = "IONOS-DynDNS";
|
||||
rev = "6c090ab928ce8d6eaa28b09614995b036ad60027";
|
||||
hash = "sha256-rabDuKuPvzcMltnCSvc5kDjcDhv7sXxbDLWw3/hdSmk=";
|
||||
};
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
||||
buildCommand = ''
|
||||
install -Dm755 $src/ionos_dyndns.py $out/lib/ionos_dyndns.py
|
||||
|
||||
makeWrapper ${pythonWithDeps}/bin/python3 $out/bin/ionos-dyndns \
|
||||
--set PATH ${lib.makeBinPath [ iproute2 gnugrep hostname ]} \
|
||||
--add-flags $out/lib/ionos_dyndns.py
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
makeWrapper,
|
||||
stdenv,
|
||||
# Runtime Dependencies
|
||||
jre
|
||||
}:
|
||||
let
|
||||
# Copied from some forum thread without much thought.
|
||||
# Let's see if they work out.
|
||||
javaFlags = "-Xmx5G -XX:+UseG1GC -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=50 -XX:+DisableExplicitGC -XX:TargetSurvivorRatio=90 -XX:G1NewSizePercent=50 -XX:G1MaxNewSizePercent=80 -XX:InitiatingHeapOccupancyPercent=10 -XX:G1MixedGCLiveThresholdPercent=50";
|
||||
in stdenv.mkDerivation rec {
|
||||
pname = "spigot-server";
|
||||
version = "1.20.1";
|
||||
src = ./spigot-${version}.jar;
|
||||
|
||||
nativeBuildInputs = [ makeWrapper ];
|
||||
|
||||
buildCommand = ''
|
||||
install -Dm644 $src $out/lib/spigot-${version}.jar
|
||||
|
||||
makeWrapper ${jre}/bin/java $out/bin/spigot-server \
|
||||
--argv0 spigot-server \
|
||||
--add-flags "${javaFlags}" \
|
||||
--add-flags "-jar $out/lib/spigot-${version}.jar"
|
||||
'';
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
# secrets
|
||||
|
||||
> Nix configuration secrets managed with [agenix](https://github.com/ryantm/agenix#tutorial).
|
||||
|
||||
Use `nix develop` in the repository root to drop into a shell with `agenix`.
|
||||
|
||||
## Editing files
|
||||
|
||||
```
|
||||
agenix -e <thingamajig.age>
|
||||
```
|
||||
@@ -0,0 +1,9 @@
|
||||
age-encryption.org/v1
|
||||
-> ssh-ed25519 9V3MUQ 7+lohnPlQALVPEGo2LwS2fj5r2RCKaVeEFmi6EYEyCE
|
||||
9U6eAthRVd5ry0ej79FEy3oRG3okJTwY6zSN1u68H1o
|
||||
-> ssh-ed25519 CcM6/g QQX9SsgKkk8YdUPRKj9Tda8mf6qRJ7ywtP6IIpN9fxo
|
||||
3Ml2+1+AQMwr5Lnv84pYOee/s5mzfVdsHRLaUIAKNFk
|
||||
-> i)!b3gaJ-grease 7|bwS ?k2JgF E-G 2HI
|
||||
0mFbZ22lqvLd
|
||||
--- 0+CwYGJlJC7bRbokHSlv+V4JKppBo+/ocfjp2NQBD3Q
|
||||
JDv�8ě ë�¶ÚŤÄ÷8é V/Ă'O”M¸x×é!ȸTÉA7ÍK5#É8©&•Ř-VqČ&}ů]ráÂ
|
||||
Binary file not shown.
@@ -0,0 +1,10 @@
|
||||
let
|
||||
# Users
|
||||
paul = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIIMFqREiw3EareYXntIrm1/numKDo113zx1WMOFO69LJ";
|
||||
|
||||
# Systems
|
||||
gilgamesh = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPDmLWYK6/4/Fh+wsoiz9+PCHvNcP2/wu2GvfzrqXCGA";
|
||||
in {
|
||||
"ionos-prefix.age".publicKeys = [ paul gilgamesh ];
|
||||
"ionos-secret.age".publicKeys = [ paul gilgamesh ];
|
||||
}
|
||||
Reference in New Issue
Block a user