Create AI chat agent for VS Code with Docker service management

Co-authored-by: kelinfoxy <67766943+kelinfoxy@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-01-11 22:50:55 +00:00
parent 0c78b3f038
commit 1b1464e278
11 changed files with 2873 additions and 1 deletions

228
docker-compose/README.md Normal file
View File

@@ -0,0 +1,228 @@
# Docker Compose Stacks
This directory contains Docker Compose files for managing your homelab services. Each file is organized by functional area to maintain clarity and organization.
## Structure
```
docker-compose/
├── infrastructure.yml # Core services (reverse proxy, DNS, etc.)
├── media.yml # Media server services (Plex, Jellyfin, etc.)
├── monitoring.yml # Observability stack (Prometheus, Grafana, etc.)
├── development.yml # Development tools and services
└── README.md # This file
```
## Usage
### Starting Services
Start all services in a compose file:
```bash
docker compose -f docker-compose/infrastructure.yml up -d
```
Start a specific service:
```bash
docker compose -f docker-compose/media.yml up -d plex
```
Start multiple compose files together:
```bash
docker compose -f docker-compose/infrastructure.yml -f docker-compose/media.yml up -d
```
### Stopping Services
Stop all services in a compose file:
```bash
docker compose -f docker-compose/infrastructure.yml down
```
Stop a specific service:
```bash
docker compose -f docker-compose/media.yml stop plex
```
### Viewing Status
Check running services:
```bash
docker compose -f docker-compose/media.yml ps
```
View logs:
```bash
docker compose -f docker-compose/media.yml logs -f plex
```
### Updating Services
Pull latest images:
```bash
docker compose -f docker-compose/media.yml pull
```
Update a specific service:
```bash
docker compose -f docker-compose/media.yml pull plex
docker compose -f docker-compose/media.yml up -d plex
```
## Networks
All services connect to a shared bridge network called `homelab-network`. Create it once:
```bash
docker network create homelab-network
```
Some services may use additional networks for security isolation:
- `monitoring-network` - For monitoring stack
- `database-network` - For database isolation
- `media-network` - For media services
Create them as needed:
```bash
docker network create monitoring-network
docker network create database-network
docker network create media-network
```
## Environment Variables
Create a `.env` file in the root of your homelab directory with common variables:
```bash
# .env
PUID=1000
PGID=1000
TZ=America/New_York
USERDIR=/home/username/homelab
DATADIR=/mnt/data
```
Never commit `.env` files to git! Use `.env.example` as a template instead.
## Best Practices
1. **Pin Versions**: Always specify image versions (e.g., `nginx:1.25.3` not `nginx:latest`)
2. **Use Labels**: Add labels for organization and documentation
3. **Health Checks**: Define health checks for critical services
4. **Resource Limits**: Set memory and CPU limits for resource-intensive services
5. **Logging**: Configure log rotation to prevent disk space issues
6. **Restart Policies**: Use `unless-stopped` for most services
7. **Comments**: Document non-obvious configurations
## Template
When creating a new service, use this template:
```yaml
services:
service-name:
image: vendor/image:version
container_name: service-name
restart: unless-stopped
networks:
- homelab-network
ports:
- "host_port:container_port"
volumes:
- ./config/service-name:/config
- service-data:/data
environment:
- PUID=${PUID}
- PGID=${PGID}
- TZ=${TZ}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:port/health"]
interval: 30s
timeout: 10s
retries: 3
labels:
- "homelab.category=category"
- "homelab.description=Service description"
volumes:
service-data:
driver: local
networks:
homelab-network:
external: true
```
## Troubleshooting
### Service won't start
1. Check logs: `docker compose -f file.yml logs service-name`
2. Validate config: `docker compose -f file.yml config`
3. Check for port conflicts: `sudo netstat -tlnp | grep PORT`
4. Verify volumes exist and have correct permissions
### Permission errors
1. Ensure PUID and PGID match your user: `id -u` and `id -g`
2. Fix directory ownership: `sudo chown -R 1000:1000 ./config/service-name`
### Network issues
1. Verify network exists: `docker network ls`
2. Check service is connected: `docker network inspect homelab-network`
3. Test connectivity: `docker compose exec service1 ping service2`
## Migration from Docker Run
If you have services running via `docker run`, migrate them to compose:
1. Get current configuration:
```bash
docker inspect container-name > container-config.json
```
2. Convert to compose format (extract image, ports, volumes, environment)
3. Test the compose configuration
4. Stop old container:
```bash
docker stop container-name
docker rm container-name
```
5. Start with compose:
```bash
docker compose -f file.yml up -d
```
## Backup Strategy
Regular backups are essential:
```bash
# Backup compose files (already in git)
git add docker-compose/*.yml
git commit -m "Update compose configurations"
# Backup volumes
docker run --rm \
-v volume-name:/data \
-v $(pwd)/backups:/backup \
busybox tar czf /backup/volume-name-$(date +%Y%m%d).tar.gz /data
# Backup config directories
tar czf backups/config-$(date +%Y%m%d).tar.gz config/
```
## Getting Help
- Check the [Docker Guidelines](../docs/docker-guidelines.md) for detailed documentation
- Review the [GitHub Copilot Instructions](../.github/copilot-instructions.md) for AI assistance
- Consult service-specific documentation in `config/service-name/README.md`
## Examples
See the example compose files in this directory:
- `infrastructure.yml` - Essential services like reverse proxy
- `media.yml` - Media server stack
- `monitoring.yml` - Observability and monitoring
- `development.yml` - Development environments and tools

