本设置包含 Backstage 应用、PostgreSQL 数据库和配置了自签名 SSL 证书的 Nginx 反向代理。使用 Yarn 4 作为包管理器,并且不依赖自定义的 Dockerfile。
在启动 Dev Container 之前,请在你的项目根目录下执行以下命令来创建 Nginx 所需的 SSL 证书。
# Create the directory structure if it doesn't exist
mkdir -p .devcontainer/nginx/certs导航到该目录并使用 openssl 生成证书和私钥。
# Navigate into the certificates directory
cd .devcontainer/nginx/certs
# Generate the private key and self-signed certificate (valid for 365 days)
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout nginx.key -out nginx.crt \
-subj "/C=US/ST=Development/L=DevCity/O=DevOrg/OU=DevDept/CN=localhost"
# Navigate back to the project root directory (optional)
cd ../../..这将在 .devcontainer/nginx/certs/ 目录下创建 nginx.key (私钥) 和 nginx.crt (证书) 文件。
请将以下文件的内容放置在项目对应的路径下。
# .devcontainer/docker-compose.yml
# Defines the services: Backstage app, PostgreSQL database, and Nginx proxy.
version: '3.8'
services:
# Service for the Backstage application
app:
# Use a pre-built Node.js image suitable for Typescript development.
# Node.js v18+ is recommended for Yarn 4 (Corepack).
image: mcr.microsoft.com/devcontainers/typescript-node:20 # Or :18, :22 etc.
container_name: backstage-app-devcontainer
# Keep the container running idly
command: sleep infinity
# Mount the entire project directory into the container's /workspace
volumes:
- ..:/workspace:cached
# Expose Backstage default port and Node debug port
ports:
- "7007:7007" # Backstage frontend/backend default port
- "9229:9229" # Node.js debug port
# Environment variables needed by Backstage to connect to the database
# Ensure these align with your Backstage app-config*.yaml files
environment:
- POSTGRES_HOST=db
- POSTGRES_PORT=5432
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres # Use a more secure password if needed
# Set Backstage base URLs if accessed via Nginx proxy, e.g., https://localhost:8443
# Adjust according to your Backstage configuration needs:
# - APP_BASE_URL=https://localhost:8443
# - BACKEND_BASE_URL=https://localhost:8443/api
# Ensure the database service is started before the app service
depends_on:
- db
# Run commands as the non-root 'node' user provided by the base image
user: node
# Set the default working directory inside the container
working_dir: /workspace
# Service for the PostgreSQL database
db:
image: postgres:15 # Or your preferred PostgreSQL version
container_name: postgres-devcontainer
restart: unless-stopped
# Mount a Docker volume to persist database data across sessions
volumes:
- postgres-data:/var/lib/postgresql/data
# Environment variables to initialize PostgreSQL
environment:
- POSTGRES_DB=backstage_plugin_${USER:-dev} # Example DB name
- POSTGRES_USER=postgres
- POSTGRES_PASSWORD=postgres # Should match the 'app' service password
# Expose port 5432 only within the Docker network by default
# Uncomment 'ports' mapping if direct access from the host machine is required
# ports:
# - "5432:5432"
# Service for the Nginx reverse proxy
nginx:
image: nginx:latest
container_name: nginx-devcontainer
restart: unless-stopped
# Map host ports to Nginx container ports
ports:
- "8443:443" # Host HTTPS port 8443 -> Container port 443
- "8080:80" # Host HTTP port 8080 -> Container port 80 (for redirect)
# Mount Nginx configuration and SSL certificates
volumes:
# Custom Nginx configuration file (read-only)
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf:ro
# SSL certificate and key directory (read-only)
- ./nginx/certs:/etc/nginx/certs:ro
# Ensure Nginx starts after the application service it proxies to
depends_on:
- app
# Define the named volume for PostgreSQL data persistence
volumes:
postgres-data:// .devcontainer/devcontainer.json
// VS Code Dev Container configuration using Yarn 4
{
// Name for the Dev Container environment displayed in VS Code
"name": "Backstage Dev (Yarn 4)",
// Use Docker Compose to define and manage the services
"dockerComposeFile": "docker-compose.yml",
// Specify the primary service VS Code should connect to (the 'app' service)
"service": "app",
// Define the workspace folder inside the container where the project is mounted
"workspaceFolder": "/workspace",
// --- Features for enhancing the container environment ---
"features": {
// Install common utilities like git, curl, etc.
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": "false", // Do not install zsh unless needed
"username": "node", // Configure features for the 'node' user
"upgradePackages": "true" // Upgrade packages during feature installation
},
// Configure Node.js environment, install version 20, and enable Corepack for Yarn 4
"ghcr.io/devcontainers/features/node:1": {
"version": "20", // Specify desired Node.js version (>= 18 recommended for corepack)
"nodeGypDependencies": true, // Install common node-gyp dependencies
"corepack": "enable" // Automatically enable corepack
},
// Include Docker client for interacting with Docker daemon from within the container (optional)
"ghcr.io/devcontainers/features/docker-in-docker:2": {
"version": "latest",
"moby": true // Use Moby (open source Docker) engine
}
},
// --- Port Forwarding: Map container ports to the host machine ---
"forwardPorts": [
7007, // Backstage default application port
8443, // Nginx HTTPS port mapped to host
8080, // Nginx HTTP port mapped to host (for redirect)
5432 // Forward PostgreSQL port only if direct access needed from host
],
// --- VS Code Settings: Applied inside the container ---
"settings": {
"terminal.integrated.defaultProfile.linux": "bash", // Set default terminal shell
// Ensure VS Code uses the workspace's version of TypeScript managed by Yarn
"typescript.tsdk": "/workspace/node_modules/typescript/lib",
"typescript.enablePromptUseWorkspaceTsdk": true,
// Improves searching in projects with large node_modules (optional)
"search.exclude": {
"**/node_modules": false
},
// Example: Configure ESLint working directories if needed (adjust based on project)
// "eslint.workingDirectories": [{ "mode": "auto" }],
// General editor settings
"editor.formatOnSave": true, // Automatically format code on save
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" // Use Prettier for TypeScript
},
"[typescriptreact]": {
"editor.defaultFormatter": "esbenp.prettier-vscode" // Use Prettier for TSX
}
},
// --- VS Code Extensions: To install inside the container ---
"extensions": [
"dbaeumer.vscode-eslint", // ESLint integration
"esbenp.prettier-vscode", // Prettier code formatter
"ms-azuretools.vscode-docker", // Docker management extension
"github.vscode-pull-request-github", // GitHub Pull Requests and Issues integration
"cweijan.vscode-postgresql-client2", // PostgreSQL client (optional, for DB inspection)
"arcanis.vscode-zipfs" // Recommended for Yarn PnP support (improves 'Go to Definition')
],
// --- Lifecycle Commands ---
// Command executed once after the container is created. Installs dependencies using Yarn 4 via Corepack.
"postCreateCommand": "corepack enable && yarn install",
// Optional: Command executed every time VS Code attaches to the container.
// Useful for automatically starting the development server.
// "postAttachCommand": "yarn dev",
// Optional but recommended for Yarn PnP: Command to configure VS Code SDKs.
// Run this manually in the integrated terminal once VS Code is attached:
// > yarn dlx @yarnpkg/sdks vscode
// Specify the user VS Code and terminal processes should run as inside the container
"remoteUser": "node"
}# .devcontainer/nginx/default.conf
# Nginx configuration: HTTP redirect and HTTPS proxy to Backstage frontend
# Server block to listen on HTTP port 80 and redirect to HTTPS
server {
listen 80;
server_name localhost; # Or your specific development domain if any
# Log redirects (optional)
# access_log /var/log/nginx/access.log main;
# error_log /var/log/nginx/error.log warn;
location / {
# Permanent redirect (301) to the HTTPS version on the mapped host port (8443)
return 301 https://$host:8443$request_uri;
}
}
# Main server block listening on port 443 for HTTPS traffic
server {
listen 443 ssl http2; # Enable SSL and HTTP/2
server_name localhost; # Should ideally match the CN in your certificate
# SSL Certificate files (paths match volume mounts in docker-compose.yml)
ssl_certificate /etc/nginx/certs/nginx.crt;
ssl_certificate_key /etc/nginx/certs/nginx.key;
# Modern SSL/TLS settings (recommended for security)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# Example cipher suite (adjust based on security requirements)
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Optional: Add security headers
# add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
# add_header X-Frame-Options DENY always;
# add_header X-Content-Type-Options nosniff always;
# add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Log configuration (optional)
# access_log /var/log/nginx/access.log main;
# error_log /var/log/nginx/error.log warn;
# Root location: Proxy all requests to the Backstage application service
location / {
# The target service name 'app' and port '7007' from docker-compose.yml
proxy_pass http://app:7007;
# Set headers to pass information to the backend (Backstage)
proxy_set_header Host $host; # Pass the original host requested by the client
proxy_set_header X-Real-IP $remote_addr; # Pass the real client IP address
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Append client IP list
proxy_set_header X-Forwarded-Proto $scheme; # Pass the original request scheme (http or https)
proxy_set_header X-Forwarded-Host $host; # Pass original host (sometimes needed)
proxy_set_header X-Forwarded-Port $server_port;# Pass original port (sometimes needed)
# WebSocket support (important if Backstage uses WebSockets)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; # Allow upgrading the connection to WebSocket
proxy_set_header Connection "upgrade"; # Set connection header for WebSocket
# Optional: Adjust timeouts for long-running requests if necessary
# proxy_connect_timeout 75s;
# proxy_read_timeout 300s;
# proxy_send_timeout 300s;
}
# Add other specific Nginx location blocks or directives if needed for your setup
# Example: Serving static files directly from Nginx
# location /static/ {
# alias /path/to/static/files/in/nginx/container;
# expires 1d;
# }
}- 安装 Docker Desktop (或适用于 Linux 的 Docker Engine + Docker Compose)。
- 安装 Visual Studio Code。
- 安装 VS Code 的 "Dev Containers" 扩展 (ID: ms-vscode-remote.remote-containers)。
- 将
docker-compose.yml和devcontainer.json放入项目根目录下的.devcontainer文件夹。 - 将
nginx/default.conf放入.devcontainer/nginx/default.conf。 - 确保按照步骤 1 生成的
nginx.key和nginx.crt位于.devcontainer/nginx/certs/。
- 打开你项目根目录下的
package.json文件。 - 确保存在
"packageManager"字段,并指向你希望使用的 Yarn 4 版本。例如:
// package.json snippet
{
"name": "my-backstage-project",
// ... other fields
"packageManager": "yarn@4.1.1" // Or another Yarn 4+ version
}- 如果项目中没有
package.json或者没有此字段,corepack enable可能无法正确启用 Yarn 4。你可能需要在容器启动后手动运行yarn set version stable或类似命令。
- 在 VS Code 中,使用
File > Open Folder...打开你的项目根目录。 - VS Code 右下角应出现提示:"Folder contains a Dev Container configuration file. Reopen folder to develop in a container." (或类似中文提示)。
- 点击 "Reopen in Container" 按钮。
- VS Code 的 Dev Containers 扩展将根据
.devcontainer/devcontainer.json和.devcontainer/docker-compose.yml配置来构建(如果需要)并启动所有服务 (app, db, nginx)。 postCreateCommand(corepack enable && yarn install) 会自动执行,安装项目依赖。首次启动可能需要一些时间下载镜像和安装依赖。
- Backstage UI (通过 Nginx HTTPS): 打开浏览器访问
https://localhost:8443。你需要接受浏览器关于自签名证书的安全警告。 - HTTP 到 HTTPS 重定向: 访问
http://localhost:8080应该会自动跳转到https://localhost:8443。 - 直接访问 Backstage (不通过 Nginx):
http://localhost:7007。 - 数据库: 数据库运行在
db服务中,app服务可以通过db:5432访问。如果需要从宿主机直接访问,请取消docker-compose.yml中db服务的端口映射注释。
- 如果你的 Backstage 项目配置为使用 Yarn Plug'n'Play (PnP),为了让 VS Code 的 IntelliSense (特别是 TypeScript 的 "Go to Definition" 等功能) 正常工作,建议在容器启动并附加 VS Code 后,在 VS Code 的集成终端中运行一次以下命令:
yarn dlx @yarnpkg/sdks vscode- 这将生成或更新 VS Code 所需的 PnP 配置。