Skip to content

Commit 79ed5a1

Browse files
authored
Add dev container config to Horizon (#1181)
Dev container config based on main with pnpm instead of yarn
1 parent 609bc3d commit 79ed5a1

File tree

8 files changed

+504
-0
lines changed

8 files changed

+504
-0
lines changed

.devcontainer/Dockerfile

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
FROM mcr.microsoft.com/devcontainers/base:debian
2+
3+
# Set non-interactive frontend for apt
4+
ENV DEBIAN_FRONTEND=noninteractive
5+
6+
# Switch to root for installing packages
7+
USER root
8+
9+
# Install additional dependencies
10+
RUN apt update && apt install -y \
11+
build-essential \
12+
curl \
13+
jq \
14+
python3 \
15+
python3-pip \
16+
python3-venv \
17+
pipx \
18+
&& apt clean \
19+
&& rm -rf /var/lib/apt/lists/*
20+
21+
# Install Node.js 20.x using NodeSource
22+
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash - && \
23+
apt update && \
24+
apt install -y nodejs && \
25+
apt clean && \
26+
rm -rf /var/lib/apt/lists/*
27+
28+
# Install Solidity compiler using pipx (isolated environment)
29+
RUN pipx install solc-select && \
30+
pipx ensurepath && \
31+
/root/.local/bin/solc-select install 0.8.27 && \
32+
/root/.local/bin/solc-select use 0.8.27 && \
33+
# Copy binaries to /usr/local/bin with proper permissions (not symlinks)
34+
cp /root/.local/bin/solc /usr/local/bin/solc && \
35+
cp /root/.local/bin/solc-select /usr/local/bin/solc-select && \
36+
chmod 755 /usr/local/bin/solc && \
37+
chmod 755 /usr/local/bin/solc-select && \
38+
# Make sure pipx directory is accessible
39+
chmod -R a+rx /root/.local/pipx && \
40+
# Set up for vscode user
41+
mkdir -p /home/vscode/.solc-select && \
42+
cp -r /root/.solc-select/* /home/vscode/.solc-select/ && \
43+
chown -R vscode:vscode /home/vscode/.solc-select
44+
45+
RUN npm install -g ethers@6.13.4
46+
47+
# Install cloc for code analysis
48+
RUN npm install -g cloc
49+
50+
# Install Foundry for Anvil (as root for global installation)
51+
RUN curl -L https://foundry.paradigm.xyz | bash && \
52+
/root/.foundry/bin/foundryup && \
53+
# Copy binaries to /usr/local/bin with proper permissions
54+
cp /root/.foundry/bin/anvil /usr/local/bin/anvil && \
55+
cp /root/.foundry/bin/cast /usr/local/bin/cast && \
56+
cp /root/.foundry/bin/forge /usr/local/bin/forge && \
57+
cp /root/.foundry/bin/chisel /usr/local/bin/chisel && \
58+
# Ensure proper permissions
59+
chmod 755 /usr/local/bin/anvil && \
60+
chmod 755 /usr/local/bin/cast && \
61+
chmod 755 /usr/local/bin/forge && \
62+
chmod 755 /usr/local/bin/chisel
63+
64+
# Set up pnpm
65+
RUN corepack enable && \
66+
corepack prepare pnpm@9.0.6 --activate
67+
68+
# Ensure all users have access to the tools
69+
RUN chmod 755 /usr/local/bin/* && \
70+
# Create a directory for vscode user's binaries
71+
mkdir -p /home/vscode/.local/bin && \
72+
chown -R vscode:vscode /home/vscode/.local/bin
73+
74+
# Switch back to vscode user
75+
USER vscode
76+
77+
# Set environment variables
78+
ENV PATH="/usr/local/bin:/home/vscode/.foundry/bin:/home/vscode/.local/bin:/root/.local/bin:$PATH"
79+
80+
# Create .bashrc additions for PATH
81+
RUN echo 'export PATH="/usr/local/bin:$HOME/.local/bin:$PATH"' >> $HOME/.bashrc
82+
83+
# Set the default command
84+
CMD ["sleep", "infinity"]

.devcontainer/README.md

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
# Graph Protocol Contracts Dev Container
2+
3+
This directory contains configuration files for the Graph Protocol contracts development container.
4+
5+
> **Note:** This dev container setup is a work in progress and will not be fully portable.
6+
7+
## Overview
8+
9+
The dev container provides a consistent development environment with caching to improve performance.
10+
11+
### Key Components
12+
13+
1. **Docker Compose Configuration**: Defines the container setup, volume mounts, and environment variables
14+
2. **Dockerfile**: Specifies the container image and installed tools
15+
3. **project-setup.sh**: Configures the environment after container creation
16+
4. **host-setup.sh**: Sets up the host environment before starting the container
17+
5. **setup-git-signing.sh**: Automatically configures Git to use SSH signing with forwarded SSH keys
18+
19+
## Cache System
20+
21+
The container uses a conservative caching approach to prevent cache corruption issues:
22+
23+
1. **Local Cache Directories**: Each container instance maintains its own cache directories
24+
25+
- `vscode-cache``/home/vscode/.cache` (VS Code cache)
26+
- `vscode-config``/home/vscode/.config` (VS Code configuration)
27+
- `vscode-data``/home/vscode/.local/share` (VS Code data)
28+
- `vscode-bin``/home/vscode/.local/bin` (User binaries)
29+
30+
2. **Safe Caches Only**: Only caches that won't cause cross-branch issues are configured
31+
32+
- GitHub CLI: `/home/vscode/.cache/github`
33+
- Python packages: `/home/vscode/.cache/pip`
34+
35+
3. **Intentionally Not Cached**: These tools use their default cache locations to avoid contamination
36+
- NPM (different dependency versions per branch)
37+
- Foundry, Solidity (different compilation artifacts per branch)
38+
- Hardhat (different build artifacts per branch)
39+
40+
## Setup Instructions
41+
42+
### Start the Dev Container
43+
44+
To start the dev container:
45+
46+
1. Open VS Code
47+
2. Use the "Remote-Containers: Open Folder in Container" command
48+
3. Select the repository directory (for example `/git/graphprotocol/contracts`)
49+
50+
When the container starts, the `project-setup.sh` script will automatically run and:
51+
52+
- Install project dependencies using pnpm
53+
- Configure Git to use SSH signing with your forwarded SSH key
54+
- Source shell customizations if available in PATH
55+
56+
## Environment Variables
57+
58+
Environment variables are defined in two places:
59+
60+
1. **docker-compose.yml**: Contains most of the environment variables for tools and caching
61+
2. **Environment File**: Personal settings are stored in `/opt/configs/graphprotocol/contracts.env` on the host
62+
63+
### Git Configuration
64+
65+
To enable Git commit signing, add the following settings to your environment file:
66+
67+
```env
68+
# Git settings for commit signing
69+
GIT_USER_NAME=Your Name
70+
GIT_USER_EMAIL=your.email@example.com
71+
```
72+
73+
These environment variables are needed for Git commit signing to work properly. If they are not defined, Git commit signing will not be configured, but the container will still work for other purposes.
74+
75+
## Troubleshooting
76+
77+
### Cache Issues
78+
79+
If you encounter build or compilation issues that seem related to cached artifacts:
80+
81+
1. **Rebuild the container**: This will start with fresh local caches
82+
2. **Clean project caches**: Run `pnpm clean` to clear project-specific build artifacts
83+
3. **Clear node modules**: Delete `node_modules` and run `pnpm install` again
84+
85+
### Git SSH Signing Issues
86+
87+
If you encounter issues with Git SSH signing:
88+
89+
1. **SSH Agent Forwarding**: Make sure SSH agent forwarding is properly set up in your VS Code settings
90+
2. **GitHub Configuration**: Ensure your SSH key is added to GitHub as a signing key in your account settings
91+
3. **Manual Setup**: If automatic setup fails, you can manually configure SSH signing:
92+
93+
```bash
94+
# Check available SSH keys
95+
ssh-add -l
96+
97+
# Configure Git to use SSH signing
98+
git config --global gpg.format ssh
99+
git config --global user.signingkey "key::ssh-ed25519 YOUR_KEY_CONTENT"
100+
git config --global gpg.ssh.allowedSignersFile ~/.ssh/allowed_signers
101+
git config --global commit.gpgsign true
102+
103+
# Create allowed signers file
104+
echo "your.email@example.com ssh-ed25519 YOUR_KEY_CONTENT" > ~/.ssh/allowed_signers
105+
```
106+
107+
For other issues, check the `project-setup.sh` and `setup-git-signing.sh` scripts for any errors.

.devcontainer/devcontainer.json

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"name": "graph contracts",
3+
"dockerComposeFile": ["docker-compose.yml"],
4+
"service": "dev-graph-contracts",
5+
"features": {
6+
"ghcr.io/devcontainers/features/git:1": {
7+
"configureGitHubCLI": true,
8+
"gitCredentialHelper": "cache"
9+
},
10+
"ghcr.io/devcontainers/features/github-cli:1": {},
11+
"ghcr.io/devcontainers/features/common-utils:2.5.3": {},
12+
"ghcr.io/devcontainers/features/node:1": {
13+
"version": "20"
14+
},
15+
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
16+
},
17+
"postCreateCommand": ".devcontainer/project-setup.sh",
18+
"remoteUser": "vscode",
19+
"workspaceFolder": "${localWorkspaceFolder}",
20+
"customizations": {
21+
"vscode": {
22+
"extensions": [
23+
"rust-lang.rust-analyzer",
24+
"tamasfe.even-better-toml",
25+
"usernamehw.errorlens",
26+
"yzhang.markdown-all-in-one",
27+
"DavidAnson.vscode-markdownlint",
28+
"shd101wyy.markdown-preview-enhanced",
29+
"bierner.markdown-preview-github-styles",
30+
"Gruntfuggly.todo-tree",
31+
"ms-azuretools.vscode-docker",
32+
"donjayamanne.githistory",
33+
"eamodio.gitlens",
34+
"fill-labs.dependi",
35+
"streetsidesoftware.code-spell-checker",
36+
"Augment.vscode-augment",
37+
"NomicFoundation.hardhat-solidity",
38+
"foundry-rs.foundry-vscode"
39+
]
40+
}
41+
}
42+
}

.devcontainer/docker-compose.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
services:
2+
dev-graph-contracts:
3+
build:
4+
context: .
5+
dockerfile: Dockerfile
6+
env_file:
7+
- /opt/configs/graphprotocol/contracts.env
8+
environment:
9+
# Essential for large builds
10+
- NODE_OPTIONS=--max-old-space-size=4096
11+
12+
# Clean development environment
13+
- PYTHONDONTWRITEBYTECODE=1
14+
15+
# Disable interactive prompts
16+
- COREPACK_ENABLE_DOWNLOAD_PROMPT=0
17+
18+
# Standard user directories
19+
- XDG_CACHE_HOME=/home/vscode/.cache
20+
- XDG_CONFIG_HOME=/home/vscode/.config
21+
- XDG_DATA_HOME=/home/vscode/.local/share
22+
23+
# Safe caches (won't cause cross-branch issues)
24+
- GH_CONFIG_DIR=/home/vscode/.cache/github
25+
- PIP_CACHE_DIR=/home/vscode/.cache/pip
26+
27+
# pnpm cache is safe to share due to content-addressable storage
28+
- PNPM_HOME=/home/vscode/.local/share/pnpm
29+
- PNPM_CACHE_DIR=/home/vscode/.cache/pnpm
30+
31+
# Note: NPM, Foundry, and Solidity caches are intentionally not set
32+
# to avoid cross-branch contamination. Tools will use their default locations.
33+
volumes:
34+
# Git repo root
35+
- /git:/git
36+
37+
# Local directories for user data (keep local to container)
38+
- vscode-cache:/home/vscode/.cache
39+
- vscode-config:/home/vscode/.config
40+
- vscode-data:/home/vscode/.local/share
41+
- vscode-bin:/home/vscode/.local/bin
42+
43+
# Shared pnpm cache (safe due to content-addressable storage)
44+
- pnpm-store:/home/vscode/.local/share/pnpm
45+
- pnpm-cache:/home/vscode/.cache/pnpm
46+
47+
volumes:
48+
vscode-cache:
49+
vscode-config:
50+
vscode-data:
51+
vscode-bin:
52+
pnpm-store:
53+
pnpm-cache:

.devcontainer/host-setup.sh

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/usr/bin/env bash
2+
# Host setup script for Graph Protocol Contracts dev container
3+
# Run this script on the host before starting the dev container
4+
# Usage: sudo .devcontainer/host-setup.sh
5+
6+
set -euo pipefail
7+
8+
echo "Setting up host environment for Graph Protocol Contracts dev container..."
9+
10+
# Check if running as root
11+
if [ "$(id -u)" -ne 0 ]; then
12+
echo "Error: This script must be run as root (sudo)" >&2
13+
exit 1
14+
fi
15+
16+
CACHE_DIRS=(
17+
"/cache/vscode-cache"
18+
"/cache/vscode-config"
19+
"/cache/vscode-data"
20+
"/cache/vscode-bin"
21+
"/cache/hardhat"
22+
"/cache/npm"
23+
"/cache/yarn"
24+
"/cache/pip"
25+
"/cache/pycache"
26+
"/cache/solidity"
27+
"/cache/foundry"
28+
"/cache/github"
29+
"/cache/apt"
30+
"/cache/apt-lib"
31+
)
32+
33+
echo "Creating cache directories..."
34+
for dir in "${CACHE_DIRS[@]}"; do
35+
if [ ! -d "$dir" ]; then
36+
echo "Creating $dir"
37+
mkdir -p "$dir"
38+
chmod 777 "$dir"
39+
else
40+
echo "$dir already exists"
41+
fi
42+
done
43+
44+
# Note: Package-specific directories will be created by the project-setup.sh script
45+
# inside the container, as they are tied to the project structure
46+
47+
echo "Host setup completed successfully!"
48+
echo "You can now start or rebuild your dev container."

0 commit comments

Comments
 (0)