mirror of
https://github.com/davegallant/davegallant.github.io.git
synced 2026-01-12 21:24:05 +00:00
Compare commits
7 Commits
137ef199b7
...
3f65793c98
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3f65793c98 | ||
|
|
e1968d56b0 | ||
|
|
0d0759bdca | ||
|
|
c07462a26d | ||
|
|
db48078e98 | ||
|
|
361cf93e8c | ||
|
|
9ffb7f8dd6 |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
|
|||||||
|
div.code-toolbar{position:relative}div.code-toolbar>.toolbar{opacity:0;position:absolute;right:.2em;top:.3em;transition:opacity .3s ease-in-out;z-index:10}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:none;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{background:#f5f2f0;background:hsla(0,0%,88%,.2);border-radius:.5em;box-shadow:0 2px 0 0 rgba(0,0,0,.2);color:#bbb;font-size:.8em;padding:0 .5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;-webkit-text-decoration:none;text-decoration:none}.command-line-prompt{border-right:1px solid #999;display:block;float:left;font-size:100%;letter-spacing:-1px;margin-right:1em;pointer-events:none;text-align:right;-webkit-user-select:none;-moz-user-select:none;user-select:none}.command-line-prompt>span:before{content:" ";display:block;opacity:.7;padding-right:.8em}.command-line-prompt>span[data-user]:before{content:"[" attr(data-user) "@" attr(data-host) "] $"}.command-line-prompt>span[data-user=root]:before{content:"[" attr(data-user) "@" attr(data-host) "] #"}.command-line-prompt>span[data-prompt]:before{content:attr(data-prompt)}.command-line-prompt>span[data-continuation-prompt]:before{content:attr(data-continuation-prompt)}.command-line span.token.output{opacity:.7}
|
||||||
|
|
||||||
|
/*! MIT License | github.com/schnerring/hugo-theme-gruvbox */code,footer{font-family:var(--font-monospace)}footer{align-items:center;color:var(--fg3);display:flex;font-size:.8rem;justify-content:center;padding-bottom:.5rem;padding-top:2rem;text-align:center}.pagination{display:flex;margin-top:2rem}.pagination__button{color:var(--primary-alt);font-family:var(--font-monospace);font-size:1.125rem}.pagination__button:hover{color:var(--primary)}.pagination__button--next{margin-left:auto}
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
/*! purgecss start ignore */div.code-toolbar{position:relative}div.code-toolbar>.toolbar{opacity:0;position:absolute;right:.2em;top:.3em;transition:opacity .3s ease-in-out;z-index:10}div.code-toolbar:hover>.toolbar{opacity:1}div.code-toolbar:focus-within>.toolbar{opacity:1}div.code-toolbar>.toolbar>.toolbar-item{display:inline-block}div.code-toolbar>.toolbar>.toolbar-item>a{cursor:pointer}div.code-toolbar>.toolbar>.toolbar-item>button{background:none;border:0;color:inherit;font:inherit;line-height:normal;overflow:visible;padding:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none}div.code-toolbar>.toolbar>.toolbar-item>a,div.code-toolbar>.toolbar>.toolbar-item>button,div.code-toolbar>.toolbar>.toolbar-item>span{background:#f5f2f0;background:hsla(0,0%,88%,.2);border-radius:.5em;box-shadow:0 2px 0 0 rgba(0,0,0,.2);color:#bbb;font-size:.8em;padding:0 .5em}div.code-toolbar>.toolbar>.toolbar-item>a:focus,div.code-toolbar>.toolbar>.toolbar-item>a:hover,div.code-toolbar>.toolbar>.toolbar-item>button:focus,div.code-toolbar>.toolbar>.toolbar-item>button:hover,div.code-toolbar>.toolbar>.toolbar-item>span:focus,div.code-toolbar>.toolbar>.toolbar-item>span:hover{color:inherit;-webkit-text-decoration:none;text-decoration:none}.command-line-prompt{border-right:1px solid #999;display:block;float:left;font-size:100%;letter-spacing:-1px;margin-right:1em;pointer-events:none;text-align:right;-webkit-user-select:none;-moz-user-select:none;user-select:none}.command-line-prompt>span:before{content:" ";display:block;opacity:.7;padding-right:.8em}.command-line-prompt>span[data-user]:before{content:"[" attr(data-user) "@" attr(data-host) "] $"}.command-line-prompt>span[data-user=root]:before{content:"[" attr(data-user) "@" attr(data-host) "] #"}.command-line-prompt>span[data-prompt]:before{content:attr(data-prompt)}.command-line-prompt>span[data-continuation-prompt]:before{content:attr(data-continuation-prompt)}.command-line span.token.output{opacity:.7}
|
|
||||||
|
|
||||||
/*! purgecss end ignore */
|
|
||||||
|
|
||||||
/*! MIT License | github.com/schnerring/hugo-theme-gruvbox */code,code[class*=language-],footer,kbd,pre[class*=language-]{font-family:var(--font-monospace)}footer{align-items:center;color:var(--fg3);display:flex;font-size:.8rem;justify-content:center;padding-bottom:.5rem;padding-top:2rem;text-align:center}.pagination{display:flex;margin-top:2rem}.pagination__button{color:var(--primary-alt);font-family:var(--font-monospace);font-size:1.125rem}.pagination__button:hover{color:var(--primary)}.pagination__button--next{margin-left:auto}
|
|
||||||
12
de/404.html
12
de/404.html
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
12
index.html
12
index.html
File diff suppressed because one or more lines are too long
@@ -5,18 +5,19 @@ Gitea Actions# Gitea Actions have made it into the 1.19.0 release. This feature
|
|||||||
So what are they? If you’ve ever used GitHub Actions (and if you’re reading this, I imagine you have), these will look familiar. Gitea Actions essentially enable the ability to run github workflows on gitea. Workflows between gitea and github are not completely interopable, but a lot of the same workflow syntax is already compatible on gitea. You can find a documented list of unsupported workflows syntax.
|
So what are they? If you’ve ever used GitHub Actions (and if you’re reading this, I imagine you have), these will look familiar. Gitea Actions essentially enable the ability to run github workflows on gitea. Workflows between gitea and github are not completely interopable, but a lot of the same workflow syntax is already compatible on gitea. You can find a documented list of unsupported workflows syntax.
|
||||||
Actions work by using a custom fork of nekos/act. Workflows run in a new container for every job. If you specify an action such as actions/checkout@v4, it defaults to downloading the scripts from github.com. To avoid internet egress, you could always clone the required actions to your local gitea instance.
|
Actions work by using a custom fork of nekos/act. Workflows run in a new container for every job. If you specify an action such as actions/checkout@v4, it defaults to downloading the scripts from github.com. To avoid internet egress, you could always clone the required actions to your local gitea instance.
|
||||||
Actions (gitea’s implementation) has me excited because it makes spinning up a network-isolated environment for workflow automation incredibly simple.
|
Actions (gitea’s implementation) has me excited because it makes spinning up a network-isolated environment for workflow automation incredibly simple.
|
||||||
Integration with Tailscale# So how does Tailscale help here? Well, more recently I’ve been exposing my self-hosted services through a combination of traefik and the tailscale (through the tailscale-traefik proxy integration described here). This allows for a nice looking dns name (i.e. gitea.my-tailnet-name.ts.net) and automatic tls certificate management. I can also share this tailscale node securely with other tailscale users without configuring any firewall rules on my router.
|
Integration with Tailscale# 2024-02-10: I had originally written this post to include Tailscale-Traefik Proxy Integration, but have since removed it in favour of Tailscale Serve after learning from this example. This simplifies the setup and reduces the number of moving parts.
|
||||||
|
So how does Tailscale help here? Well, more recently I’ve been exposing my self-hosted services using Tailscale Serve. This allows for a nice looking dns name (i.e. gitea.my-tailnet-name.ts.net), automatic tls certificate management, and optionally allowing the address to be publically accessible (by using Funnel).
|
||||||
Deploying Gitea, Traefik, and Tailscale# In my case, the following is already set up:
|
Deploying Gitea, Traefik, and Tailscale# In my case, the following is already set up:
|
||||||
docker-compose is installed tailscale is installed on the gitea host tailscale magic dns is enabled My preferred approach to deploying code in a homelab environment is with docker compose. I have deployed this in a proxmox lxc container based on debian with a hostname gitea. This could be deployed in any environment and with any hostname (as long you updated the tailscale machine name to your preferred subdomain for magic dns).
|
docker-compose is installed tailscale magic dns is enabled My preferred approach to deploying code in a homelab environment is with docker compose. I have deployed this in a LXC on Proxmox. You could run this on a virtual machine or a physical host as well.
|
||||||
The docker-compose.yaml file looks like:
|
The docker-compose.yaml file looks like:
|
||||||
version: "3.7" services: gitea: image: gitea/gitea:1.21.1 container_name: gitea environment: - USER_UID=1000 - USER_GID=1000 - GITEA__server__DOMAIN=gitea.my-tailnet-name.ts.net - GITEA__server__ROOT_URL=https://gitea.my-tailnet-name.ts.net - GITEA__server__HTTP_ADDR=0.0.0.0 - GITEA__server__LFS_JWT_SECRET=my-secret-jwt restart: always volumes: - ./data:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro traefik: image: traefik:v3.0.0-beta4 container_name: traefik security_opt: - no-new-privileges:true restart: unless-stopped ports: - 80:80 - 443:443 volumes: - ./traefik/data/traefik.yaml:/traefik.yaml:ro - ./traefik/data/dynamic.yaml:/dynamic.yaml:ro - /var/run/tailscale/tailscaled.sock:/var/run/tailscale/tailscaled.sock traefik/data/traefik.yaml:
|
version: "3.7" services: gitea: image: gitea/gitea:1.21.1 container_name: gitea network_mode: service:ts-gitea environment: - USER_UID=1000 - USER_GID=1000 - GITEA__server__DOMAIN=gitea.my-tailnet-name.ts.net - GITEA__server__ROOT_URL=https://gitea.my-tailnet-name.ts.net - GITEA__server__HTTP_ADDR=0.0.0.0 - GITEA__server__LFS_JWT_SECRET=my-secret-jwt restart: always volumes: - ./data:/data - /etc/timezone:/etc/timezone:ro - /etc/localtime:/etc/localtime:ro ts-gitea: image: tailscale/tailscale:v1.58 container_name: ts-gitea hostname: gitea environment: - TS_AUTHKEY=<FILL THIS IN> - TS_SERVE_CONFIG=/config/gitea.json - TS_STATE_DIR=/var/lib/tailscale volumes: - \${PWD}/state:/var/lib/tailscale - \${PWD}/config:/config - /dev/net/tun:/dev/net/tun cap_add: - net_admin - sys_module restart: unless-stopped Note that you must specify a TS_AUTHKEY in the ts-gitea service. You can generate an auth key here.
|
||||||
entryPoints: https: address: ":443" providers: file: filename: dynamic.yaml certificatesResolvers: myresolver: tailscale: {} log: level: INFO and finally traefik/data/dynamic/dynamic.yaml:
|
config/gitea.json:
|
||||||
http: routers: gitea: rule: Host(\`gitea.my-tailnet-name.ts.net\`) entrypoints: - "https" service: gitea tls: certResolver: myresolver services: gitea: loadBalancer: servers: - url: "http://gitea:3000" Something to consider is whether or not you want to use ssh with git. One method to get this to work with containers is to use ssh container passthrough. I decided to keep it simple and not use ssh, since communicating over https is perfectly fine for my use case.
|
{ "TCP": { "443": { "HTTPS": true } }, "Web": { "\${TS_CERT_DOMAIN}:443": { "Handlers": { "/": { "Proxy": "http://127.0.0.1:3000" } } }, }, "AllowFunnel": { "\${TS_CERT_DOMAIN}:443": false }, } After adding the above configuration, running docker compose up -d should be enough to get an instance up and running. It will be accessible at https://gitea.my-tailnet-name.ts.net from within the tailnet.
|
||||||
After adding the above configuration, running docker compose up -d should be enough to get an instance up and running. It will be accessible at https://gitea.my-tailnet-name.ts.net from within the tailnet.
|
Something to consider is whether or not you want to use ssh with git. One method to get this to work with containers is to use ssh container passthrough. I decided to keep it simple and not use ssh, since communicating over https is perfectly fine for my use case.
|
||||||
Theming# I discovered some themes for gitea here and decided to try out gruvbox.
|
Theming# I discovered some themes for gitea here and decided to try out gruvbox.
|
||||||
I added the theme by cloning theme-gruvbox-auto.css into ./data/gitea/public/assets/css. I then added the following to environment in docker-compose.yml:
|
I added the theme by cloning theme-gruvbox-auto.css into ./data/gitea/public/assets/css. I then added the following to environment in docker-compose.yml:
|
||||||
- GITEA__ui__DEFAULT_THEME=gruvbox-auto - GITEA__ui__THEMES=gruvbox-auto After restarting the gitea instance, the default theme was applied.
|
- GITEA__ui__DEFAULT_THEME=gruvbox-auto - GITEA__ui__THEMES=gruvbox-auto After restarting the gitea instance, the default theme was applied.
|
||||||
Connecting runners# I installed the runner by following the docs. I opted for installing it on a separate host (another lxc container) as recommended in the docs. I used the systemd unit file to ensure that the runner comes back online after system reboots. I installed tailscale on this gitea runner as well, so that it can have the same “networking privileges” as the main instance.
|
Connecting runners# I installed the runner by following the docs. I opted for installing it on a separate host as recommended in the docs. I used the systemd unit file to ensure that the runner comes back online after system reboots. I installed tailscale on the gitea runner as well, so that it can be part of the same tailnet as the main instance.
|
||||||
After registering this runner and starting the daemon, the runner appeared in /admin/actions/runners. I added two other runners to help with parallelization.
|
After registering this runner and starting the daemon, the runner appeared in /admin/actions/runners. I added two other runners to help with parallelization.
|
||||||
Running a workflow# Now it’s time start running some automation. I used the demo workflow as a starting point to verify that the runner is executing workflows.
|
Running a workflow# Now it’s time start running some automation. I used the demo workflow as a starting point to verify that the runner is executing workflows.
|
||||||
After this, I wanted to make sure that some of my existing workflows could be migrated over.
|
After this, I wanted to make sure that some of my existing workflows could be migrated over.
|
||||||
@@ -1 +1 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" standalone="yes"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>/en/sitemap.xml</loc><lastmod>2024-01-27T14:57:33-05:00</lastmod></sitemap><sitemap><loc>/de/sitemap.xml</loc></sitemap></sitemapindex>
|
<?xml version="1.0" encoding="utf-8" standalone="yes"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"><sitemap><loc>/en/sitemap.xml</loc><lastmod>2024-02-10T10:20:25-05:00</lastmod></sitemap><sitemap><loc>/de/sitemap.xml</loc></sitemap></sitemapindex>
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user