· 5 min read
Setting Up a Dev Blog With Astro and Devcontainers
I wanted a simple place to document weekend projects. Here's how I built it with Astro, AstroWind, devcontainers and what I learned along the way.
How I Set Up This Blog
Every blog needs a first post. Mine is about building the blog itself. I am not a web developer by trade and I don’t work with Node.js day to day, so the process turned out to be more interesting than I expected. I want to document it while it’s fresh.
This is a practical walkthrough of how to go from zero to a personal blog using Astro. I’ll explain the decisions I made along the way so you can follow the same path.
Why Astro
I wanted a fast, modern static site that I could own completely. Playing with it would also allow me to learn a bit of front end development in my spare time. Blogging is not my first goal here, otherwise I would have used WordPress or Medium and called it a day.
Astro was the obvious choice: it generates pure static HTML, is blazing fast and has a great developer experience. It also has a large collection of free themes.
The theme I chose is AstroWind which is free, actively maintained and built with Astro and Tailwind CSS. It is more complex than simpler alternatives like AstroPaper, but it is very extensible. If I ever decide to build websites for side projects in the future, I will already know the codebase.
Setting Up the Development Environment
I do not like cluttering my computer with libraries and config files that are only used for a single project. Rather than installing Node.js directly on my machine, I set up a devcontainer which is a full development environment that runs inside Docker.
A devcontainer is a configuration file that tells VS Code to run your project inside a Docker container with everything pre-installed. You get the same environment every time, on any machine.
You will need the following:
- VS Code
- Docker
- The Dev Containers extension for VS Code
Once those are in place, fork the AstroWind repo on GitHub, clone it locally, and let VS Code generate the base devcontainer config:
Ctrl+Shift+P → Dev Containers: Add Dev Container Configuration Files → Node.js LTS
This gives you a .devcontainer/devcontainer.json. Add a Dockerfile alongside it for full reproducibility, and configure a few extras such as the Astro VS Code extension, Tailwind CSS IntelliSense, format on save, and automatic port forwarding for Astro’s dev server on port 4321.
Linux only: Instead of changing
astro.config.tsto bind to0.0.0.0, add"runArgs": ["--network=host"]to yourdevcontainer.json. This lets Astro’s dev server bind to localhost normally while still being reachable from your browser. This only works on Linux hosts.
Dealing With Vulnerabilities
After running npm install I was greeted with 23 vulnerabilities. I am new to this Node.js and npm game so I thought someone would hack me about 2 minutes after publishing the site. I am paranoid, I know.
The first thing to do is update all packages without introducing breaking changes:
# Fix everything that doesn't require breaking changes
npm audit fix
# Check what's left
npm auditAfter the first command I was down to 2 remaining, one of which was svgo. Afraid to get hacked by everyone on the web, I spent some time trying to update the library before it finally clicked.
This is a static site. There is no upload functionality, no database and no user input in production. The svgo vulnerability is a Billion Laughs attack. It works by feeding a malicious SVG file into the build process to crash it. Since I control every file that goes into my build, it seems the only person I should be afraid of is myself. Most of these vulnerabilities live in build tools that never touch your live site.
Lesson learned: read the advisory before panicking. With dependencies sorted, let’s move on.
Customising AstroWind
AstroWind ships as a full demo site with SaaS landing pages, pricing pages, fake testimonials, lorem ipsum everywhere. The cleanup is straightforward once you know which files to touch.
The files worth knowing about:
src/config.yaml— site name, description, SEO defaults, blog settingssrc/navigation.ts— header and footer links (not native Astro, just AstroWind’s own convention)src/pages/index.astro— the homepage, built from composable widget componentssrc/data/post/— where your blog posts live as Markdown filessrc/pages/— file-based routing, one file = one URL
Delete everything you do not need such as demo home pages, landing pages, pricing, services and strip the navigation down to just the pages you actually have. The homepage can be reduced to three components:
<Hero />
<!-- tagline and CTA -->
<Note />
<!-- current project callout -->
<BlogLatestPosts />
<!-- auto-pulls your latest posts -->With everything stripped down, it is time to write this very blog post. That’s Meta.
Content Structure
Blog posts are Markdown files in src/data/post/. The only required frontmatter field is title — everything else is optional but worth using from the start:
---
publishDate: 2026-03-08T00:00:00Z
title: Your post title
excerpt: A short summary shown on the blog listing page
tags:
- astro
- devcontainers
draft: false
---
## Super engaging content
written in markdown 🤯One thing to note: AstroWind hides draft posts completely, including in local development. I keep draft: false and use git branches for work in progress instead, only deploying main to production.
What’s Next
The site is now live at scriptapex.com. The next post covers deploying it to Netlify for free with a custom domain (coming soon).