Compare commits

1 Commits

Author SHA1 Message Date
muszyn 9912f0a4a7 initial commit 2025-12-17 11:08:03 -05:00
10 changed files with 153 additions and 284 deletions
-69
View File
@@ -1,69 +0,0 @@
# Advanced compose.yaml with additional options
# Rename to compose.yaml to use this configuration
services:
portfolio:
build:
context: .
dockerfile: Dockerfile
container_name: portfolio
restart: unless-stopped
# Environment variables
environment:
- NODE_ENV=production
# Add any custom Next.js environment variables here
# - NEXT_PUBLIC_SITE_URL=https://portfolio.yourdomain.com
# Health check
healthcheck:
test: ["CMD", "node", "-e", "require('http').get('http://localhost:3000', (r) => {process.exit(r.statusCode === 200 ? 0 : 1)})"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
networks:
- traefik
labels:
# Enable Traefik
- "traefik.enable=true"
# HTTP Router
- "traefik.http.routers.portfolio.rule=Host(`portfolio.yourdomain.com`)"
- "traefik.http.routers.portfolio.entrypoints=web"
# HTTPS Router
- "traefik.http.routers.portfolio-secure.rule=Host(`portfolio.yourdomain.com`)"
- "traefik.http.routers.portfolio-secure.entrypoints=websecure"
- "traefik.http.routers.portfolio-secure.tls=true"
- "traefik.http.routers.portfolio-secure.tls.certresolver=letsencrypt"
# HTTP to HTTPS Redirect
- "traefik.http.routers.portfolio.middlewares=portfolio-redirect"
- "traefik.http.middlewares.portfolio-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.portfolio-redirect.redirectscheme.permanent=true"
# Optional: Security Headers
- "traefik.http.routers.portfolio-secure.middlewares=portfolio-headers"
- "traefik.http.middlewares.portfolio-headers.headers.customFrameOptionsValue=SAMEORIGIN"
- "traefik.http.middlewares.portfolio-headers.headers.customResponseHeaders.X-Robots-Tag=index,follow"
- "traefik.http.middlewares.portfolio-headers.headers.sslRedirect=true"
- "traefik.http.middlewares.portfolio-headers.headers.stsSeconds=31536000"
- "traefik.http.middlewares.portfolio-headers.headers.stsIncludeSubdomains=true"
- "traefik.http.middlewares.portfolio-headers.headers.stsPreload=true"
# Service
- "traefik.http.services.portfolio.loadbalancer.server.port=3000"
# Dockge metadata
- "com.dockge.project=portfolio"
- "com.dockge.description=Personal portfolio website"
# Watchtower auto-update (optional, if you use Watchtower)
- "com.centurylinklabs.watchtower.enable=true"
networks:
traefik:
external: true
+4 -19
View File
@@ -6,33 +6,18 @@ services:
container_name: portfolio container_name: portfolio
restart: unless-stopped restart: unless-stopped
networks: networks:
- traefik - proxy
labels: labels:
# Enable Traefik
- "traefik.enable=true" - "traefik.enable=true"
- "traefik.http.routers.portfolio-secure.rule=Host(`site.musyzn.dev`)"
# HTTP Router
- "traefik.http.routers.portfolio.rule=Host(`portfolio.yourdomain.com`)"
- "traefik.http.routers.portfolio.entrypoints=web"
# HTTPS Router
- "traefik.http.routers.portfolio-secure.rule=Host(`portfolio.yourdomain.com`)"
- "traefik.http.routers.portfolio-secure.entrypoints=websecure" - "traefik.http.routers.portfolio-secure.entrypoints=websecure"
- "traefik.http.routers.portfolio-secure.tls=true" - "traefik.http.routers.portfolio-secure.tls=true"
- "traefik.http.routers.portfolio-secure.tls.certresolver=letsencrypt" - "traefik.http.routers.portfolio-secure.tls.certresolver=letsencrypt"
# HTTP to HTTPS Redirect
- "traefik.http.routers.portfolio.middlewares=portfolio-redirect"
- "traefik.http.middlewares.portfolio-redirect.redirectscheme.scheme=https"
- "traefik.http.middlewares.portfolio-redirect.redirectscheme.permanent=true"
# Service
- "traefik.http.services.portfolio.loadbalancer.server.port=3000" - "traefik.http.services.portfolio.loadbalancer.server.port=3000"
# Dockge metadata (optional, for better organization in Dockge) - "com.dockge.project=site"
- "com.dockge.project=portfolio"
- "com.dockge.description=Personal portfolio website" - "com.dockge.description=Personal portfolio website"
networks: networks:
traefik: proxy:
external: true external: true
+115
View File
@@ -0,0 +1,115 @@
---
title: 'Bluetooth on Linux'
date: '2025-12-08'
excerpt: 'Learn how to use bluetooth on a debian based linux distribution.'
---
So I've been on quite the journey learning linux as my daily driver operating system.
Today I wanted to pair my bluetooth keyboard to my desktop because.. why not, I like swapping between a few keyboards sometimes.
I went to the panel/app bar and saw no trace of a 'bluetooth' icon I had come to expect during my days on Windows and MacOS.
I attempted to look for a 'bluetooth' app to no avail and then finally went to the internet.
It didn't take long to find that my flavor of linux (mint) has a built in `bluetoothctl` tool that we can use.
## bluetoothctl
There are two ways to use `bluetoothctl` the first is by prepending every command with `bluetoothctl`. This is how the tutorial ran me through it but I wasn't a big fan and opted for the alternative way.
If you just type `bluetoothctl` you will enter an interactive utility.
```
muszyn:~/$ bluetoothctl
[Keychron K6 Pro]# Agent registered
[Keychron K6 Pro]# [CHG] Controller B4:6B:FC:6A:DB:27 Pairable: yes
```
> You may notice that I have a bluetooth device already registered `Keychron K6 Pro`, this is the keyboard I am currently using.
Once you are in the control menu there are a list of commands to easily get started:
> you can type `help` at any time to print a list of all available commands.
- scan on | scan off
- pair `{device-mac-addr}`
- connect `{device-mac-addr}`
- devices
- remove `{device-mac-addr}`
- disconnect `{device-mac-addr}`
So lets put these commands to work.
## Scanning for Devices
To search for a bluetooth device that you can connect to use the scan command.
```bash
scan on
```
This will begin discovery and output the devices that your system detects.
```
[Keychron K6 Pro]# scan on
[Keychron K6 Pro]# SetDiscoveryFilter success
[Keychron K6 Pro]# Discovery started
[Keychron K6 Pro]# [CHG] Controller B4:6B:FC:6A:DB:27 Discovering: yes
[Keychron K6 Pro]# [NEW] Device 55:41:D0:21:FD:EE 55-41-D0-21-FD-EE
[Keychron K6 Pro]# [NEW] Device 04:D5:83:26:88:0A KM18
```
The output above has a good deal of information so lets break it down.
Bluetooth devices are labeled as **Device** follwed by their Media Access Control (MAC) addresses which is a unique identifier for the device. All MAC addresses follow the format **XX:XX:XX:XX:XX:XX**. If the device has a name associated with it like *KM18*, bluetoothctl will display it. However, not every device has a display name as shown above by *55-41-D0-21-FD-EE* which is just the MAC address with '-' instead of ':'.
## Connecting to a Device
Once we have found a list of available devices we can choose to connect to one.
The first step is to pair your system to the device using the `pair` command.
Using KM18 in the list above:
```bash
pair 04:D5:83:26:88:0A
```
> Note: when using the interactive utility you can press `TAB` twice to ouput the available MAC addresses, begin typing one and then press `TAB` once to auto-fill the rest of the address.
If this isn't your first time pairing to the device then you can use the `connect` command to establish a bluetooth connection.
This is useful if your device does not automatically connect on startup or if you would like to take over the connection from another device (this happens all the time with my headphones).
```bash
connect 04:D5:83:26:88:0A
```
## Listing Paired Devices
Using the utility listing paried devices can be useful if you don't want to `scan` all the time.
```bash
devices Paried
```
This will output a list of your paired devices that you can then use to connect/disconnect from your system.
## Disconnecting Devices
To unpair the device use the `remove` command.
```bash
remove 04:D5:83:26:88:0A
```
To disconnect the device use the `disconnect` command:
```bash
disconnect 04:D5:83:26:88:0A
```
## Exiting the Interactive Mode
To exit, either type `exit`, or `quit`, OR you can use `ctl+D` whichever you prefer.
## Non-Interactive
If you want to use the non-interactive tool then simply place `bluetoothctl` in front of each command.
The primary benefit I found for the interactive tool was the tab completion for the MAC addresses :D.
-37
View File
@@ -1,37 +0,0 @@
---
title: 'Building Beautiful UIs with shadcn/ui'
date: '2025-12-08'
excerpt: 'Discover how shadcn/ui can accelerate your UI development with beautiful, accessible components.'
---
# Building Beautiful UIs with shadcn/ui
shadcn/ui has revolutionized how we build component libraries. Unlike traditional component libraries, shadcn/ui gives you full ownership of your components.
## What Makes shadcn/ui Different?
Instead of installing components as dependencies, shadcn/ui copies the component code directly into your project. This means:
- **Full Control**: Modify components however you need
- **No Lock-in**: You own the code, no vendor lock-in
- **Tailwind CSS**: Built on top of Tailwind CSS for easy customization
## Getting Started
Installation is straightforward:
```bash
npx shadcn@latest init
```
Then add components as needed:
```bash
npx shadcn@latest add button
```
## Customization
Since the components are in your codebase, customization is as simple as editing the files. No need to override styles or fight with CSS specificity.
shadcn/ui is the perfect choice for teams that want beautiful components with complete control.
@@ -1,24 +0,0 @@
---
title: 'Getting Started with Next.js'
date: '2025-12-12'
excerpt: 'An introduction to building modern web applications with Next.js and React.'
---
# Getting Started with Next.js
Next.js has become one of the most popular frameworks for building React applications. In this post, we'll explore why Next.js is such a powerful choice for modern web development.
## What is Next.js?
Next.js is a React framework that enables functionality such as server-side rendering and generating static websites. It's built by Vercel and has become the go-to choice for many developers.
## Key Features
- **Server-Side Rendering**: Render your React components on the server for better performance and SEO.
- **Static Site Generation**: Pre-render pages at build time for lightning-fast load times.
- **File-based Routing**: Create routes by simply adding files to the `app` directory.
- **API Routes**: Build API endpoints right within your Next.js application.
## Why Choose Next.js?
Next.js takes care of many of the common challenges in web development, allowing you to focus on building features rather than configuration.
-41
View File
@@ -1,41 +0,0 @@
---
title: 'Tailwind CSS Tips and Tricks'
date: '2025-12-05'
excerpt: 'Level up your Tailwind CSS skills with these advanced tips and tricks.'
---
# Tailwind CSS Tips and Tricks
Tailwind CSS has changed how we write styles. Here are some advanced tips to take your Tailwind skills to the next level.
## Use @apply Sparingly
While `@apply` is useful for extracting repeated patterns, overusing it defeats the purpose of utility-first CSS. Keep most styles in your JSX.
## Leverage JIT Mode
The Just-In-Time compiler generates styles on-demand, giving you:
- Faster build times
- Smaller file sizes
- All variants enabled by default
## Custom Utilities
Extend Tailwind with custom utilities in your `tailwind.config.js`:
```javascript
module.exports = {
theme: {
extend: {
spacing: {
'128': '32rem',
}
}
}
}
```
## Conclusion
These tips will help you use Tailwind CSS more effectively and build better UIs faster.
-41
View File
@@ -1,41 +0,0 @@
---
title: 'TypeScript Best Practices for 2025'
date: '2025-12-10'
excerpt: 'Learn the latest TypeScript best practices to write more maintainable and type-safe code.'
---
# TypeScript Best Practices for 2025
TypeScript has evolved significantly, and with it, the best practices for writing type-safe code have also matured. Let's explore some essential practices for 2025.
## Use Strict Mode
Always enable strict mode in your `tsconfig.json`:
```json
{
"compilerOptions": {
"strict": true
}
}
```
## Leverage Type Inference
TypeScript's type inference is powerful. Let the compiler infer types when it's obvious:
```typescript
// Good
const count = 42;
// Unnecessary
const count: number = 42;
```
## Avoid `any`
The `any` type defeats the purpose of TypeScript. Use `unknown` instead when the type is truly unknown, or take time to properly type your data.
## Conclusion
Following these best practices will help you write more maintainable and bug-free TypeScript code.
+34
View File
@@ -0,0 +1,34 @@
---
title: 'Homelab Server'
description: 'A personal server that replicates a plethora of self-hosted solutions'
links:
github: 'https://github.com/amuszyn/homelab'
---
# Homelab Server
A personal server that replicates a plethora of self-hosted solutions.
## Features
- Git server
- Reverse proxy
- Log aggregation and filtering
- Monitoring and visualization
- Network wide ad-blocking
- VPN
- Automatic photo backup
- Network Security
## Built With
- Dockge
- Docker
- Graphana
- Prometheus
- Traefik
- Gitea
- Wireguard
- PiHole
- Cloudflare
- Immich
-27
View File
@@ -1,27 +0,0 @@
---
title: 'Markdown Editor'
description: 'A sleek markdown editor with live preview and export options'
links:
github: 'https://github.com/username/markdown-editor'
gitea: 'https://gitea.example.com/username/markdown-editor'
---
# Markdown Editor
A beautiful and intuitive markdown editor with real-time preview, syntax highlighting, and multiple export formats.
## Features
- Live preview
- Syntax highlighting
- Export to PDF, HTML
- Dark mode support
- Keyboard shortcuts
- Auto-save
## Built With
- React
- CodeMirror
- react-markdown
- Tailwind CSS
-26
View File
@@ -1,26 +0,0 @@
---
title: 'Task Manager App'
description: 'A collaborative task management application with real-time updates'
links:
github: 'https://github.com/username/task-manager'
live: 'https://tasks.example.com'
---
# Task Manager App
A full-stack task management application that helps teams collaborate and stay organized.
## Key Features
- Real-time collaboration
- Task assignments and due dates
- Project organization
- Priority levels
- Search and filtering
## Tech Stack
- Frontend: React, TypeScript
- Backend: Node.js, Express
- Database: PostgreSQL
- Real-time: Socket.io