fix: stop link component opening internal page in new tab
All checks were successful
Docker / build-and-push-image (push) Successful in 1m16s
All checks were successful
Docker / build-and-push-image (push) Successful in 1m16s
This commit is contained in:
parent
9346a78c27
commit
237eeb4cac
5 changed files with 166 additions and 384 deletions
|
@ -3,13 +3,21 @@ import type { HTMLAttributes } from "astro/types";
|
|||
|
||||
interface Props extends HTMLAttributes<"a"> {
|
||||
href: string;
|
||||
external?: boolean;
|
||||
class?: string;
|
||||
}
|
||||
|
||||
const { href, external = true, ...rest } = Astro.props;
|
||||
const { href, ...rest } = Astro.props;
|
||||
|
||||
const isExternal =
|
||||
/^(https?:)?\/\//.test(href) ||
|
||||
href.startsWith("mailto:") ||
|
||||
href.startsWith("tel:");
|
||||
---
|
||||
|
||||
<a href={href} target={external ? "_blank" : "_self"} {...rest}>
|
||||
<a
|
||||
href={href}
|
||||
target={isExternal ? "_blank" : "_self"}
|
||||
rel={isExternal ? "noopener noreferrer" : undefined}
|
||||
{...rest}
|
||||
>
|
||||
<slot />
|
||||
</a>
|
||||
|
|
|
@ -1,220 +0,0 @@
|
|||
---
|
||||
title: "Hosting my own Digital Content"
|
||||
date: 2025-05-03
|
||||
description: "An overview of what I am using to host my digital content."
|
||||
image:
|
||||
url: "showcase.webp"
|
||||
alt: "Website showcase"
|
||||
categories: ["personal"]
|
||||
tags: ["self-host", "forgejo", "docker", "vps"]
|
||||
draft: true
|
||||
---
|
||||
|
||||
This post will outline my workflow of using a self-hosted Forgejo instance and Actions runner to automatically deploy my personal site and any software releases, all without having to rely on another provider.
|
||||
|
||||
What initially started as a bit of experimentation out of intrigue has evolved into allowing me better control over tasks I now carry out with work. It has given me the confidence to expand my knowledge out to other areas and even aid others.
|
||||
|
||||

