How do you deploy Astro applications to different platforms (Vercel, Netlify, Node.js)? What are the deployment best practices?
Astro's deployment methods depend on the rendering mode you choose (SSG, SSR, or hybrid). Understanding different deployment options and best practices is crucial for successfully publishing Astro projects.
Static Deployment (SSG):
For pure static sites, you can deploy the build output to any static hosting service.
-
Vercel Deployment:
bash# Install Vercel CLI npm i -g vercel # Deploy verceljavascript// vercel.json { "buildCommand": "astro build", "outputDirectory": "dist" } -
Netlify Deployment:
bash# Install Netlify CLI npm i -g netlify-cli # Deploy netlify deploy --prodtoml# netlify.toml [build] command = "astro build" publish = "dist" [[redirects]] from = "/*" to = "/index.html" status = 200 -
GitHub Pages Deployment:
javascript// astro.config.mjs import { defineConfig } from 'astro/config'; export default defineConfig({ site: 'https://username.github.io', base: '/repository-name', });bash# Build and deploy npm run build # Push dist directory contents to gh-pages branch
Server-Side Deployment (SSR):
For applications requiring server-side rendering, you need to use adapters.
-
Vercel SSR Deployment:
bashnpx astro add verceljavascript// astro.config.mjs import { defineConfig } from 'astro/config'; import vercel from '@astrojs/vercel/server'; export default defineConfig({ output: 'server', adapter: vercel(), }); -
Netlify Edge Functions:
bashnpx astro add netlifyjavascript// astro.config.mjs import { defineConfig } from 'astro/config'; import netlify from '@astrojs/netlify/edge'; export default defineConfig({ output: 'server', adapter: netlify(), }); -
Node.js Server:
bashnpx astro add nodejavascript// astro.config.mjs import { defineConfig } from 'astro/config'; import node from '@astrojs/node'; export default defineConfig({ output: 'server', adapter: node({ mode: 'standalone', }), });bash# Build and run npm run build node ./dist/server/entry.mjs -
Cloudflare Pages:
bashnpx astro add cloudflarejavascript// astro.config.mjs import { defineConfig } from 'astro/config'; import cloudflare from '@astrojs/cloudflare'; export default defineConfig({ output: 'server', adapter: cloudflare(), });
Docker Deployment:
dockerfile# Dockerfile FROM node:18-alpine AS builder WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . RUN npm run build FROM node:18-alpine AS runner WORKDIR /app COPY /app/package*.json ./ RUN npm ci --production COPY /app/dist ./dist EXPOSE 4321 CMD ["node", "./dist/server/entry.mjs"]
bash# Build and run Docker image docker build -t astro-app . docker run -p 4321:4321 astro-app
Environment Variables Configuration:
bash# .env.example PUBLIC_API_URL=https://api.example.com DATABASE_URL=postgresql://... SECRET_KEY=your-secret-key
javascript// astro.config.mjs import { defineConfig } from 'astro/config'; export default defineConfig({ vite: { define: { 'import.meta.env.PUBLIC_API_URL': JSON.stringify(process.env.PUBLIC_API_URL), }, }, });
CI/CD Configuration:
yaml# .github/workflows/deploy.yml name: Deploy on: push: branches: [main] jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Setup Node.js uses: actions/setup-node@v3 with: node-version: '18' cache: 'npm' - name: Install dependencies run: npm ci - name: Build run: npm run build - name: Deploy to Vercel uses: amondnet/vercel-action@v20 with: vercel-token: ${{ secrets.VERCEL_TOKEN }} vercel-org-id: ${{ secrets.ORG_ID }} vercel-project-id: ${{ secrets.PROJECT_ID }} vercel-args: '--prod'
Performance Optimization Deployment:
-
Enable Compression:
javascript// astro.config.mjs export default defineConfig({ compressHTML: true, }); -
Configure CDN:
javascript// astro.config.mjs export default defineConfig({ build: { assets: '_astro', }, }); -
Cache Strategy:
javascript// src/middleware.ts export const onRequest = async (context, next) => { const response = await next(); if (context.url.pathname.startsWith('/_astro/')) { response.headers.set('Cache-Control', 'public, max-age=31536000, immutable'); } return response; };
Monitoring and Logging:
typescript// src/lib/monitoring.ts export function logDeploymentInfo() { console.log({ version: import.meta.env.PUBLIC_VERSION, buildTime: new Date().toISOString(), environment: import.meta.env.MODE, }); } // Call in entry file logDeploymentInfo();
Best Practices:
-
Choose the Right Deployment Platform:
- Static sites: Vercel, Netlify, GitHub Pages
- SSR apps: Vercel, Netlify Edge, Node.js
- Edge computing: Cloudflare Workers, Vercel Edge
-
Environment Variables Management:
- Use
.envfiles for local development - Configure production environment variables on deployment platform
- Distinguish between public and private variables
- Use
-
Automated Deployment:
- Use CI/CD pipelines
- Automatically run tests
- Automatically deploy to production
-
Monitoring and Logging:
- Set up error tracking
- Monitor performance metrics
- Log deployment information
-
Rollback Strategy:
- Keep multiple deployment versions
- Quickly rollback to stable version
- Use feature flags
Astro provides flexible deployment options, allowing you to choose the most suitable deployment strategy based on your project requirements.