惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

腾讯CDC
The Cloudflare Blog
IT之家
IT之家
V
V2EX
雷峰网
雷峰网
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
Stack Overflow Blog
Stack Overflow Blog
博客园 - Franky
Engineering at Meta
Engineering at Meta
S
SegmentFault 最新的问题
GbyAI
GbyAI
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - 司徒正美
云风的 BLOG
云风的 BLOG
小众软件
小众软件
博客园 - 叶小钗
Blog — PlanetScale
Blog — PlanetScale
C
Check Point Blog
A
About on SuperTechFans
B
Blog
月光博客
月光博客
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Running Astro in a preview container
Steve Fenton · 2026-04-27 · via DEV Community

If you’ve ever worked on a collection of different Node apps, you’ve likely encountered version conflicts. Everyone wants a different version of Node or PNPM, and your new job is trying to align them all, or managing versions daily.

That’s when open-source hero Kostis Kapelonis said, “Why don’t we run the preview in a container?” In fact, he didn’t just say this; he also submitted a PR. I told you he’s an open-source hero.

The PR added a Dockerfile and a docker-compose.yaml file to the project, which let you spin up the preview site using:

docker compose up

Enter fullscreen mode Exit fullscreen mode

Once Kostis had done all the hard work, I added a small enhancement to make Astro’s live preview work when you change files. That meant you could start the container and keep working while all your changes are instantly visible in the preview. That keeps the developer inner loop nice and tight.

If you want to do the same, here’s how to make it happen. Once again, I added a very small cherry to Kostis’ wonderfully fluffy cake, so send your adoration his way.

Add a Docker compose file

Here’s the docker-compose.yml file for your Astro project. It goes in the root directory.

services:
  astro:
    build: .
    ports:
 - "3000:3000"
    volumes:
 - .:/app
 - /app/node_modules
    environment:
 - NODE_ENV=development
 - HOST=0.0.0.0
    stdin_open: true
    tty: true

Enter fullscreen mode Exit fullscreen mode

This maps the volumes, with a special case for node_modules. It exposes Astro’s port 3000 inside the container to port 3000 on your machine so you can open it in your browser.

The Docker file

Here’s the Dockerfile, which also goes in your project’s root directory.

# Use Node 20 as the base image
FROM node:20-slim

# Install pnpm globally
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable

# Set the working directory
WORKDIR /app

# Copy package files
COPY package.json pnpm-lock.yaml* ./

# Install dependencies
RUN pnpm install

# Copy the rest of the source code
COPY . .

# Expose the default Astro port
EXPOSE 3000

# Start the dev server
CMD ["pnpm", "compose:dev"]

Enter fullscreen mode Exit fullscreen mode

There’s an optimization here around the package files, which is why they get their own copy command. There’s an extra command in the package.json file that we call here, too. It’s a variation of the dev script we use, but switches out the Astro run with a slight variation (the addition of the --host flag) lets just show the important bits in this code snippet:

"scripts": {     
    "compose:dev": "npm-run-all --parallel dev:img dev:dictionary compose:dev:astro dev:watch",
    "compose:dev:astro": "astro dev --host",

Enter fullscreen mode Exit fullscreen mode

The Vite config change

The final change is the one that makes the live refresh to work. This goes in your astro.config.mjs file, and I popped it right after the existing server config.

server: {
    port: 3000
}
vite: {
    server: {
        watch: {
            usePolling: true,
        },
    },
},

Enter fullscreen mode Exit fullscreen mode

Spinning it up

The first time I ran this, I started things up with:

docker compose up --build

Enter fullscreen mode Exit fullscreen mode

You can then stop the container with

docker compose down

Enter fullscreen mode Exit fullscreen mode

If you haven’t changed the container, you can start it with the faster:

docker compose up

Enter fullscreen mode Exit fullscreen mode