Deploying Astro Site with Traefik and Systemd
This tutorial guides you through deploying an Astro Starlight site using Docker containers, Traefik as a reverse proxy with automatic SSL, and systemd for service management. By the end, you’ll have a production-ready site with automatic SSL certificates, load balancing, and automated service management. This guide assumes you have basic Linux command line knowledge and access to a server with Debian/Ubuntu, Docker, and Docker Compose installed.
Prerequisites
Section titled “Prerequisites”- Server with Debian/Ubuntu
- Docker and Docker Compose installed
- Domain name (e.g.,
<example.com>) - Basic knowledge of Linux command line
- Node.js 18.17 or newer
Setting Up Your Astro Project
Section titled “Setting Up Your Astro Project”If you don’t already have an Astro project, create one using the official CLI:
npm create astro@latest my-siteThe wizard will guide you through your options (default: Starlight, empty configuration, etc.). Once created, navigate to your project directory:
cd my-siteArchitecture Overview
Section titled “Architecture Overview”Internet → Traefik (SSL/Port 443) → Busybox httpd (Static Files) ↓ Systemd Service Management- Traefik: Handles SSL certificates, routing, and load balancing
- Busybox httpd: Lightweight web server serving static Astro files
- Systemd: Manages service lifecycle and automatic restarts
Step 1: Build Your Astro Site
Section titled “Step 1: Build Your Astro Site”-
Install dependencies and build
Terminal window npm installnpm run build -
Verify build output
Terminal window ls -la dist/You should see your static site files in the
dist/directory.
Step 2: Prepare Deployment Directory
Section titled “Step 2: Prepare Deployment Directory”-
Create deployment directory
Terminal window sudo mkdir -p /etc/docker-compose/<your_site> -
Copy build files
Terminal window sudo cp -r dist /etc/docker-compose/<your_site>/ -
Create Docker files Create the following files in
/etc/docker-compose/<your_site>/:
compose.yaml
Section titled “compose.yaml”services: traefik: image: traefik:latest command: - "--api.insecure=true" - "--providers.docker=true" - "--providers.docker.exposedbydefault=false" - "--entrypoints.web.address=:80" - "--entrypoints.web.http.redirections.entrypoint.to=websecure" - "--entrypoints.web.http.redirections.entrypoint.scheme=https" - "--entrypoints.websecure.address=:443" - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true" - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web" - "--certificatesresolvers.letsencrypt.acme.email=<your_email>" - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json" ports: - "80:80" - "443:443" - "8080:8080" volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - letsencrypt:/letsencrypt networks: - web restart: unless-stopped
web: image: busybox:1.36 command: httpd -f -p 80 -h /www volumes: - /etc/docker-compose/<your_site>/dist:/www:ro labels: - "traefik.enable=true" - "traefik.http.routers.<your_site>.rule=Host(`<example.com>`)" - "traefik.http.routers.<your_site>.entrypoints=websecure" - "traefik.http.routers.<your_site>.tls.certresolver=letsencrypt" - "traefik.http.services.<your_site>.loadbalancer.server.port=80" networks: - web restart: unless-stopped
volumes: letsencrypt:
networks: web: driver: bridgeStep 3: Configure Systemd Service
Section titled “Step 3: Configure Systemd Service”-
Create systemd service template
Terminal window sudo tee /etc/systemd/system/docker-compose@.service > /dev/null <<EOF[Unit]Description=docker-compose %i serviceRequires=docker.service network-online.targetAfter=docker.service network-online.target[Service]WorkingDirectory=/etc/docker-compose/%iType=simpleTimeoutStartSec=15minRestart=alwaysExecStartPre=/usr/bin/docker compose pull --quietExecStartPre=/usr/bin/docker compose buildExecStart=/usr/bin/docker compose up --remove-orphansExecStop=/usr/bin/docker compose down --remove-orphansExecReload=/usr/bin/docker compose pull --quietExecReload=/usr/bin/docker compose build[Install]WantedBy=multi-user.targetEOF -
Reload systemd
Terminal window sudo systemctl daemon-reload
Step 4: Configure DNS
Section titled “Step 4: Configure DNS”-
Add A record Point your domain (
<example.com>) to your server’s IP address. -
Verify DNS propagation
Terminal window nslookup <example.com>
Step 5: Start the Service
Section titled “Step 5: Start the Service”-
Start the service
Terminal window sudo systemctl start docker-compose@<your_site> -
Enable on boot
Terminal window sudo systemctl enable docker-compose@<your_site> -
Check status
Terminal window sudo systemctl status docker-compose@<your_site>
Step 6: Verify Deployment
Section titled “Step 6: Verify Deployment”-
Check Traefik dashboard Visit
http://<your_server_ip>:8080to see the Traefik dashboard. -
Test HTTPS Visit
https://<example.com>- you should see your Astro site with a valid SSL certificate. -
Check logs
Terminal window sudo journalctl -u docker-compose@<your_site> -f
Updating Your Site
Section titled “Updating Your Site”-
Build new version
Terminal window npm run build -
Update deployment files
Terminal window sudo cp -r dist/* /etc/docker-compose/<your_site>/dist/ -
Reload service
Terminal window sudo systemctl reload docker-compose@<your_site>
Troubleshooting
Section titled “Troubleshooting”Service won’t start
Section titled “Service won’t start”# Check Docker statussudo systemctl status docker
# Check compose logssudo docker compose -f /etc/docker-compose/<your_site>/compose.yaml logsSSL certificate issues
Section titled “SSL certificate issues”# Check Traefik logssudo docker logs traefik
# Verify domain routingcurl -I https://<example.com>Permission issues
Section titled “Permission issues”# Fix permissionssudo chown -R $USER:$USER /etc/docker-compose/<your_site>/Security Considerations
Section titled “Security Considerations”- Change the default Traefik dashboard port (8080) in production
- Use strong passwords for any exposed services
- Keep Docker and Traefik updated
- Monitor logs regularly
Conclusion
Section titled “Conclusion”You now have a production-ready Astro site deployment with:
- Automatic SSL certificates
- Load balancing and routing
- Service monitoring and auto-restart
- Easy updates and maintenance
Next steps:
- Check the Traefik documentation for advanced configurations
- Review the Docker Compose documentation for more options
- Consider adding monitoring with tools like Prometheus or Grafana