View File

@@ -0,0 +1,187 @@
# Development Services
# Tools and services for development work
services:
# Code Server - VS Code in the browser
# Access at: http://server-ip:8443
code-server:
image: lscr.io/linuxserver/code-server:4.20.0
container_name: code-server
restart: unless-stopped
networks:
- homelab-network
ports:
- "8443:8443"
volumes:
- ./config/code-server:/config
- ${PROJECTDIR:-/home/user/projects}:/projects
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
- TZ=${TZ:-America/New_York}
- PASSWORD=${CODE_SERVER_PASSWORD:-changeme}
- SUDO_PASSWORD=${CODE_SERVER_SUDO_PASSWORD:-changeme}
labels:
- "homelab.category=development"
- "homelab.description=VS Code in browser for remote development"
# GitLab CE - Self-hosted Git repository manager
# Access at: http://server-ip:8929
# Note: Requires significant resources (4GB+ RAM recommended)
gitlab:
image: gitlab/gitlab-ce:16.7.0-ce.0
container_name: gitlab
restart: unless-stopped
networks:
- homelab-network
ports:
- "8929:80" # Web UI
- "2222:22" # SSH
volumes:
- ./config/gitlab/config:/etc/gitlab
- gitlab-logs:/var/log/gitlab
- gitlab-data:/var/opt/gitlab
environment:
GITLAB_OMNIBUS_CONFIG: |
external_url 'http://${SERVER_IP}:8929'
gitlab_rails['gitlab_shell_ssh_port'] = 2222
gitlab_rails['time_zone'] = '${TZ:-America/New_York}'
shm_size: '256m'
deploy:
resources:
limits:
memory: 4G
reservations:
memory: 2G
labels:
- "homelab.category=development"
- "homelab.description=Self-hosted Git repository manager"
# PostgreSQL - Database for development
# Access at: localhost:5432 from other containers
postgres:
image: postgres:16.1-alpine
container_name: postgres-dev
restart: unless-stopped
networks:
- database-network
- homelab-network
ports:
- "5432:5432"
volumes:
- postgres-data:/var/lib/postgresql/data
- ./config/postgres/init:/docker-entrypoint-initdb.d
environment:
- POSTGRES_USER=${POSTGRES_USER:-postgres}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-changeme}
- POSTGRES_DB=${POSTGRES_DB:-homelab}
- PGDATA=/var/lib/postgresql/data/pgdata
labels:
- "homelab.category=development"
- "homelab.description=PostgreSQL database for development"
# Redis - In-memory data store
# Access at: localhost:6379 from other containers
redis:
image: redis:7.2.3-alpine
container_name: redis-dev
restart: unless-stopped
networks:
- database-network
- homelab-network
ports:
- "6379:6379"
volumes:
- redis-data:/data
- ./config/redis/redis.conf:/usr/local/etc/redis/redis.conf
command: redis-server /usr/local/etc/redis/redis.conf --appendonly yes
labels:
- "homelab.category=development"
- "homelab.description=Redis in-memory data store"
# pgAdmin - PostgreSQL management UI
# Access at: http://server-ip:5050
pgadmin:
image: dpage/pgadmin4:8.2
container_name: pgadmin
restart: unless-stopped
networks:
- database-network
- homelab-network
ports:
- "5050:80"
volumes:
- pgadmin-data:/var/lib/pgadmin
environment:
- PGADMIN_DEFAULT_EMAIL=${PGADMIN_EMAIL:-admin@example.com}
- PGADMIN_DEFAULT_PASSWORD=${PGADMIN_PASSWORD:-changeme}
- PGADMIN_CONFIG_SERVER_MODE=False
depends_on:
- postgres
labels:
- "homelab.category=development"
- "homelab.description=PostgreSQL administration UI"
# Jupyter Lab - Interactive computing notebooks
# Access at: http://server-ip:8888
# Token displayed in logs on first start
jupyter:
image: jupyter/scipy-notebook:2023-12-25
container_name: jupyter
restart: unless-stopped
networks:
- homelab-network
ports:
- "8888:8888"
volumes:
- ./config/jupyter:/home/jovyan/work
environment:
- JUPYTER_ENABLE_LAB=yes
- GRANT_SUDO=yes
user: root
command: start-notebook.sh --NotebookApp.token='${JUPYTER_TOKEN:-changeme}'
# Uncomment for GPU support (NVIDIA)
# runtime: nvidia
# environment:
# - NVIDIA_VISIBLE_DEVICES=all
labels:
- "homelab.category=development"
- "homelab.description=Jupyter Lab for data science and ML"
# Node-RED - Visual programming for automation
# Access at: http://server-ip:1880
nodered:
image: nodered/node-red:3.1.3
container_name: nodered
restart: unless-stopped
networks:
- homelab-network
ports:
- "1880:1880"
volumes:
- nodered-data:/data
environment:
- TZ=${TZ:-America/New_York}
labels:
- "homelab.category=development"
- "homelab.description=Visual automation and workflow tool"
volumes:
gitlab-logs:
driver: local
gitlab-data:
driver: local
postgres-data:
driver: local
redis-data:
driver: local
pgadmin-data:
driver: local
nodered-data:
driver: local
networks:
database-network:
driver: bridge
homelab-network:
external: true

