Skip to content

Commit d4384fc

Browse files
committed
chore(devcontainer): simpler setup w/o docker compose
1 parent b625f46 commit d4384fc

15 files changed

Lines changed: 228 additions & 188 deletions

.devcontainer/.env.example

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
# Devcontainer configuration
2-
RUBY_VERSION="3.4.9"
2+
3+
RUBY_VERSION=3.4.9
34

45
# E2E testing
5-
SENTRY_DSN="http://user:pass@sentry.localhost/project/42"
6-
# SENTRY_DSN_JS="http://user:pass@sentry-js.localhost/project/43"
7-
SENTRY_DSN_JS=""
6+
SENTRY_DSN=http://user:pass@sentry.localhost/project/42
7+
# SENTRY_DSN_JS=http://user:pass@sentry-js.localhost/project/43
8+
SENTRY_DSN_JS=
89

910
SENTRY_E2E_RAILS_APP_PORT=4000
1011
SENTRY_E2E_SVELTE_APP_PORT=4001
1112

12-
SENTRY_E2E_RAILS_APP_URL="http://localhost:4000"
13-
SENTRY_E2E_SVELTE_APP_URL="http://localhost:4001"
13+
SENTRY_E2E_RAILS_APP_URL=http://localhost:4000
14+
SENTRY_E2E_SVELTE_APP_URL=http://localhost:4001
1415

1516
# ActiveJob queue adapter under test: async | inline | sidekiq | resque | delayed_job
16-
SENTRY_E2E_ACTIVE_JOB_ADAPTER="async"
17-
18-
# Redis for the sidekiq/resque adapters (the Compose service is named "redis")
19-
REDIS_URL="redis://redis:6379"
17+
SENTRY_E2E_ACTIVE_JOB_ADAPTER=async
2018

21-
# Faster builds with compose
22-
COMPOSE_BAKE=true
19+
# Redis for the sidekiq/resque adapters
20+
REDIS_URL=redis://localhost:6379

.devcontainer/Dockerfile

Lines changed: 6 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,14 @@ RUN userdel -r ubuntu 2>/dev/null || true \
3535
&& groupadd --gid 1000 sentry \
3636
&& useradd --uid 1000 --gid sentry --shell /bin/bash --create-home sentry
3737

38-
WORKDIR /workspace/sentry
38+
WORKDIR /workspaces/sentry-ruby
3939

40-
RUN chown -R sentry:sentry /workspace/sentry
40+
RUN chown -R sentry:sentry /workspaces/sentry-ruby
4141

4242
ENV LANG=C.UTF-8 \
4343
BUNDLE_JOBS=4 \
4444
BUNDLE_RETRY=3 \
45-
REDIS_HOST=redis \
45+
REDIS_HOST=localhost \
4646
PATH=/home/sentry/.local/share/mise/shims:/home/sentry/.local/bin:$PATH
4747

4848
USER sentry
@@ -52,32 +52,6 @@ USER sentry
5252
# directory content when a volume is first attached).
5353
RUN mkdir -p /home/sentry/bundle
5454

55-
RUN curl https://mise.run | sh \
56-
&& echo 'eval "$(/home/sentry/.local/bin/mise activate bash)"' >> /home/sentry/.bashrc \
57-
&& echo 'eval "$(/home/sentry/.local/bin/mise activate zsh)"' >> /home/sentry/.zshenv
58-
59-
# Pre-install Ruby at build time so the container starts immediately without
60-
# downloading it at runtime. Switching Ruby versions requires a rebuild.
61-
ARG RUBY_VERSION=latest
62-
63-
# Java is always installed (required for JRuby). It is listed in .mise.toml so
64-
# it is available for all users regardless of which Ruby flavour they use.
65-
RUN echo "📦 Pre-installing java@temurin-21..." && \
66-
/home/sentry/.local/bin/mise install "java@temurin-21" && \
67-
/home/sentry/.local/bin/mise use --global "java@temurin-21"
68-
69-
RUN echo "📦 Pre-installing ruby@${RUBY_VERSION} (precompiled)..." && \
70-
MISE_RUBY_COMPILE=0 /home/sentry/.local/bin/mise install "ruby@${RUBY_VERSION}" && \
71-
/home/sentry/.local/bin/mise use --global "ruby@${RUBY_VERSION}"
72-
73-
# Node.js is always needed for the svelte-mini e2e app.
74-
RUN echo "📦 Pre-installing node@lts..." && \
75-
/home/sentry/.local/bin/mise install "node@lts" && \
76-
/home/sentry/.local/bin/mise use --global "node@lts"
77-
78-
# Install headless Chromium via Playwright (includes all system dependencies).
79-
# Symlink the binary into ~/.local/bin which is already on PATH.
80-
RUN /home/sentry/.local/share/mise/shims/npx playwright install chromium --with-deps
81-
# Playwright lays out the binary under chrome-linux/ on arm64 and chrome-linux64/
82-
# on x86_64 (since Playwright 1.57), so the glob has to match both.
83-
RUN bash -c 'ln -sf /home/sentry/.cache/ms-playwright/chromium-*/chrome-linux*/chrome /home/sentry/.local/bin/chromium'
55+
# mise and the toolchain (Java, Ruby, Node, Chromium) are installed by the local
56+
# `./features/tools` dev container feature, which runs after this Dockerfile —
57+
# see devcontainer.json.

