diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 00000000..c1123b2d --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,59 @@ +{ + "name": "Yggdrasil Go Development", + "dockerFile": "../contrib/docker/devcontainer/Dockerfile", + "context": "..", + // Set up port forwarding for development + "forwardPorts": [ + 9000, + 9001, + 9002, + 9003 + ], + // Configure Docker run options for TUN device access + "runArgs": [ + "--privileged", + "--cap-add=NET_ADMIN", + "--device=/dev/net/tun" + ], + // Configure VS Code settings and extensions + "customizations": { + "vscode": { + "settings": { + "go.toolsManagement.checkForUpdates": "local", + "go.useLanguageServer": true, + "go.gopath": "/go", + "go.goroot": "/usr/local/go", + "go.lintTool": "golangci-lint", + "go.lintFlags": [ + "--fast" + ], + "terminal.integrated.defaultProfile.linux": "zsh", + "editor.formatOnSave": true, + "go.formatTool": "goimports", + "go.buildOnSave": "package" + }, + "extensions": [ + "golang.Go" + ] + } + }, + // Environment variables for Go module caching + "containerEnv": { + "GOCACHE": "/home/vscode/.cache/go-build", + "GOMODCACHE": "/home/vscode/.cache/go-mod" + }, + // Post create command to set up the environment + "postCreateCommand": "mkdir -p /home/vscode/.cache/go-build /home/vscode/.cache/go-mod && cd /workspace && go mod download && go mod tidy", + // Keep the container running + "overrideCommand": false, + // Use non-root user + "remoteUser": "vscode", + // Configure container user + "containerUser": "vscode", + "updateRemoteUserUID": true, + // Features to install + "features": { + "ghcr.io/devcontainers/features/git:1": {}, + "ghcr.io/devcontainers/features/github-cli:1": {} + } +} \ No newline at end of file diff --git a/contrib/docker/devcontainer/Dockerfile b/contrib/docker/devcontainer/Dockerfile new file mode 100644 index 00000000..0380a261 --- /dev/null +++ b/contrib/docker/devcontainer/Dockerfile @@ -0,0 +1,60 @@ +# Development Dockerfile for VS Code Dev Containers +FROM golang:1.24-bullseye + +# Install only essential system packages +RUN apt-get update && apt-get install -y \ + git \ + ca-certificates \ + sudo \ + zsh \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# Install Oh My Zsh for better terminal experience +RUN sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)" --unattended + +# Install essential Go development tools only +RUN go install golang.org/x/tools/gopls@latest \ + && go install github.com/go-delve/delve/cmd/dlv@latest \ + && go install golang.org/x/tools/cmd/goimports@latest \ + && go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + +# Create a non-root user for development +ARG USERNAME=vscode +ARG USER_UID=1000 +ARG USER_GID=$USER_UID + +# Create user and group with proper permissions +RUN groupadd --gid $USER_GID $USERNAME \ + && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME -s /bin/zsh \ + && echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME \ + && chmod 0440 /etc/sudoers.d/$USERNAME + +# Fix Go module cache permissions +RUN chown -R $USERNAME:$USERNAME /go/pkg/mod || true \ + && chmod -R 755 /go/pkg/mod || true + +# Create default yggdrasil conf directory +RUN mkdir -p /etc/yggdrasil \ + && chown -R $USERNAME:$USERNAME /etc/yggdrasil + +# Set up the workspace with proper ownership +WORKDIR /workspace +RUN chown $USERNAME:$USERNAME /workspace + +# Copy go module files to enable dependency caching +COPY go.mod go.sum ./ +RUN go mod download && chown -R $USERNAME:$USERNAME /workspace + +# Set up shell environment for vscode user +USER $USERNAME +ENV SHELL=/bin/zsh +RUN echo 'export PATH=$PATH:$(go env GOPATH)/bin' >> ~/.zshrc \ + && echo 'export GO111MODULE=on' >> ~/.zshrc \ + && mkdir -p ~/.cache + +# Expose common ports that might be used by Yggdrasil +EXPOSE 9001 9002 9003 + +# Keep container running for dev containers +CMD ["sleep", "infinity"] \ No newline at end of file diff --git a/contrib/docker/devcontainer/Makefile b/contrib/docker/devcontainer/Makefile new file mode 100644 index 00000000..c2019a2b --- /dev/null +++ b/contrib/docker/devcontainer/Makefile @@ -0,0 +1,36 @@ +# Development container management + +.PHONY: dev-build dev-run dev-shell dev-stop dev-clean + +# Build development container +dev-build: + docker build -f Dockerfile -t yggdrasil-dev . + +# Run development container with volume mounts +dev-run: + docker run -it --rm \ + --name yggdrasil-dev \ + -v $(PWD):/workspace \ + -v ~/.gitconfig:/home/vscode/.gitconfig:ro \ + -p 9001:9001 \ + -p 9002:9002 \ + -p 9003:9003 \ + --privileged \ + --cap-add=NET_ADMIN \ + yggdrasil-dev + +# Get shell access to running container +dev-shell: + docker exec -it yggdrasil-dev /bin/zsh + +# Stop development container +dev-stop: + docker stop yggdrasil-dev || true + +# Clean development artifacts +dev-clean: + docker rmi yggdrasil-dev || true + docker system prune -f + +# Build and run in one command +dev: dev-build dev-run \ No newline at end of file diff --git a/contrib/docker/devcontainer/README.md b/contrib/docker/devcontainer/README.md new file mode 100644 index 00000000..840c5286 --- /dev/null +++ b/contrib/docker/devcontainer/README.md @@ -0,0 +1,112 @@ +# Development Environment Setup + +This document describes how to set up a development environment for Yggdrasil using Docker and VS Code Dev Containers. + +## Prerequisites + +- Docker installed and running +- VS Code with the "Dev Containers" extension installed +- Git configured with your user information + +## Option 1: VS Code Dev Containers (Recommended) + +1. Open this project in VS Code +2. When prompted, click "Reopen in Container" or: + - Press `Ctrl+Shift+P` (or `Cmd+Shift+P` on macOS) + - Type "Dev Containers: Reopen in Container" + - Select the option + +VS Code will automatically build the development container and set up the environment with: +- Go 1.23 with all necessary tools +- Language server (gopls) +- Linting (golangci-lint) +- Debugging support (delve) +- Git integration +- Zsh shell with Oh My Zsh + +## Option 2: Manual Docker Container + +If you prefer to use Docker directly: + +### Using Makefile commands: + +```bash +# Build and run the development container +make -f Makefile dev + +# Or build and run separately +make -f Makefile dev-build +make -f Makefile dev-run + +# Get shell access to running container +make -f Makefile dev-shell + +# Stop the container +make -f Makefile dev-stop + +# Clean up +make -f Makefile dev-clean +``` + +### Using Docker directly: + +```bash +# Build the development image +docker build -f Dockerfile -t yggdrasil-dev . + +# Run the container +docker run -it --rm \ + --name yggdrasil-dev \ + -v $(pwd):/workspace \ + -v ~/.gitconfig:/home/vscode/.gitconfig:ro \ + -p 9000:9000 \ + -p 9001:9001 \ + -p 9002:9002 \ + -p 9003:9003 \ + --privileged \ + --cap-add=NET_ADMIN \ + --device=/dev/net/tun \ + yggdrasil-dev +``` + +## Development Features + +The development environment includes: + +- **Go Tools**: gopls, delve debugger, goimports, golangci-lint, staticcheck +- **Editor Support**: Syntax highlighting, auto-completion, debugging +- **Testing**: Go test runner and coverage tools +- **Networking**: Privileged access for network interface testing +- **Port Forwarding**: Ports 9000-9003 exposed for Yggdrasil services + +## Building and Testing + +Inside the container: + +```bash +# Build the project +./build + +# Run tests +go test ./... + +# Generate configuration +./yggdrasil -genconf > yggdrasil.conf + +# Run with configuration +./yggdrasil -useconf yggdrasil.conf +``` + +## Tips + +1. Your local Git configuration is mounted into the container +2. The workspace directory (`/workspace`) is mapped to your local project directory +3. All changes made to source files are persistent on your host machine +4. The container runs as a non-root user (`vscode`) for security +5. Network capabilities are enabled for testing network-related features + +## Troubleshooting + +- If the container fails to start, ensure Docker has enough resources allocated +- For network-related issues, verify that the container has the necessary privileges +- If Go tools are missing, rebuild the container: `make -f Makefile dev-clean dev-build` \ No newline at end of file