View File

@@ -0,0 +1,107 @@
# Infrastructure Services
# Core services that other services depend on
services:
# Nginx Proxy Manager - Web-based reverse proxy management
# Access at: http://server-ip:81
# Default credentials: admin@example.com / changeme
nginx-proxy-manager:
image: jc21/nginx-proxy-manager:2.10.4
container_name: nginx-proxy-manager
restart: unless-stopped
networks:
- homelab-network
ports:
- "80:80" # HTTP
- "443:443" # HTTPS
- "81:81" # Admin UI
volumes:
- ./config/nginx-proxy-manager/data:/data
- ./config/nginx-proxy-manager/letsencrypt:/etc/letsencrypt
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:81"]
interval: 30s
timeout: 10s
retries: 3
labels:
- "homelab.category=infrastructure"
- "homelab.description=Reverse proxy with Let's Encrypt support"
# Pi-hole - Network-wide ad blocker and DNS server
# Access at: http://server-ip:8080/admin
pihole:
image: pihole/pihole:2024.01.0
container_name: pihole
restart: unless-stopped
networks:
- homelab-network
ports:
- "53:53/tcp" # DNS TCP
- "53:53/udp" # DNS UDP
- "8080:80/tcp" # Web interface
volumes:
- ./config/pihole/etc-pihole:/etc/pihole
- ./config/pihole/etc-dnsmasq.d:/etc/dnsmasq.d
environment:
- TZ=${TZ:-America/New_York}
- WEBPASSWORD=${PIHOLE_PASSWORD:-changeme}
- FTLCONF_LOCAL_IPV4=${SERVER_IP}
dns:
- 127.0.0.1
- 1.1.1.1
cap_add:
- NET_ADMIN
labels:
- "homelab.category=infrastructure"
- "homelab.description=Network-wide ad blocking and DNS"
# Portainer - Docker management UI
# Access at: http://server-ip:9000
portainer:
image: portainer/portainer-ce:2.19.4
container_name: portainer
restart: unless-stopped
networks:
- homelab-network
ports:
- "9000:9000"
- "9443:9443"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- portainer-data:/data
security_opt:
- no-new-privileges:true
labels:
- "homelab.category=infrastructure"
- "homelab.description=Docker container management UI"
# Watchtower - Automatic container updates
# Runs silently in background, no UI
watchtower:
image: containrrr/watchtower:1.7.1
container_name: watchtower
restart: unless-stopped
networks:
- homelab-network
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
- WATCHTOWER_CLEANUP=true
- WATCHTOWER_INCLUDE_RESTARTING=true
- WATCHTOWER_SCHEDULE=0 0 4 * * * # 4 AM daily
- WATCHTOWER_NOTIFICATIONS=shoutrrr
- WATCHTOWER_NOTIFICATION_URL=${WATCHTOWER_NOTIFICATION_URL}
labels:
- "homelab.category=infrastructure"
- "homelab.description=Automatic Docker container updates"
volumes:
portainer-data:
driver: local
networks:
homelab-network:
external: true