.devcontainer/VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1.1.0
1+
2.0.0

.devcontainer/devcontainer-lock.json

Lines changed: 0 additions & 34 deletions
This file was deleted.

.devcontainer/devcontainer.json

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,27 @@
11
{
22
"name": "sentry-ruby",
3-
"dockerComposeFile": "docker-compose.yml",
4-
"service": "sentry-dev",
5-
"workspaceFolder": "/workspace/sentry",
3+
"build": {
4+
"dockerfile": "Dockerfile",
5+
"context": "..",
6+
"args": {
7+
"BASE_IMAGE": "${localEnv:BASE_IMAGE:ubuntu:24.04}"
8+
}
9+
},
10+
"runArgs": ["--init"],
11+
"forwardPorts": [4000, 4001, 6379],
12+
"containerEnv": {
13+
"REDIS_URL": "redis://localhost:6379"
14+
},
615
"features": {
716
"ghcr.io/devcontainers/features/git:latest": {
817
"ppa": false,
918
"version": "2.54.0"
1019
},
1120
"ghcr.io/devcontainers/features/github-cli:latest": {},
1221
"ghcr.io/nils-geistmann/devcontainers-features/zsh:latest": {},
13-
"ghcr.io/devcontainers/features/node:latest": {},
14-
"ghcr.io/devcontainers-extra/features/npm-packages:latest": {},
22+
"./features/tools": {
23+
"rubyVersion": "${localEnv:RUBY_VERSION:4.0}"
24+
},
1525
"ghcr.io/rocker-org/devcontainer-features/apt-packages:latest": {
1626
"packages": "inotify-tools,tzdata"
1727
}

.devcontainer/docker-compose.yml

Lines changed: 0 additions & 51 deletions
This file was deleted.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"name": "sentry-ruby toolchain",
3+
"id": "tools",
4+
"version": "1.0.0",
5+
"description": "Installs mise and pre-installs the sentry-ruby toolchain (Java, Ruby, Node) via mise plus headless Chromium via Playwright, baked into the image so the container starts without downloading anything.",
6+
"options": {
7+
"rubyVersion": {
8+
"type": "string",
9+
"default": "4.0",
10+
"description": "Ruby version to pre-install and set as the global default (latest 4.0.x by default). Switching versions requires an image rebuild."
11+
}
12+
}
13+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Installs mise system-wide and pre-installs the sentry-ruby toolchain (Java,
4+
# Ruby, Node) plus a headless Chromium, all baked into the image so the
5+
# container starts without downloading anything at runtime.
6+
#
7+
set -euo pipefail
8+
9+
RUBY_VERSION="${RUBYVERSION:-latest}"
10+
USERNAME="${_REMOTE_USER:-sentry}"
11+
USER_HOME="${_REMOTE_USER_HOME:-/home/${USERNAME}}"
12+
13+
# Install mise system-wide via the official installer. This downloads a prebuilt
14+
# binary from mise's CDN rather than the GitHub API, avoiding the API rate
15+
# limits the gh-release-based community feature hits on shared CI runners.
16+
echo "📦 Installing mise..."
17+
export MISE_INSTALL_PATH=/usr/local/bin/mise
18+
curl https://mise.run | sh
19+
MISE_BIN=/usr/local/bin/mise
20+
"$MISE_BIN" --version
21+
22+
# Activate mise for the remote user's interactive shells.
23+
echo "eval \"\$(${MISE_BIN} activate bash)\"" >> "${USER_HOME}/.bashrc"
24+
echo "eval \"\$(${MISE_BIN} activate zsh)\"" >> "${USER_HOME}/.zshenv"
25+
chown "${USERNAME}:${USERNAME}" "${USER_HOME}/.bashrc" "${USER_HOME}/.zshenv"
26+
27+
# Run a command as the remote user with a sane PATH so mise writes tools into
28+
# the user's own data dir (~/.local/share/mise) rather than root's.
29+
as_user() {
30+
sudo -u "${USERNAME}" -H env "PATH=${USER_HOME}/.local/bin:/usr/local/bin:/usr/bin:/bin" "$@"
31+
}
32+
33+
# ~/.local/bin is on PATH but nothing creates it now that mise is installed
34+
# system-wide; ensure it exists for the Chromium symlink below.
35+
as_user mkdir -p "${USER_HOME}/.local/bin"
36+
37+
# Java is always installed (required for JRuby) and listed in .mise.toml so it
38+
# is available regardless of which Ruby flavour is used.
39+
echo "📦 Pre-installing java@temurin-21..."
40+
as_user "$MISE_BIN" install "java@temurin-21"
41+
as_user "$MISE_BIN" use --global "java@temurin-21"
42+
43+
# Pre-install Ruby (precompiled) so the container starts immediately.
44+
echo "📦 Pre-installing ruby@${RUBY_VERSION} (precompiled)..."
45+
as_user env MISE_RUBY_COMPILE=0 "$MISE_BIN" install "ruby@${RUBY_VERSION}"
46+
as_user "$MISE_BIN" use --global "ruby@${RUBY_VERSION}"
47+
48+
# Node.js is always needed for the svelte-mini e2e app.
49+
echo "📦 Pre-installing node@lts..."
50+
as_user "$MISE_BIN" install "node@lts"
51+
as_user "$MISE_BIN" use --global "node@lts"
52+
53+
# Install headless Chromium via Playwright (includes all system dependencies)
54+
# and symlink the binary into ~/.local/bin which is already on PATH.
55+
echo "📦 Installing headless Chromium via Playwright..."
56+
as_user "${USER_HOME}/.local/share/mise/shims/npx" playwright install chromium --with-deps
57+
# Playwright lays out the binary under chrome-linux/ on arm64 and chrome-linux64/
58+
# on x86_64 (since Playwright 1.57), so the glob has to match both.
59+
as_user bash -c "ln -sf ${USER_HOME}/.cache/ms-playwright/chromium-*/chrome-linux*/chrome ${USER_HOME}/.local/bin/chromium"
60+
61+
echo "✅ Toolchain pre-install completed!"

.devcontainer/run

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,31 +2,34 @@
22
#
33
# Container entrypoint. Ruby and other toolchains are pre-installed in the
44
# image; this script only handles per-run setup (ownership, mise activation)
5-
# and hands off to whatever docker-compose passes as `command`.
5+
# and hands off to whatever command is passed at runtime.
66
#
77
set -euo pipefail
88

9-
cd /workspace/sentry
9+
cd /workspaces/sentry-ruby
1010

1111
# In CI the workspace is checked out by the runner user (e.g. UID 1001) and
1212
# then bind-mounted into the container where we run as sentry (UID 1000).
1313
# Fix ownership once here so bundler, git, etc. can write freely.
14-
sudo chown -R sentry:sentry /workspace/sentry 2>/dev/null || true
15-
MISE_BIN="/home/sentry/.local/bin/mise"
14+
sudo chown -R sentry:sentry /workspaces/sentry-ruby 2>/dev/null || true
15+
16+
# mise is installed system-wide by the tools dev container feature, so it lives
17+
# on PATH (typically /usr/local/bin/mise).
18+
MISE_BIN="$(command -v mise || true)"
1619

1720
# Git also refuses to operate in directories owned by a different user.
18-
git config --global --add safe.directory /workspace/sentry 2>/dev/null || true
21+
git config --global --add safe.directory /workspaces/sentry-ruby 2>/dev/null || true
1922

20-
if [[ ! -x "$MISE_BIN" ]]; then
21-
echo "❌ mise not found at $MISE_BIN (it should be installed by the Dockerfile)"
23+
if [[ -z "$MISE_BIN" || ! -x "$MISE_BIN" ]]; then
24+
echo "❌ mise not found on PATH (it should be installed by the tools dev container feature)"
2225
exit 1
2326
fi
2427

2528
# Activate mise for this shell so PATH/shims are resolved correctly.
2629
eval "$("$MISE_BIN" activate bash)"
2730

2831
# Trust the workspace config so mise will use it without prompting.
29-
"$MISE_BIN" trust /workspace/sentry >/dev/null
32+
"$MISE_BIN" trust /workspaces/sentry-ruby >/dev/null
3033

3134
if [[ $# -eq 0 ]]; then
3235
exec sleep infinity

.devcontainer/setup

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class SetupScript
2525
only_npm: false,
2626
with_foreman: false
2727
}
28-
@workspace_root = '/workspace/sentry'
28+
@workspace_root = '/workspaces/sentry-ruby'
2929
end
3030

3131
def run(args)

0 commit comments

Comments
 (0)