Deploy app in VPS via Portainer 🤩
updated at Sat, Mar 15, 2025
What is Portainer
?
Portainer
is a GUI-based tool for managing Docker
.
I’d like to host projects using Docker
on a VPS, and Portainer
makes maintenance much easier.
Table of contents
4. Create a container by Portainer
1. Prerequest
- VPS
- Portainer is deployed
- Docker
- Github account
2. Prepare a source code
Create a directory in VPS
~$ mkdir ~/home/<user name>/<project name>
Then add a source code with Dockerfile
.
Dockerfile
# Use the latest LTS version of Node.js
FROM node:18-alpine
# Set the working directory inside the container
WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./
# Install dependencies
RUN npm install
# Copy the rest of your application files
COPY . .
# Expose the port your app runs on
EXPOSE 3000
# Define the command to run your app
CMD ["npm", "start"]
3. Register Image to GHCR
However Portainer
handles containers like Docker Compose
, Portainer
itself doesn’t build Docker Image
.
So build Docker Image
then register it to Github Container Registory(GHCR)
to use it in Portainer
’s stack.
I prefer to use GHCR
because it allows me to host multiple private Images.
-
Build Image. *All process are done under project’s directory.
$ docker build -t <app name>:<version number> .
-
Get an Personal Access Token in
Github
to registerDocker Image
toGHCR
. -
Access
GHCR
bydocker login
. Let’s say we store Personal Access Token in~/ghcr.txt
$ cat ~/ghcr.txt | docker login ghcr.io -u <github user name> --password-stdin
-
Push
Docker Image
toGHCR
.$ docker tag <Image id> ghcr.io/<github user name>/<repository>/<Image name>:<version number> $ docker push ghcr.io/<github user name>/<repository>/<Image name>:<version number>
4. Create a container by Portainer
Create a new stack to Portainer.
If the app use .env
, add environment
in the stack.
Stack
services:
app:
image: ghcr.io/<github user name>/<repository>/<image name>:<version number>
container_name: <container name>
volumes:
- /home/<user name>/<...directory>/<project name>/node_modules:/app/node_modules
ports:
- "3000:3000"
stdin_open: true
tty: true
Access the web application from <vps-address>:3000
.
5. My trouble shooting
Actually, I was faced un error.
The error-log said that react-start script not found
.
It meant that node_modules
wasn’t exist in the container.
So I updated Dockerfile
like below,
# Use the latest LTS version of Node.js
FROM node:18-alpine
# Set the working directory inside the container
WORKDIR /app
# Copy package.json and package-lock.json
COPY package*.json ./
# Copy the rest of your application files
COPY . .
# Install dependencies
RUN npm install
# Expose the port your app runs on
EXPOSE 3000
# Define the command to run your app
CMD ["npm", "start"]
To debug this situation, I added command: sh
to Portainer’s stack.
Since the container was stopped immediately after it was created, I can pose this process by adding it.
Don’t forget to remove it after debugging after then.
Happy dev!😉
Update at Sat, Mar 15, 2025
My initial configuration of the volume in docker-compose.yaml
wasn’t correct.
volumes:
- ./node_modules:/app/node_modules
Should be like this.
volumes:
- /home/<user name>/<...directory>/<project name>/node_modules:/app/