Deploy Fullstack in Vps 💪

Last time, I wrote about deploying a static web application on a VPS via Portainer.

This article summarizes the knowledge I gained from deployment a full-stack web application on a VPS via Portainer.

Table of contents

Insights

docker-compose.yaml

Unknown Error

Insights

1. Building a Dockerfile Requires a Local Build File

Building a Dockerfile requires the application’s build file to be in the root directory.

Additionally, to build a full-stack application locally, the database must be started.

I encountered the following error due to a missing or failed build file:

Error: ENOENT: no such file or directory, open '<path to the project>/.next/prerender-manifest.json'

Stackoverflow: react-next-app-keeps-giving-me-an-error-about-missing-prerender-manifest-json

2. Database Configuration

  1. Ensure the application starts only after the database has started.

    dockerdocs: Control startup

  2. Use link to specify the hostname for the application to connect to the database.

    dockerdocs: links

  3. After initializing a volume, set up the database in the application by executing the necessary commands.

docker-compose.yaml

This is the docker-compose.yaml file for the full-stack application.

services:
  hoge:
    image: <path to the image>
    container_name: hogehoge
    depends_on:
      db:
        condition: service_healthy
        restart: true
    links:
      - db
    environment:
       - VPS_DATABASE_URL=postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@db:5432/${POSTGRES_DB}?schema=public
    ports:
       - "4000:3000"
    volumes:
      - <path to the app>:/app
      - <path to the app>/node_modules:/app/node_modules
    networks:
      hoge-net:
        aliases:
           - app
      reverseproxy-nw:
  db:
    image: postgres:16
    environment:
      - POSTGRES_USER=${POSTGRES_USER}
      - POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
      - POSTGRES_DB=${POSTGRES_DB}
    volumes:
      - pgdata:/var/lib/postgresql/data
    # ports:
    #   - "5432:5432"
    networks:
      hoge-net:
        aliases:
          - db
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 1s
      retries: 5

volumes:
  pgdata:
    driver: local

networks:
  hoge-net:
    driver: bridge
  reverseproxy-nw:
    external: true

Unknown error 🤔

Although I was able to deploy locally, I encountered a message that daemon: unauthorized error when pulling an image from GHCR using Portainer.

After re-registering the newly built Docker image to GHCR, I was able to deploy successfully.