Author SHA1 Message Date
paul 03c7277692 Fix ionos-dyndns timer interval
Check / Lint Ansible Files (push) Successful in 2m29s
systemd uses min, not m for minutes.
2023-11-20 21:45:13 +01:00
paul de16857570 Remove unused leftover variable 2023-11-19 03:38:50 +01:00
paul f2f12a2688 Add agenix, spigot-server and ionos-dyndns to gilgamesh config
Check / Lint Ansible Files (push) Successful in 3m1s
2023-11-19 03:09:42 +01:00
paul e61a07f8d3 Add ionos-dyndns module for the NixOS config 2023-11-19 03:05:31 +01:00
paul ea38d94178 Add runtime dependencies to ionos-dyndns package 2023-11-19 03:04:52 +01:00
paul 81771725d0 Add agenix secrets for IONOS dyndns 2023-11-19 03:04:01 +01:00
paul 06345cd04c Add agenix to dev flake 2023-11-19 02:59:34 +01:00
paul 9b622e6e3e Number of fixes
Check / Lint Ansible Files (push) Successful in 1m40s
Package IONOS-DynDNS repository

Fix spigot-server's ExecStop

Enable Firewall but allow port 25565
2023-11-18 13:44:10 +01:00
paul 8e0c6266af Add gilgamesh NixOS config and spigot-server package
Check / Lint Ansible Files (push) Successful in 2m18s
2023-11-18 05:28:33 +01:00
paul 11049a04d8 Disable admin interface in Caddy
Check / Lint Ansible Files (push) Successful in 1m32s
2023-09-12 20:51:51 +02:00
paul 483ea954b2 Update TODO
Check / Lint Ansible Files (push) Successful in 1m39s
2023-09-01 03:47:02 +02:00
paul 8fa1f674f9 Implement ansible-lint workflow 2023-09-01 03:47:02 +02:00
paul 2006b9733e Add CI using Gitea actions 2023-09-01 03:47:02 +02:00
paul 0af355843d Add Gitea actions act_runner
continuous-integration/drone/push Build is passing
2023-09-01 01:58:02 +02:00
paul 1b2227af24 Bump Gitea to 1.20.3
continuous-integration/drone/push Build is passing
Enable Gitea actions
2023-09-01 01:08:40 +02:00
paul 85f2e87040 Remove .ipynb rendering 2023-09-01 00:42:49 +02:00
paul d400a4b0e7 Mark system users as such
continuous-integration/drone/push Build is passing
2023-08-31 20:10:07 +02:00
paul 9d148f5f9e Bump factorio server to 1.1.87
continuous-integration/drone Build was killed
2023-08-31 19:58:54 +02:00
paul 836e49f772 Update gitea to 1.20
continuous-integration/drone/push Build is passing
2023-07-17 16:21:27 +02:00
paul 9bd2f16dbb Update and disable factorio server
continuous-integration/drone Build is passing
2023-07-17 15:34:20 +02:00
paul 0510bf6e90 Remove glebby vhost
continuous-integration/drone/push Build is passing
2023-06-12 01:14:05 +02:00
paul aadd803df0 Make score listen on port 8080
continuous-integration/drone/push Build is passing
2023-06-11 23:19:58 +02:00
Lukas Brocke c760b77bfe Bump score to 1.0.2
The image now uses /data for the sqlite database by default, therefore
remove unnecessary configuration options from docker-compose file.
2023-06-11 22:08:33 +02:00
paul 7e446f25eb Bump ansible version in ansible-playbook --check CI step
continuous-integration/drone/push Build is passing
2023-06-09 00:55:46 +02:00
paul 21329ecabd Make CI install ansible package
continuous-integration/drone/push Build is passing
This might fix the community.docker.docker_network missing error
2023-06-09 00:53:43 +02:00
paul 06b673ec89 Apply ansible-lint fixes
continuous-integration/drone/push Build is failing
2023-06-09 00:42:43 +02:00
paul 84bfeb5c32 Add ansible-lint configuration file 2023-06-09 00:42:05 +02:00
paul 083f93ec5f Update nixpkgs
continuous-integration/drone/push Build is failing
2023-06-09 00:32:51 +02:00
paul 552a3c58a6 Add swap files to gitignore 2023-06-09 00:32:21 +02:00
paul 4060c7afba Update ansible-lint version in CI
continuous-integration/drone/push Build is failing
Reduce CI time by telling pip and ansible-lint that they shouldn't check for new versions
2023-06-09 00:27:38 +02:00
paul 6c3bd0f1d4 Add score
continuous-integration/drone/push Build is failing
2023-06-08 23:55:38 +02:00
paul 41b3733482 Bump utoy to 0.6
continuous-integration/drone Build is failing
2023-06-08 21:45:42 +02:00
paul e070e30a4d Bump utoy to 0.5
continuous-integration/drone/push Build is passing
2023-03-24 13:15:49 +01:00
paul 5df3b0ec08 Bump utoy to 0.3
continuous-integration/drone/push Build is passing
2023-03-16 03:27:07 +01:00
paul 92981e0ccf Bump utoy to 0.2
continuous-integration/drone/push Build is passing
2023-03-10 18:55:50 +01:00
paul bae3028751 Add utoy, disable glebby
continuous-integration/drone/push Build is passing
2023-03-09 02:47:03 +01:00
paul d4c58b8763 Change secret sauce :) 2023-03-07 02:02:16 +01:00
paul 05bdddfed7 Bump jup to 1.5 2023-03-07 01:58:34 +01:00
paul 1b61394afd Use vault password secret in CI
continuous-integration/drone/push Build is passing
2023-01-27 04:59:29 +01:00
paul 9f40b38886 Add encrypted .env files 2023-01-27 04:59:12 +01:00
paul a1cac6b8a3 Move docker folder and delete hedgedoc user
continuous-integration/drone/push Build is passing
2023-01-27 04:29:32 +01:00
paul 3f3d619694 Adjust playbooks for check mode
continuous-integration/drone/push Build is passing
2023-01-27 02:55:53 +01:00
paul 0061d7dbf0 Change misc hostname to contabo subdomain
continuous-integration/drone/push Build is failing
2023-01-27 01:47:45 +01:00
paul 7de9db5de0 Move into ansible directory before running the playbook
continuous-integration/drone/push Build is failing
2023-01-27 01:44:20 +01:00
paul 206a43526a Fix typo
continuous-integration/drone/push Build is passing
2023-01-27 01:41:50 +01:00
paul 2f9af8621d Create .ssh directory in check CI step
continuous-integration/drone/push Build is failing
2023-01-27 01:39:11 +01:00
paul 60a455486c Add ansible playbook check step to CI
continuous-integration/drone/push Build is failing
2023-01-27 01:35:43 +01:00
paul b4f6538ffe Add Gitea up check before deploying configs
continuous-integration/drone/push Build is passing
2023-01-19 18:33:45 +01:00
paul d91d332af9 Add glebby
continuous-integration/drone/push Build is passing
2023-01-19 03:02:39 +01:00
paul e677effa5f Update jup version
continuous-integration/drone/push Build is passing
2022-11-13 15:00:07 +01:00
paul 885a41088d Add jupyter server
continuous-integration/drone/push Build is passing
2022-11-02 18:42:02 +01:00
paul f47e4f5c36 Reset pad to hackMD
continuous-integration/drone/push Build is passing
hedgedoc doesn't do PlantUML right now
2022-10-25 15:57:00 +02:00
paul 797b276da4 Update Gitea to 1.17.3 2022-10-25 15:43:32 +02:00
paul 404087a8b0 Use hedgedoc instead of hackmd
Use pad.pbrinkmeier.de instead of codi.pbrinkmeier.de
2022-10-25 15:24:12 +02:00
paul 0a6cd8f866 Authenticate Codi via Gitea not mail
continuous-integration/drone/push Build is passing
2022-10-25 14:37:57 +02:00
paul f9af291df7 Add factorio server
continuous-integration/drone/push Build is passing
2022-10-15 23:51:26 +02:00
paul 4dfc8af94b Update CI config to pin python and ansible-lint versions
continuous-integration/drone/push Build is passing
2022-09-20 23:34:09 +02:00
paul 83dbdcea3e Replace requirements.txt with a Nix flake
continuous-integration/drone/push Build is failing
2022-09-20 23:19:18 +02:00
paul 5474dbe720 Make Gitea display graphs in notebooks
continuous-integration/drone/push Build is passing
2022-09-19 12:54:44 +02:00
paul 2586773680 Update todos 2022-09-19 12:54:12 +02:00
paul 13e48a54c3 Add notebook support to Gitea 2022-09-19 12:53:37 +02:00
paul a71f915e06 Update todos
continuous-integration/drone/push Build is passing
2022-09-15 15:32:24 +02:00
paul 74237d4ea2 Use fully qualified module name
continuous-integration/drone/push Build is passing
2022-09-15 15:20:07 +02:00
paul 0d0ae513f0 Update setup for new VPS shamash
continuous-integration/drone/push Build is failing
2022-09-15 15:16:19 +02:00
paul 045506a9ab Turn shell task into smaller Ansible tasks
continuous-integration/drone/push Build is passing
2022-09-15 13:58:48 +02:00
paul ef9d3d0beb Fix ansible-lint failures
continuous-integration/drone/push Build is passing
2022-09-15 13:48:59 +02:00
paul 9121b5edc0 Replace Nix-based ansible-lint
continuous-integration/drone/push Build is failing
continuous-integration/drone Build is failing
2022-09-15 06:04:38 +02:00
paul 78c13e41a6 Add ansible-lint drone config
continuous-integration/drone/push Build is failing
2022-09-15 05:01:01 +02:00
paul c7bcf2cddf Use Nix instead of virtualenv 2022-09-15 04:57:37 +02:00
paul a86b3e6a43 Move playbooks to playbooks folder 2022-09-15 04:56:14 +02:00
paul 39a18a603d Remove web and runner configs 2022-09-15 03:02:06 +02:00
paul 034465b02d Add codi config 2022-09-15 02:50:00 +02:00
paul 736a19e8d4 Add gitea and drone configs 2022-09-15 02:23:47 +02:00
64 changed files with 1449 additions and 322 deletions
+4
View File
@@ -0,0 +1,4 @@
---
profile: production
offline: true
+15
View File
@@ -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
View File
@@ -1,2 +1,2 @@
*.env
backups backups
*.swp
+9 -14
View File
@@ -4,21 +4,16 @@
| Prop | Value | | Prop | Value |
| --- | --- | | --- | --- |
| Hostname | `h2954114` | | Hostname | `shamash` |
| Domains | `{wiki.,codi.,git.,}pbrinkmeier.de`, `tichy.click`, `h2954114.stratoserver.net` | | 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) to avoid checking for a new version every single run.
### Collaborative Markdown Editing
[codi.pbrinkmeier.de](https://codi.pbrinkmeier.de)
### Tichy-Clicker
[tichy.click](https://tichy.click)
+10 -3
View File
@@ -1,11 +1,18 @@
# TODO # TODO
- [ ] Update Readme (CI, Git, plantuml, etc.) - [ ] Update Readme (CI, Git, plantuml, etc.)
- [ ] Split `docker/web/docker-compose.yaml` into different configs (e.g. `web`, `gitlab`, `drone`) using the same network - [x] Split `docker/web/docker-compose.yaml` into different configs (e.g. `web`, `gitlab`, `drone`) using the same network
- [x] Use `/var/lib/pbri/docker/...` instead of Docker volumes (makes backups easier) - [x] Use `/var/lib/pbri/docker/...` instead of Docker volumes (makes backups easier)
- [x] Make it inaccessible to anyone but root (`-rw------`) - [x] Make it inaccessible to anyone but root (`-rw------`)
- [x] Add [Drone runner](https://docs.drone.io/runner/docker/installation/linux/) - [x] Add [Drone runner](https://docs.drone.io/runner/docker/installation/linux/)
- [ ] Figure out how to dependably store `.env` files (Ansible vault? Something else?) - [ ] Figure out how to dependably store `.env` files (Ansible vault? Something else?)
- [ ] Check out docker swarm and current best practices for Ansible - [ ] In vault, seperate from other config
- [ ] Use Gitea instead of GitLab - [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` - [ ] Add drone exec runner for Nix builds with shared `/nix`
- [ ] 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
View File
@@ -1 +0,0 @@
venv
+3 -2
View File
@@ -2,10 +2,11 @@
## Ansible Control Node Setup ## Ansible Control Node Setup
In a Python 3 environment (perhaps a venv): 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` ## `misc.yaml`
+1
View File
@@ -1,2 +1,3 @@
[defaults] [defaults]
inventory = ./inventory inventory = ./inventory
roles_path = ./roles
+3 -2
View File
@@ -1,3 +1,4 @@
--- ---
ansible_user: andi # Has pw-less sudo
ansible_python_interpreter: /usr/bin/python3 ansible_user: paul
ansible_python_interpreter: /usr/bin/python3
+1 -1
View File
@@ -1,2 +1,2 @@
[misc] [misc]
pbrinkmeier.de vmd98928.contaboserver.net ansible_port=2309
-64
View File
@@ -1,64 +0,0 @@
---
- hosts: misc
tasks:
- name: Add users for running containers
become: yes
ansible.builtin.user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
create_home: no
state: present
loop:
- name: jupyter
uid: 42000
state: present
- name: gitea
uid: 42001
state: present
# All services that are behind Caddy need to be in this network
- name: Create Caddy network
become: yes
docker_network:
name: caddy-network
state: present
- name: Upload docker configuration
become: yes
copy:
src: ../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: Create directory for docker volumes
become: yes
file:
path: /var/lib/pbri/docker
state: directory
# Hide contents from non-root users
mode: u=rwx,g=,o=
- name: Set up docker stuff
become: yes
docker_compose:
project_src: "/etc/pbri/docker/{{ item.name }}"
state: "{{ item.state }}"
build: yes
debug: yes
loop:
- name: web
state: absent
- name: runner
state: absent
- name: gitea
state: present
- name: caddy
state: present
- name: Add Notebooks folder
become: yes
ansible.builtin.file:
path: /home/jupyter/Notebooks
owner: jupyter
group: jupyter
state: directory
mode: 0755
-52
View File
@@ -1,52 +0,0 @@
---
- hosts: misc
tasks:
- name: Install basic packages
become: yes
apt:
name:
- vim
- git
- htop
- tmux
update_cache: yes
tags:
- apt
- include_role:
name: docker
- include_role:
name: install_nix
- name: Install pip prerequisites
become: yes
apt:
name:
- python3-pip
- python3-setuptools
- python3-virtualenv
- name: Install global python docker package
become: yes
pip:
name:
- docker
- docker-compose
- requests
- name: Configure sshd
register: sshdconfig
become: yes
copy:
dest: /etc/ssh/sshd_config.d/00_pbri.conf
mode: u=rw,g=r,o=r
# Included by /etc/ssh/sshd_config before other configuration
content: |
Port 2309
PermitRootLogin no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
validate: /usr/sbin/sshd -T -f %s
- name: Restart sshd
when: sshdconfig.changed
become: yes
service:
name: sshd
state: restarted
+155
View File
@@ -0,0 +1,155 @@
---
- name: Update Docker configuration on shamash
hosts: misc
tasks:
- name: Add users for running containers
become: true
ansible.builtin.user:
name: "{{ item.name }}"
uid: "{{ item.uid }}"
state: "{{ item.state }}"
create_home: false
system: true
loop:
- name: jupyter
uid: 42000
state: present
- 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
community.docker.docker_network:
name: caddy-network
state: present
- name: Upload docker configuration
become: true
ansible.builtin.copy:
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:
path: /var/lib/pbri/docker
state: directory
# Hide contents from non-root users
mode: u=rwx,g=,o=
- name: Create jupyter folders
become: true
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
debug: true
loop:
- name: caddy
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: jupyter
state: present
- name: utoy
state: present
- name: score
state: present
- name: factorio
state: absent
- name: glebby
state: absent
+74
View File
@@ -0,0 +1,74 @@
---
- name: Basic setup for shamash (packages, Docker, Nix, sshd)
hosts: misc
tasks:
- name: Create /etc/pbri
become: true
ansible.builtin.file:
path: /etc/pbri
state: directory
mode: u=rwx,g=rx,o=rx
- name: Create /home/paul/{Sites,Source}
become: true
ansible.builtin.file:
path: "/home/paul/{{ item }}"
state: directory
owner: paul
group: paul
mode: u=rwx,g=rx,o=rx
loop:
- Sites
- Source
- name: Install basic packages
become: true
ansible.builtin.apt:
name:
- vim
- git
- htop
- tmux
update_cache: true
tags:
- apt
- name: Install and set up Docker and docker-compose
ansible.builtin.include_role:
name: docker
- name: Install and set up Nix
ansible.builtin.include_role:
name: install_nix
- name: Install pip prerequisites
become: true
ansible.builtin.apt:
name:
- python3-pip
- python3-setuptools
- python3-virtualenv
- name: Install global python docker package
become: true
ansible.builtin.pip:
name:
- docker
- docker-compose
- requests
- name: Configure sshd
become: true
ansible.builtin.copy:
dest: /etc/ssh/sshd_config.d/00_pbri.conf
mode: u=rw,g=r,o=r
# Included by /etc/ssh/sshd_config before other configuration
content: |
Port 2309
PermitRootLogin no
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
PasswordAuthentication no
validate: /usr/sbin/sshd -T -f %s
notify:
- Restart sshd
handlers:
- name: Restart sshd
become: true
ansible.builtin.service:
name: sshd
state: restarted
@@ -1,7 +1,9 @@
--- ---
- hosts: misc - name: Check out static sites hosted on shamash
hosts: misc
tasks: tasks:
- include_role: - name: Check out static sites
ansible.builtin.include_role:
name: checkout_static_sites name: checkout_static_sites
vars: vars:
checkout_static_sites: checkout_static_sites:
@@ -1,6 +1,6 @@
--- ---
- name: Create static site directories - name: Create static site directories
become: yes become: true
ansible.builtin.file: ansible.builtin.file:
path: "{{ item.path }}" path: "{{ item.path }}"
state: directory state: directory
@@ -9,7 +9,7 @@
group: "{{ item.owner }}" group: "{{ item.owner }}"
loop: "{{ checkout_static_sites.checkouts }}" loop: "{{ checkout_static_sites.checkouts }}"
- name: Check out static site repositories - name: Check out static site repositories
become: yes become: true
become_user: "{{ item.owner }}" become_user: "{{ item.owner }}"
ansible.builtin.git: ansible.builtin.git:
dest: "{{ item.path }}" dest: "{{ item.path }}"
+31 -19
View File
@@ -1,38 +1,50 @@
--- ---
- name: Install Docker installation prerequisites - name: Install Docker installation prerequisites
become: yes become: true
apt: ansible.builtin.apt:
update_cache: yes update_cache: true
state: latest # Don't upgrade, only make sure that the packages are present
# state: latest
name: name:
- ca-certificates - ca-certificates
- curl - curl
- gnupg - gnupg
- lsb-release - lsb-release
- name: Add Docker GPG key - name: Retrieve Docker GPG key
become: yes check_mode: false
shell: "curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg" ansible.builtin.uri:
url: https://download.docker.com/linux/debian/gpg
return_content: true
register: docker_gpg_key
- name: Install Docker GPG key
become: true
ansible.builtin.command: "gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg"
args: args:
stdin: "{{ docker_gpg_key.content }}"
creates: /usr/share/keyrings/docker-archive-keyring.gpg creates: /usr/share/keyrings/docker-archive-keyring.gpg
- name: Retrieve dpkg architecture - name: Retrieve dpkg architecture
shell: dpkg --print-architecture check_mode: false
register: dpkg_architecture ansible.builtin.command: dpkg --print-architecture
changed_when: False register: docker_dpkg_architecture
changed_when: false
- name: Add Docker apt repository - name: Add Docker apt repository
become: yes become: true
template: ansible.builtin.template:
src: docker.list.j2 src: docker.list.j2
dest: /etc/apt/sources.list.d/docker.list dest: /etc/apt/sources.list.d/docker.list
mode: "u=rw,g=r,o=r"
- name: Install Docker - name: Install Docker
become: yes become: true
apt: ansible.builtin.apt:
update_cache: yes update_cache: true
state: latest # Don't upgrade, only make sure that the packages are present
# state: latest
name: name:
- docker-ce - docker-ce
- docker-ce-cli - docker-ce-cli
- containerd.io - containerd.io
@@ -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
+1 -1
View File
@@ -1,7 +1,7 @@
--- ---
# Obvious race condition here that we are just going to ignore # Obvious race condition here that we are just going to ignore
- name: Copy Nix installation script - name: Copy Nix installation script
become: yes become: true
ansible.builtin.copy: ansible.builtin.copy:
src: install-nix src: install-nix
dest: /etc/pbri/install-nix dest: /etc/pbri/install-nix
+4
View File
@@ -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 { pbrinkmeier.de {
file_server { file_server {
root /srv/pbrinkmeier.de root /srv/pbrinkmeier.de
@@ -11,6 +15,10 @@ tichy.click {
} }
codi.pbrinkmeier.de { codi.pbrinkmeier.de {
redir https://pad.pbrinkmeier.de{uri} permanent
}
pad.pbrinkmeier.de {
reverse_proxy codi:3000 reverse_proxy codi:3000
} }
@@ -32,3 +40,11 @@ jupyter.pbrinkmeier.de {
plantuml.pbrinkmeier.de { plantuml.pbrinkmeier.de {
reverse_proxy codi_plantuml:8080 reverse_proxy codi_plantuml:8080
} }
utoy.beany.club {
reverse_proxy utoy:3000
}
score.brocke.net {
reverse_proxy score:8080
}
+10
View File
@@ -0,0 +1,10 @@
Add a `.env` file like this:
```
CODI_SESSION_SECRET=...
CODI_DB_USER=...
CODI_DB_PASSWORD=...
CODI_DB_DB=...
```
See also: https://docs.drone.io/server/provider/gitea/.
+59
View File
@@ -0,0 +1,59 @@
version: "3"
services:
codi:
image: hackmdio/hackmd:2.4.2
user: hackmd
environment:
# 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
volumes:
- /var/lib/pbri/docker/codi_uploads:/home/hackmd/app/public/uploads
restart: always
codi_db:
image: postgres:11.6-alpine
environment:
POSTGRES_USER: "${CODI_DB_USER}"
POSTGRES_PASSWORD: "${CODI_DB_PASSWORD}"
POSTGRES_DB: "${CODI_DB_DB}"
volumes:
- /var/lib/pbri/docker/codi_database:/var/lib/postgresql/data
restart: always
codi_plantuml:
image: plantuml/plantuml-server:jetty-v1.2022.7
restart: always
networks:
default:
name: caddy-network
external: true
+9
View File
@@ -0,0 +1,9 @@
Add a `.env` file like this:
```
DRONE_GITEA_CLIENT_ID=...
DRONE_GITEA_CLIENT_SECRET=...
DRONE_RPC_SECRET=...
```
See also: https://docs.drone.io/server/provider/gitea/.
+32
View File
@@ -0,0 +1,32 @@
version: "3"
services:
drone:
image: drone/drone:2
environment:
DRONE_GITEA_SERVER: https://git.pbrinkmeier.de
DRONE_GITEA_CLIENT_ID: "${DRONE_GITEA_CLIENT_ID}"
DRONE_GITEA_CLIENT_SECRET: "${DRONE_GITEA_CLIENT_SECRET}"
DRONE_RPC_SECRET: "${DRONE_RPC_SECRET}"
DRONE_SERVER_HOST: ci.pbrinkmeier.de
DRONE_SERVER_PROTO: https
volumes:
- /var/lib/pbri/docker/drone:/data
restart: unless-stopped
drone_runner:
image: drone/drone-runner-docker:1
environment:
DRONE_RPC_PROTO: https
DRONE_RPC_HOST: ci.pbrinkmeier.de
DRONE_RPC_SECRET: "${DRONE_RPC_SECRET}"
DRONE_RUNNER_CAPACITY: 1
DRONE_RUNNER_NAME: shamash
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: unless-stopped
networks:
default:
name: caddy-network
external: true
+4
View File
@@ -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" ]
+10
View File
@@ -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
}
+3
View File
@@ -0,0 +1,3 @@
FROM gitea/act_runner:0.2.5
COPY runner-config.yaml /opt/runner-config.yaml
+17
View File
@@ -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: services:
gitea: gitea:
image: gitea/gitea:1.17.1 image: gitea/gitea:1.20.3
restart: always restart: unless-stopped
environment: environment:
# Ref: https://docs.gitea.io/en-us/config-cheat-sheet # Ref: https://docs.gitea.io/en-us/config-cheat-sheet
# User is created by misc-docker.yaml # User is created by misc-docker.yaml
@@ -35,12 +35,17 @@ services:
GITEA__service__DEFAULT_ENABLE_TIMETRACKING: "false" GITEA__service__DEFAULT_ENABLE_TIMETRACKING: "false"
GITEA__service__DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME: "false" GITEA__service__DEFAULT_ALLOW_ONLY_CONTRIBUTORS_TO_TRACK_TIME: "false"
GITEA__mailer__ENABLED: "true" 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__FROM: git@pbrinkmeier.de
GITEA__mailer__USER: hallo@pbrinkmeier.de GITEA__mailer__USER: hallo@pbrinkmeier.de
GITEA__mailer__PASSWD: "${GITEA_SMTP_PASSWORD}" GITEA__mailer__PASSWD: "${GITEA_SMTP_PASSWORD}"
GITEA__openid__ENABLE_OPENID_SIGNIN: "false" GITEA__openid__ENABLE_OPENID_SIGNIN: "false"
GITEA__openid__ENABLE_OPENID_SIGNUP: "false" GITEA__openid__ENABLE_OPENID_SIGNUP: "false"
# Enable Gitea actions
# Ref: https://docs.gitea.com/usage/actions/quickstart
GITEA__actions__ENABLED: "true"
volumes: volumes:
- /var/lib/pbri/docker/gitea:/data - /var/lib/pbri/docker/gitea:/data
- /etc/timezone:/etc/timezone:ro - /etc/timezone:/etc/timezone:ro
@@ -52,7 +57,7 @@ services:
gitea_db: gitea_db:
image: postgres:14.5-alpine image: postgres:14.5-alpine
restart: always restart: unless-stopped
environment: environment:
POSTGRES_DB: gitea POSTGRES_DB: gitea
POSTGRES_USER: gitea POSTGRES_USER: gitea
@@ -60,6 +65,21 @@ services:
volumes: volumes:
- /var/lib/pbri/docker/gitea_db:/var/lib/postgresql/data - /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: networks:
default: default:
name: caddy-network name: caddy-network
+85
View File
@@ -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:
+11
View File
@@ -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
+15
View File
@@ -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
+16
View File
@@ -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
+11
View File
@@ -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
+20
View File
@@ -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
+14
View File
@@ -0,0 +1,14 @@
$ANSIBLE_VAULT;1.1;AES256
31333834393366333930346366373931333930646233383664643463393965303238613430646638
6461373434616433353337643131396462326537346434380a386562633335346436303662336362
62333739626237323334333666633162616338313932393261303231353539623237383638643030
3364393934653232310a383065386530373433393635313665353532666361303436613337316565
32306233336134383531633232393862303466373331373764376462653736663861663366323762
65666263366461396362386264613830336435346234386234333562616131653938386439336566
34386461343433346363336161373038303434383563303564653533623939613937323030636362
66636639643963613236366138646335393831366432333637333065326162646237643561336666
61323833333337633861646462393930663733333266336233663630396532366566303835653431
38363365383166393765343735363030363562313837643837313864373735643264663264643633
66306261633666616363666562306632613032373231633730313638383033633761653661383738
39623630643766663438656635653530626664313765633430646330356333306239653437373839
3933
+7
View File
@@ -0,0 +1,7 @@
$ANSIBLE_VAULT;1.1;AES256
32356463313330336636636363646138393236636233326132623165353962623565356364396530
3636336532396665333637653432353332643434643962390a313162343836306435383536313937
36656632356366303561366536373535383538303730386239386437323466346533353634306436
3930633464353235360a653936333734353137313363316261366666353238366566613865366463
32393431343439383733343766323831643561663938376264336331306139646337343633346536
3236343538323032636666366639303539316236393535323661
+14
View File
@@ -0,0 +1,14 @@
$ANSIBLE_VAULT;1.1;AES256
35623364633833623964623536646534373634663736613561333561343136333965306638396532
6162393239383936386338666565306132646230383066630a336337613636383431623738343663
61343262363631376665383035323139313863626331666439336134613035663439376231343863
3032353139643138640a383365356630323835383538393734643134343133653033383663333464
62386361633435633664306531623835353665326432393932336163316561653866343137323030
63643262323436356166373533363235366238393633336631336266373837373932313134303563
65633337393938623134636538653561356565333831356638373862376333336163363438626438
39343436383732313561396236656530303064363961663636353538346264633532633866333162
35303032303662646166333537373566316462633536333463323433353539623363323036643763
34376365613932303133366236613235636238643139666663356436326532616437383432303437
39376535656266383465373837643634383937656431323265386163373138336164383666383962
64623762613332363731323739666238613634646237396331666463363663313461313966356233
30653362353061333739303234336461373337346632646433623462623765353330
-19
View File
@@ -1,19 +0,0 @@
# runner
After installation, individual runners must still be registered, e.g.:
```
docker run --rm -it -v gitlab_runner_config:/etc/gitlab-runner gitlab/gitlab-runner register --name <name>
```
An issue I encountered when trying to cache stuff between builds was the following warning in the runner logs:
```
ERROR: Could not create cache adapter error=cache factory not found: factory for cache adapter "" was not registered
```
In order to make the runner able to create caches, register it like so:
```
docker run --rm -it -v gitlab_runner_config:/etc/gitlab-runner gitlab/gitlab-runner register --name <name> --docker-disable-cache=false -docker-cache-dir /cache --docker-volumes gitlab_runner_cache:/cache
```
-13
View File
@@ -1,13 +0,0 @@
version: "3"
services:
# Webserver for static files and reverse proxy
gitlab_runner:
image: gitlab/gitlab-runner:alpine
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- gitlab_runner_config:/etc/gitlab-runner
restart: always
volumes:
gitlab_runner_config:
external: yes
-7
View File
@@ -1,7 +0,0 @@
# web
Old god project.
## Jupyter
The Docker image for Jupyter is built using Nix. That process is not part of the Ansible setup (yet).
-114
View File
@@ -1,114 +0,0 @@
version: "3"
services:
codi:
image: hackmdio/hackmd:2.4.2
# CMD_DB_{URL,CMD_SESSION_SECRET}
env_file: codi.env
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
depends_on:
- codi_db
- codi_plantuml
volumes:
- /var/lib/pbri/docker/codi_uploads:/home/hackmd/app/public/uploads
restart: always
codi_db:
image: postgres:11.6-alpine
# POSTGRES_{USER,PASSWORD,DB}
# Must match CMD_DB_URL in codi.env
env_file: codi_db.env
volumes:
- /var/lib/pbri/docker/codi_database:/var/lib/postgresql/data
restart: always
codi_plantuml:
image: plantuml/plantuml-server:jetty-v1.2022.7
restart: always
gitlab:
image: gitlab/gitlab-ce:15.3.2-ce.0
ports:
- "22:22"
volumes:
- /var/lib/pbri/docker/gitlab_data:/var/opt/gitlab
- /var/lib/pbri/docker/gitlab_logs:/var/log/gitlab
- /var/lib/pbri/docker/gitlab_config:/etc/gitlab
restart: always
# GITLAB_SMTP_PASSWORD
env_file: gitlab.env
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'https://git.pbrinkmeier.de'
gitlab_rails['smtp_enable'] = true
gitlab_rails['smtp_address'] = "smtp.mailbox.org"
gitlab_rails['smtp_port'] = 465
gitlab_rails['smtp_user_name'] = "hallo@pbrinkmeier.de"
gitlab_rails['smtp_password'] = ENV['GITLAB_SMTP_PASSWORD']
gitlab_rails['smtp_domain'] = "smtp.mailbox.org"
gitlab_rails['smtp_authentication'] = "login"
gitlab_rails['smtp_enable_starttls_auto'] = true
gitlab_rails['smtp_tls'] = true
gitlab_rails['smtp_openssl_verify_mode'] = 'none'
gitlab_rails['gitlab_email_from'] = 'git@pbrinkmeier.de'
gitlab_rails['gitlab_email_reply_to'] = 'noreply@pbrinkmeier.de'
gitlab_rails['gitlab_shell_ssh_port'] = 22
# https://docs.gitlab.com/omnibus/settings/rpi.html
puma['worker_processes'] = 2
sidekiq['concurrency'] = 9
nginx['listen_port'] = 80
nginx['listen_https'] = false
# https://forum.gitlab.com/t/clear-up-postges-prometheus-data/38216/3
prometheus_monitoring['enable'] = false
prometheus['enable'] = false
prometheus['flags'] = {
'storage.tsdb.retention.time' => "12h"
}
jupyter:
image: ihaskell-docker:1.0
# ports:
# - "8888:8888"
user: "42000" # Jupyter user UID (jupyter does not exist in container (TODO...))
environment:
HOME: /Notebooks
volumes:
- /home/jupyter/Notebooks:/Notebooks
restart: always
drone:
image: drone/drone:2
# DRONE_{GITLAB_CLIENT_ID,GITLAB_CLIENT_SECRET,RPC_SECRET}
env_file: drone.env
environment:
DRONE_GITLAB_SERVER: https://git.pbrinkmeier.de
DRONE_SERVER_HOST: ci.pbrinkmeier.de
DRONE_SERVER_PROTO: https
volumes:
- /var/lib/pbri/docker/drone:/data
restart: always
drone_runner:
image: drone/drone-runner-docker:1
# DRONE_RPC_SECRET
env_file: drone.env
environment:
DRONE_RPC_PROTO: https
DRONE_RPC_HOST: ci.pbrinkmeier.de
DRONE_RUNNER_CAPACITY: 1
DRONE_RUNNER_NAME: shamash
volumes:
- /var/run/docker.sock:/var/run/docker.sock
restart: always
Generated
+140
View File
@@ -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
}
+29
View File
@@ -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"
'';
};
}
);
}
+12
View File
@@ -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`
+146
View File
@@ -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?
}
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env bash
nixos-rebuild -I nixos-config=configuration.nix --target-host gilgamesh --use-remote-sudo switch
+33
View File
@@ -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;
}
+118
View File
@@ -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;
};
};
};
};
}
+81
View File
@@ -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";
};
};
};
};
}
+1
View File
@@ -0,0 +1 @@
spigot-1.20.1.jar
+11
View File
@@ -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
+37
View File
@@ -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
'';
}
+26
View File
@@ -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"
'';
}
+11
View File
@@ -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>
```
+9
View File
@@ -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.
+10
View File
@@ -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 ];
}