|
||||
|
||||
This website's goal is not only to showcase my interests and the subsequent artwork which comes from that. But to also act as a way for me to learn more about web development, software deployment, and hosting on your own infrastructure.
|
||||
|
||||
---
|
||||
|
||||
As a result of all this, it gave me the drive to pursue using NixOS on my personal rig, and using it to set up a home server to host a Jellyfin and Immich instance.
|
||||
|
||||
## Steps
|
||||
|
||||
### Private image access login?
|
||||
|
||||
```sh
|
||||
echo '<token>' | docker login code.troylusty.com -u troy --password-stdin
|
||||
```
|
||||
|
||||
```sh
|
||||
echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g
|
||||
```
|
||||
|
||||
### Aliases for updating VPS and pruning Docker
|
||||
|
||||
```sh
|
||||
echo 'alias dockerclean="docker system prune -a --volumes"' >> .bashrc
|
||||
echo 'alias updateall="sudo apt update && sudo apt upgrade && sudo apt autoremove"' >> .bashrc
|
||||
```
|
||||
|
||||
Thanks to [Tech Tales](https://tech-tales.blog/posts/2025/01-forgejo-runner-update) for the clean instructions on how to setup an Actions runner with Forgejo.
|
||||
|
||||
```sh
|
||||
docker compose run --rm forgejo-runner 'forgejo-runner' 'generate-config' > forgejo-runner/config.yml
|
||||
```
|
||||
|
||||
Setup `container.docker_host: "unix:///var/run/docker.sock"` and `container.network: "forgejo"` and any labels such as `runner.labels: ["ubuntu-latest:docker://gitea/runner-images:ubuntu-latest"]`
|
||||
|
||||
```
|
||||
docker compose run --rm -it forgejo-runner 'forgejo-runner' 'register'
|
||||
```
|
||||
|
||||
Input `http://forgejo:3000` as the domain since forgejo is the container name in Docker and port 3000 is its relevant port.
|
||||
|
||||
## Docker compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
traefik:
|
||||
image: traefik:latest
|
||||
container_name: traefik
|
||||
command:
|
||||
- "--providers.docker"
|
||||
- "--providers.docker.exposedbydefault=false"
|
||||
- "--entryPoints.websecure.address=:443"
|
||||
- "--certificatesresolvers.myresolver.acme.tlschallenge=true"
|
||||
- "--certificatesresolvers.myresolver.acme.email=traefik@troylusty.com"
|
||||
- "--certificatesresolvers.myresolver.acme.storage=/letsencrypt/acme.json"
|
||||
- "--entrypoints.web.address=:80"
|
||||
- "--entrypoints.web.http.redirections.entrypoint.to=websecure"
|
||||
- "--entrypoints.web.http.redirections.entrypoint.scheme=https"
|
||||
- "--ping=true"
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- "traefik.http.middlewares.securityHeaders.headers.stsSeconds=31536000"
|
||||
- "traefik.http.middlewares.securityHeaders.headers.stsIncludeSubdomains=true"
|
||||
- "traefik.http.middlewares.securityHeaders.headers.frameDeny=true"
|
||||
- "traefik.http.middlewares.securityHeaders.headers.contentTypeNosniff=true"
|
||||
- "traefik.http.middlewares.securityHeaders.headers.contentSecurityPolicy=default-src 'self'; script-src 'self' 'unsafe-eval' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; base-uri 'none'; form-action 'self'; object-src 'none'; frame-ancestors 'none'; upgrade-insecure-requests"
|
||||
- "traefik.http.middlewares.securityHeaders.headers.referrerPolicy=no-referrer"
|
||||
- "traefik.http.middlewares.securityHeaders.headers.permissionsPolicy=accelerometer=(), autoplay=(), camera=(), cross-origin-isolated=(), display-capture=(), encrypted-media=(), fullscreen=(), geolocation=(), gyroscope=(), keyboard-map=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), screen-wake-lock=(), sync-xhr=(self), usb=(), web-share=(), xr-spatial-tracking=(), clipboard-read=(), clipboard-write=(), gamepad=(), hid=(), idle-detection=(), interest-cohort=(), serial=(), unload=()"
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock:ro
|
||||
- letsencrypt:/letsencrypt
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- traefik
|
||||
healthcheck:
|
||||
test: ["CMD", "traefik", "healthcheck", "--ping"]
|
||||
depends_on:
|
||||
watchtower:
|
||||
condition: service_healthy
|
||||
|
||||
watchtower:
|
||||
image: containrrr/watchtower:latest
|
||||
command: --label-enable --interval 1800 --rolling-restart --cleanup --remove-volumes
|
||||
container_name: watchtower
|
||||
networks:
|
||||
- traefik
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
- /home/troy/.docker/config.json:/config.json
|
||||
restart: unless-stopped
|
||||
healthcheck:
|
||||
test: ["CMD", "/watchtower", "--health-check"]
|
||||
|
||||
personalsite:
|
||||
image: code.troylusty.com/troy/troylusty.com:latest
|
||||
container_name: personalsite
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.personalsite.rule=Host(`troylusty.com`)"
|
||||
- "traefik.http.routers.personalsite.entrypoints=websecure"
|
||||
- "traefik.http.routers.personalsite.tls.certresolver=myresolver"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- "traefik.http.routers.personalsite.middlewares=securityHeaders"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- traefik
|
||||
depends_on:
|
||||
traefik:
|
||||
condition: service_healthy
|
||||
|
||||
zolapress:
|
||||
image: code.troylusty.com/troy/zolapress:latest
|
||||
container_name: zolapress
|
||||
profiles:
|
||||
- donotstart
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.zolapress.rule=Host(`edu.troylusty.com`)"
|
||||
- "traefik.http.routers.zolapress.entrypoints=websecure"
|
||||
- "traefik.http.routers.zolapress.tls.certresolver=myresolver"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- "traefik.http.middlewares.auth.basicauth.users=troy:$$2y$$05$$fgVNzDsxXDq4co3aTh/OMOKZdLzUiM9XPEU5DXCivc9sYUZy/oq1W"
|
||||
- "traefik.http.routers.zolapress.middlewares=securityHeaders, auth"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- traefik
|
||||
depends_on:
|
||||
traefik:
|
||||
condition: service_healthy
|
||||
|
||||
unduck:
|
||||
image: code.troylusty.com/troy/unduck:latest
|
||||
container_name: unduck
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.unduck.rule=Host(`unduck.troylusty.com`)"
|
||||
- "traefik.http.routers.unduck.entrypoints=websecure"
|
||||
- "traefik.http.routers.unduck.tls.certresolver=myresolver"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- "traefik.http.routers.unduck.middlewares=securityHeaders"
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- traefik
|
||||
depends_on:
|
||||
traefik:
|
||||
condition: service_healthy
|
||||
|
||||
forgejo:
|
||||
image: codeberg.org/forgejo/forgejo:10
|
||||
container_name: forgejo
|
||||
restart: unless-stopped
|
||||
networks:
|
||||
- traefik
|
||||
- forgejo
|
||||
labels:
|
||||
- "traefik.enable=true"
|
||||
- "traefik.http.routers.forgejo.rule=Host(`code.troylusty.com`)"
|
||||
- "traefik.http.routers.forgejo.entrypoints=websecure"
|
||||
- "traefik.http.routers.forgejo.tls.certresolver=myresolver"
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
- "traefik.http.routers.forgejo.middlewares=securityHeaders"
|
||||
- "traefik.http.services.forgejo.loadbalancer.server.port=3000"
|
||||
- "traefik.docker.network=traefik"
|
||||
volumes:
|
||||
- ./forgejo:/data
|
||||
ports:
|
||||
- "2222:22"
|
||||
depends_on:
|
||||
traefik:
|
||||
condition: service_healthy
|
||||
|
||||
forgejo-runner:
|
||||
image: code.forgejo.org/forgejo/runner:6.0.1
|
||||
container_name: forgejo-runner
|
||||
user: 0:0
|
||||
depends_on:
|
||||
forgejo:
|
||||
condition: service_started
|
||||
networks:
|
||||
- forgejo
|
||||
labels:
|
||||
- "com.centurylinklabs.watchtower.enable=true"
|
||||
volumes:
|
||||
- ./forgejo-runner:/data
|
||||
- ./forgejo-runner/config.yml:/data/config.yml
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
restart: unless-stopped
|
||||
command: forgejo-runner -c /data/config.yml daemon
|
||||
|
||||
networks:
|
||||
traefik:
|
||||
external: false
|
||||
name: traefik
|
||||
forgejo:
|
||||
external: false
|
||||
name: forgejo
|
||||
|
||||
volumes:
|
||||
letsencrypt:
|
||||
```
|
Binary file not shown.
Before Width: | Height: | Size: 160 KiB |
Loading…
Add table
Add a link
Reference in a new issue