Astro’s static output is a perfect fit for nginx.
Build locally
npm install
npm run build
# output is in dist/
Before building, make sure site in astro.config.mjs is your real domain, otherwise sitemap and hreflang links will point to the wrong address.
Upload to the server
rsync -avz --delete dist/ user@server:/var/www/blog/
nginx site config
/etc/nginx/sites-available/blog.conf:
server {
listen 80;
server_name blog.example.com;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name blog.example.com;
root /var/www/blog;
index index.html;
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;
# long cache for static assets
location ~* \.(js|css|png|jpg|svg|woff2|ico)$ {
expires 30d;
add_header Cache-Control "public, immutable";
}
# clean URL support
location / {
try_files $uri $uri/ $uri.html =404;
}
}
Enable and issue a certificate
sudo ln -s /etc/nginx/sites-available/blog.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo certbot --nginx -d blog.example.com
Automated deploy flow
Create a deploy script deploy.sh on the server:
#!/usr/bin/env bash
set -e
cd /path/to/blog
git pull
npm ci
npm run build
rsync -avz --delete dist/ /var/www/blog/
Combine it with cron or a webhook for push-to-publish.
Common issues
- Refresh gives 404: make sure
try_filesincludes$uri.html - Assets 404: a non-
/baseneeds manual asset prefix handling - Wrong domain in sitemap: check
siteinastro.config.mjs