0Pricing
Vue Academy · Lesson

Deploying Full-Stack Vue to Production

Docker Compose for Vue + Fastify, nginx reverse proxy, SSL with Let's Encrypt, CI/CD.

Deploying Full-Stack Vue to Production is a free Vue Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Vue Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The Production Topology

A full-stack Vue + Fastify app in production typically runs as two containers: an nginx container serving the built Vue static files, and a Fastify API container. nginx also reverse-proxies /api to the API.

Building the Vue App

Build the SPA with Vite to produce optimized static assets in dist. This is what nginx will serve.

# package.json script
npm run build
# produces dist/ with hashed JS/CSS and index.html

Vue Dockerfile (multi-stage)

Use a multi-stage Docker build: build with Node, then copy the static output into a small nginx image. The final image contains only static files and nginx.

FROM node:20-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf

nginx.conf: SPA + API Proxy

The nginx config serves the SPA (with a try_files fallback to index.html for client routing) and proxies /api to the Fastify container by its service name.

server {
  listen 80;
  root /usr/share/nginx/html;

  location / {
    try_files $uri $uri/ /index.html;
  }

  location /api/ {
    proxy_pass http://fastify-api:3000;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
  }
}

Fastify Dockerfile

The API image installs production dependencies and runs the server. Bind to 0.0.0.0 so it is reachable from other containers.

FROM node:20-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --omit=dev
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

docker-compose.yml

docker-compose wires the two services on a shared network. The proxy target fastify-api in nginx.conf matches the service name here.

services:
  vue-nginx:
    build: ./frontend
    ports:
      - '80:80'
      - '443:443'
    depends_on:
      - fastify-api
  fastify-api:
    build: ./backend
    environment:
      - JWT_SECRET=${JWT_SECRET}
    expose:
      - '3000'

Service Discovery by Name

Inside the compose network, containers reach each other by service name. nginx proxies to http://fastify-api:3000 — no IPs, no public exposure of the API port.

# only nginx is published to the host (80/443)
# fastify-api uses 'expose', reachable only internally

SSL with Certbot

Add HTTPS using Let's Encrypt via Certbot. Mount the certificates into nginx and configure a 443 server block, redirecting HTTP to HTTPS.

server {
  listen 443 ssl;
  ssl_certificate /etc/letsencrypt/live/app.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/app.com/privkey.pem;
  # ... same location blocks as before
}
server {
  listen 80;
  return 301 https://$host$request_uri;
}

Certbot Renewal

Certbot certificates last 90 days. Run a renewal command on a schedule (cron or a sidecar container) and reload nginx so renewed certs take effect.

# cron entry, twice daily
certbot renew --quiet && nginx -s reload

GitHub Actions CI/CD

Automate build and deploy with GitHub Actions: on push to main, build and test, then build/push images or SSH to the server to pull and restart with compose.

name: deploy
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm test
      - name: Deploy over SSH
        run: ssh $HOST 'cd /app && git pull && docker compose up -d --build'

Secrets and Environment

Never bake secrets into images. Pass them via environment variables (compose environment / env_file) sourced from GitHub Actions secrets. Keep JWT_SECRET, DB URLs, etc. out of the repo.

Quick Check

Test your understanding of full-stack deployment.

Recap

You learned production deployment:

  • Two services: vue-nginx (static) and fastify-api
  • nginx.conf serves the SPA and proxies /api to the API service name
  • docker-compose wires them; only nginx is published to the host
  • HTTPS via Certbot with scheduled renewal
  • GitHub Actions builds, tests, and deploys; secrets stay in env vars

Frequently asked questions

Is the “Deploying Full-Stack Vue to Production” lesson free?

Yes — the full text of “Deploying Full-Stack Vue to Production” is free to read here on the web, and the Vue Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Vue Academy course, upgrade to CoddyKit PRO.

What will I learn in “Deploying Full-Stack Vue to Production”?

Docker Compose for Vue + Fastify, nginx reverse proxy, SSL with Let's Encrypt, CI/CD. You practise Vue Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Vue Academy?

No prior experience is required. Vue Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Deploying Full-Stack Vue to Production” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Vue Academy lesson?

Yes. Every Vue Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Fastify Backend for Vue SPAs
  2. JWT Authentication: Login and Refresh
  3. Authenticated API Calls with Axios Interceptors
  4. Deploying Full-Stack Vue to Production
← Back to Vue Academy