171
docker-compose/media.yml Normal file
View File

@@ -0,0 +1,171 @@
# Media Services
# Services for media management and streaming
services:
# Plex Media Server - Media streaming platform
# Access at: http://server-ip:32400/web
plex:
image: plexinc/pms-docker:1.40.0.7998-f68041501
container_name: plex
restart: unless-stopped
networks:
- media-network
- homelab-network
ports:
- "32400:32400" # Plex web UI
volumes:
- ./config/plex:/config
- ${MEDIADIR:-/media}:/media:ro
- plex-transcode:/transcode
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
- TZ=${TZ:-America/New_York}
- PLEX_CLAIM=${PLEX_CLAIM}
- ADVERTISE_IP=http://${SERVER_IP}:32400/
devices:
# Uncomment for hardware transcoding (Intel QuickSync)
# - /dev/dri:/dev/dri
# Uncomment for NVIDIA GPU transcoding
# - /dev/nvidia0:/dev/nvidia0
# - /dev/nvidiactl:/dev/nvidiactl
# - /dev/nvidia-modeset:/dev/nvidia-modeset
# - /dev/nvidia-uvm:/dev/nvidia-uvm
# - /dev/nvidia-uvm-tools:/dev/nvidia-uvm-tools
# Uncomment for NVIDIA GPU support
# runtime: nvidia
# environment:
# - NVIDIA_VISIBLE_DEVICES=all
# - NVIDIA_DRIVER_CAPABILITIES=compute,video,utility
labels:
- "homelab.category=media"
- "homelab.description=Plex media streaming server"
# Jellyfin - Free alternative to Plex
# Access at: http://server-ip:8096
jellyfin:
image: jellyfin/jellyfin:10.8.13
container_name: jellyfin
restart: unless-stopped
networks:
- media-network
- homelab-network
ports:
- "8096:8096"
volumes:
- ./config/jellyfin:/config
- ./config/jellyfin/cache:/cache
- ${MEDIADIR:-/media}:/media:ro
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
- TZ=${TZ:-America/New_York}
devices:
# Uncomment for hardware transcoding
# - /dev/dri:/dev/dri
labels:
- "homelab.category=media"
- "homelab.description=Open-source media streaming server"
# Sonarr - TV show automation
# Access at: http://server-ip:8989
sonarr:
image: lscr.io/linuxserver/sonarr:4.0.0
container_name: sonarr
restart: unless-stopped
networks:
- media-network
- homelab-network
ports:
- "8989:8989"
volumes:
- ./config/sonarr:/config
- ${MEDIADIR:-/media}:/media
- ${DOWNLOADDIR:-/downloads}:/downloads
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
- TZ=${TZ:-America/New_York}
labels:
- "homelab.category=media"
- "homelab.description=TV show management and automation"
# Radarr - Movie automation
# Access at: http://server-ip:7878
radarr:
image: lscr.io/linuxserver/radarr:5.2.6
container_name: radarr
restart: unless-stopped
networks:
- media-network
- homelab-network
ports:
- "7878:7878"
volumes:
- ./config/radarr:/config
- ${MEDIADIR:-/media}:/media
- ${DOWNLOADDIR:-/downloads}:/downloads
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
- TZ=${TZ:-America/New_York}
labels:
- "homelab.category=media"
- "homelab.description=Movie management and automation"
# Prowlarr - Indexer manager
# Access at: http://server-ip:9696
prowlarr:
image: lscr.io/linuxserver/prowlarr:1.11.4
container_name: prowlarr
restart: unless-stopped
networks:
- media-network
- homelab-network
ports:
- "9696:9696"
volumes:
- ./config/prowlarr:/config
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
- TZ=${TZ:-America/New_York}
labels:
- "homelab.category=media"
- "homelab.description=Indexer manager for Sonarr/Radarr"
# qBittorrent - Torrent client
# Access at: http://server-ip:8081
# Default credentials: admin / adminadmin
qbittorrent:
image: lscr.io/linuxserver/qbittorrent:4.6.2
container_name: qbittorrent
restart: unless-stopped
networks:
- media-network
- homelab-network
ports:
- "8081:8081" # Web UI
- "6881:6881" # Torrent port TCP
- "6881:6881/udp" # Torrent port UDP
volumes:
- ./config/qbittorrent:/config
- ${DOWNLOADDIR:-/downloads}:/downloads
environment:
- PUID=${PUID:-1000}
- PGID=${PGID:-1000}
- TZ=${TZ:-America/New_York}
- WEBUI_PORT=8081
labels:
- "homelab.category=media"
- "homelab.description=Torrent download client"
volumes:
plex-transcode:
driver: local
networks:
media-network:
driver: bridge
homelab-network:
external: true

