DEV: Overhaul devcontainer configuration (#28446)

- Uses a more appropriate image, with immutable tag (so update prompts work correctly)
- Updates port forwarding
- Improves mount setup (inc. persistant PG/Redis when rebuilding)
- Fixes ember-cli live reload
- Automatically configures VSCode & extensions
This commit is contained in:
David Taylor 2024-11-14 12:11:38 +00:00 committed by GitHub
parent 8dc772f2a8
commit fd5ef6896d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 108 additions and 18 deletions

View File

@ -1,16 +1,37 @@
{
"name": "Discourse",
"image": "discourse/discourse_dev:release",
"workspaceMount": "source=${localWorkspaceFolder}/../..,target=/var/www/discourse,type=bind",
"workspaceFolder": "/var/www/discourse",
"settings": {
"search.followSymlinks": false
},
"postStartCommand": "sudo /sbin/boot",
"extensions": ["rebornix.Ruby"],
"forwardPorts": [9292],
"image": "docker.io/discourse/discourse_dev:20241111-0710",
"workspaceMount": "source=${localWorkspaceFolder},target=/workspace/discourse,type=bind",
"workspaceFolder": "/workspace/discourse",
"postStartCommand": "./.devcontainer/scripts/start.rb",
"forwardPorts": [
9292, // bin/unicorn
3000, // bin/rails s
4200, // ember-cli
8025, // mailhog
9229 // chrome remote debug
],
"remoteUser": "discourse",
"remoteEnv": {
"DISCOURSE_DEV_HOSTS": ".githubpreview.dev"
"RAILS_DEVELOPMENT_HOSTS": ".app.github.dev",
"PGUSER": "discourse",
"SELENIUM_FORWARD_DEVTOOLS_TO_PORT": "9229",
},
"mounts": [
"source=${localWorkspaceFolderBasename}-node_modules,target=${containerWorkspaceFolder}/node_modules,type=volume",
"source=${localWorkspaceFolderBasename}-pg,target=/shared/postgres_data,type=volume",
"source=${localWorkspaceFolderBasename}-redis,target=/shared/redis,type=volume"
],
"customizations": {
"vscode": {
"extensions": [
"Shopify.ruby-lsp",
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"ruby-syntax-tree.vscode-syntax-tree",
"lifeart.vscode-glimmer-syntax",
"typed-ember.glint-vscode"
]
}
}
}

27
.devcontainer/scripts/start.rb Executable file
View File

@ -0,0 +1,27 @@
#!/usr/bin/env ruby
# frozen_string_literal: true
puts "👋 Welcome to the Discourse devcontainer! Let's get everything ready..."
puts "Setting permissions on volume mounts..."
system "sudo chown discourse .", exception: true
system "sudo chown discourse node_modules", exception: true
system "sudo chown -R postgres /shared/postgres_data", exception: true
puts "Starting services..."
fork do
Process.daemon
exec "sudo nohup /sbin/boot"
end
system "cp -n .vscode/settings.json.sample .vscode/settings.json", exception: true
system "cp -n .vscode/tasks.json.sample .vscode/tasks.json", exception: true
puts <<~TXT
🎉 All done!
Next steps:
1. Cmd/Ctrl + Shift + B to run the shortcuts/boot-dev task
2. Wait for the server to start
3. Open your browser to http://localhost:4200
TXT

View File

@ -5,6 +5,7 @@
"esbenp.prettier-vscode",
"dbaeumer.vscode-eslint",
"ruby-syntax-tree.vscode-syntax-tree",
"lifeart.vscode-glimmer-syntax"
"lifeart.vscode-glimmer-syntax",
"typed-ember.glint-vscode"
]
}

View File

@ -4,9 +4,9 @@
"version": "2.0.0",
"tasks": [
{
"label": "deps/yarn",
"label": "deps/pnpm",
"type": "shell",
"command": "yarn install",
"command": "pnpm install",
"presentation": {
"reveal": "always",
"group": "deps",
@ -28,7 +28,7 @@
{
"label": "deps/all",
"dependsOn": [
"deps/yarn",
"deps/pnpm",
"deps/bundle"
],
"problemMatcher": []

View File

@ -95,10 +95,11 @@ function updateScriptReferences({
);
}
// We use _lr/livereload.js directly instead of ember-cli-live-reload so that the protocol/port is configured automatically
// ember-cli-live-reload doesn't select ports correctly, so we use _lr/livereload directly
// (important for cloud development environments like GitHub CodeSpaces)
newElements.unshift(
`<script async src="/_lr/livereload.js?path=_lr/livereload" nonce="${nonce}"></script>`
`<script nonce="${nonce}">window.LiveReloadOptions = { "path": "_lr/livereload", "host": location.host, "port": location.port || (location.protocol === "https:" ? 443 : 80) }</script>`,
`<script async src="/_lr/livereload.js" nonce="${nonce}"></script>`
);
}

View File

@ -67,6 +67,17 @@ pnpm_env["FORWARD_HOST"] = "true" if ARGV.include?("--forward-host")
if ARGV.include?("-u") || ARGV.include?("--unicorn")
unicorn_env = { "DISCOURSE_PORT" => ENV["DISCOURSE_PORT"] || "4200" }
if command == "server" && ENV["CODESPACE_NAME"]
unicorn_env.merge!(
{
"DISCOURSE_PORT" => "443",
"DISCOURSE_FORCE_HTTPS" => "1",
"DISCOURSE_FORCE_HOSTNAME" => "#{ENV["CODESPACE_NAME"]}-4200.#{ENV["GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN"]}"
}
)
end
unicorn_pid = spawn(unicorn_env, __dir__ + "/unicorn")
ember_cli_pid = nil

View File

@ -8,6 +8,20 @@ module SystemHelpers
msg = "Test paused. Press enter to resume, or `d` + enter to start debugger.\n\n"
msg += "Browser inspection URLs:\n"
base_url = page.driver.browser.send(:devtools_address)
uri = URI(base_url)
response = Net::HTTP.get(uri.hostname, "/json/list", uri.port)
socat_pid = nil
if exposed_port = ENV["SELENIUM_FORWARD_DEVTOOLS_TO_PORT"]
socat_pid =
fork do
chrome_port = uri.port
exec "socat tcp-listen:#{exposed_port},reuseaddr,fork tcp:localhost:#{chrome_port}"
end
end
# Fetch devtools urls
base_url = page.driver.browser.send(:devtools_address)
uri = URI(base_url)
@ -15,13 +29,28 @@ module SystemHelpers
JSON
.parse(response)
.each do |result|
msg +=
" - (#{result["type"]}) #{base_url}#{result["devtoolsFrontendUrl"]} (#{URI(result["url"]).path})\n"
devtools_url = "#{base_url}#{result["devtoolsFrontendUrl"]}"
devtools_url = devtools_url.gsub(":#{uri.port}", ":#{exposed_port}") if exposed_port
if ENV["CODESPACE_NAME"]
devtools_url =
devtools_url
.gsub(
"localhost:#{exposed_port}",
"#{ENV["CODESPACE_NAME"]}-#{exposed_port}.#{ENV["GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN"]}",
)
.gsub("http://", "https://")
.gsub("ws=", "wss=")
end
msg += " - (#{result["type"]}) #{devtools_url} (#{URI(result["url"]).path})\n"
end
result = ask("\n\e[33m#{msg}\e[0m")
binding.pry if result == "d" # rubocop:disable Lint/Debugger
puts "\e[33mResuming...\e[0m"
Process.kill("TERM", socat_pid) if socat_pid
self
end