Deploy Astro on VPS with Nginx: Complete Guide Using Docker and Docker Compose
3 min read
TL;DR Deploying an Astro website on your VPS using Docker, Docker Compose, and Nginx provides full control, security, and scalability. Organize the project with a modular directory structure, configure Docker Compose to orchestrate services, and use Nginx as a reverse proxy. Build and start the services with
docker-compose up --build -d
, then access your website via your VPS IP. Enhance security with SSL and DNS proxying.
Deploying Astro to Your VPS with Nginx

Deploying an Astro website on your own Virtual Private Server (VPS) gives you full control over your web project while enhancing security and performance. This guide shows you how to deploy an Astro website using Docker, Docker Compose, and Nginx.
By the end of this article, you will:
- Deploy Astro on a VPS using Docker and Docker Compose.
- Configure Nginx as a reverse proxy for secure and efficient traffic management.
- Manage containerized services for scalability and maintainability.
Prerequisites
Before you begin, make sure you have the following:
- A VPS with root access.
- Docker and Docker Compose installed.
- Basic knowledge of Docker and Nginx.
Directory Structure
Organize your project directory as follows:
project-directory/
|-- docker-compose.yml
|-- astro/
| |-- Dockerfile
| |-- (Astro project files)
|-- nginx/
|-- Dockerfile
|-- nginx.conf
This structure keeps configurations modular and maintainable.
Step 1: Docker Compose Configuration
The docker-compose.yml
file orchestrates your deployment, defining two services:
astro
: Hosts the Astro website.nginx
: Acts as a reverse proxy for incoming traffic.
Create the docker-compose.yml
file:
version: '1'
services:
astro:
container_name: astro
restart: unless-stopped
build:
context: ./astro
dockerfile: Dockerfile
volumes:
- shared-data:/usr/src/astro/shared-data
ports:
- "4321:4321"
networks:
- network1
nginx:
container_name: nginx
restart: unless-stopped
build:
context: ./nginx
dockerfile: Dockerfile
volumes:
- shared-data:/usr/src/nginx/shared-data
ports:
- "80:80"
depends_on:
- astro
networks:
- network1
volumes:
shared-data:
networks:
network1:
driver: bridge
This configuration ensures:
- Volumes: Shared data between containers.
- Networks: Secure communication between services.
- Depends_on: Nginx starts after Astro is ready.
Step 2: Astro Dockerfile
Inside the astro/
directory, create a Dockerfile
:
FROM node:lts AS base
WORKDIR /app
COPY package.json package-lock.json ./
ENV ASTRO_DB_REMOTE_URL=libsql://example.com
ENV ASTRO_DB_APP_TOKEN=123456789
FROM base AS prod-deps
RUN npm install --omit=dev
FROM base AS build-deps
RUN npm install
FROM build-deps AS build
COPY . .
RUN npm run build --remote
FROM base AS runtime
COPY --from=prod-deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
ENV HOST=0.0.0.0
ENV PORT=4321
EXPOSE 4321
CMD node ./dist/server/entry.mjs
This Dockerfile uses a multi-stage build to optimize image size and maintain security.
Step 3: Nginx Configuration
Inside the nginx/
directory, create a Dockerfile
and nginx.conf
.
Nginx Dockerfile:
FROM nginx:1.23.1
WORKDIR usr/src/nginx
RUN rm /etc/nginx/nginx.conf
COPY nginx.conf /etc/nginx/
RUN rm /etc/nginx/conf.d/default.conf
COPY project.conf /etc/nginx/conf.d/
RUN mkdir /usr/src/nginx/shared-data
nginx.conf:
user nginx;
worker_processes 1;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
http {
include /etc/nginx/mime.types;
default_type text/html;
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
gzip on;
include /etc/nginx/conf.d/*.conf;
}
project.conf:
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://astro:4321;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_buffering off;
}
}
This setup ensures Nginx proxies traffic efficiently to the Astro service.
Step 4: Deploy the Setup
- Place all files in the appropriate directories.
- Build and start the services:
docker-compose up --build -d
- Access your VPS IP in a browser to view the deployed Astro website.
Next Steps and References
To secure your deployment, consider:
- Configuring SSL with Let’s Encrypt.
- Using a DNS proxy like Cloudflare.
Feb 22, 2025