View File

@@ -0,0 +1,173 @@
# Monitoring and Observability Services
# Services for monitoring your homelab infrastructure
services:
# Prometheus - Metrics collection and storage
# Access at: http://server-ip:9090
prometheus:
image: prom/prometheus:v2.48.1
container_name: prometheus
restart: unless-stopped
networks:
- monitoring-network
- homelab-network
ports:
- "9090:9090"
volumes:
- ./config/prometheus:/etc/prometheus
- prometheus-data:/prometheus
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--storage.tsdb.path=/prometheus'
- '--storage.tsdb.retention.time=30d'
- '--web.console.libraries=/etc/prometheus/console_libraries'
- '--web.console.templates=/etc/prometheus/consoles'
- '--web.enable-lifecycle'
user: "${PUID:-1000}:${PGID:-1000}"
labels:
- "homelab.category=monitoring"
- "homelab.description=Metrics collection and time-series database"
# Grafana - Metrics visualization
# Access at: http://server-ip:3000
# Default credentials: admin / admin (change on first login)
grafana:
image: grafana/grafana:10.2.3
container_name: grafana
restart: unless-stopped
networks:
- monitoring-network
- homelab-network
ports:
- "3000:3000"
volumes:
- grafana-data:/var/lib/grafana
- ./config/grafana/provisioning:/etc/grafana/provisioning
environment:
- GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASSWORD:-admin}
- GF_USERS_ALLOW_SIGN_UP=false
- GF_SERVER_ROOT_URL=http://${SERVER_IP}:3000
- GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource,grafana-piechart-panel
user: "${PUID:-1000}:${PGID:-1000}"
depends_on:
- prometheus
labels:
- "homelab.category=monitoring"
- "homelab.description=Metrics visualization and dashboards"
# Node Exporter - Host metrics exporter
# Metrics at: http://server-ip:9100/metrics
node-exporter:
image: prom/node-exporter:v1.7.0
container_name: node-exporter
restart: unless-stopped
networks:
- monitoring-network
ports:
- "9100:9100"
volumes:
- /proc:/host/proc:ro
- /sys:/host/sys:ro
- /:/rootfs:ro
command:
- '--path.procfs=/host/proc'
- '--path.rootfs=/rootfs'
- '--path.sysfs=/host/sys'
- '--collector.filesystem.mount-points-exclude=^/(sys|proc|dev|host|etc)($$|/)'
labels:
- "homelab.category=monitoring"
- "homelab.description=Hardware and OS metrics exporter"
# cAdvisor - Container metrics exporter
# Access at: http://server-ip:8082
cadvisor:
image: gcr.io/cadvisor/cadvisor:v0.47.2
container_name: cadvisor
restart: unless-stopped
networks:
- monitoring-network
ports:
- "8082:8080"
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker:/var/lib/docker:ro
- /dev/disk:/dev/disk:ro
privileged: true
devices:
- /dev/kmsg
labels:
- "homelab.category=monitoring"
- "homelab.description=Container metrics and performance monitoring"
# Uptime Kuma - Uptime monitoring
# Access at: http://server-ip:3001
uptime-kuma:
image: louislam/uptime-kuma:1.23.11
container_name: uptime-kuma
restart: unless-stopped
networks:
- monitoring-network
- homelab-network
ports:
- "3001:3001"
volumes:
- uptime-kuma-data:/app/data
labels:
- "homelab.category=monitoring"
- "homelab.description=Service uptime monitoring and alerts"
# Loki - Log aggregation
# Access at: http://server-ip:3100
loki:
image: grafana/loki:2.9.3
container_name: loki
restart: unless-stopped
networks:
- monitoring-network
ports:
- "3100:3100"
volumes:
- ./config/loki:/etc/loki
- loki-data:/loki
command: -config.file=/etc/loki/loki-config.yml
user: "${PUID:-1000}:${PGID:-1000}"
labels:
- "homelab.category=monitoring"
- "homelab.description=Log aggregation system"
# Promtail - Log shipper for Loki
# Ships Docker container logs to Loki
promtail:
image: grafana/promtail:2.9.3
container_name: promtail
restart: unless-stopped
networks:
- monitoring-network
volumes:
- ./config/promtail:/etc/promtail
- /var/log:/var/log:ro
- /var/lib/docker/containers:/var/lib/docker/containers:ro
command: -config.file=/etc/promtail/promtail-config.yml
depends_on:
- loki
labels:
- "homelab.category=monitoring"
- "homelab.description=Log collector for Loki"
volumes:
prometheus-data:
driver: local
grafana-data:
driver: local
uptime-kuma-data:
driver: local
loki-data:
driver: local
networks:
monitoring-network:
driver: bridge
homelab-network:
external: true