# Nuxt3 Deployment
Here is a memo for deployment. It skips lots of detail and only focus on nuxt3 project setup.
## I. Web App Project Settings
First, get started with web project settings to understand how to start a server in dockerfile.
### Package.json
There are there scripts required in deployment.
- `build`: Build nitro server in production. If there is variable that is not runtime env, pass it as env arg.
- `start`: Start nitro server in production. If there is variable that is runtime env, pass it as env arg.
- `coverage`: Run overall vitest to get coverage report. It's useful to prepare report for sonarqube.
```json
{
"scripts": {
"build": "nuxt build",
"start": "node .output/server/index.mjs",
"coverage": "vitest run --coverage"
}
}
```
### Dotenv File
Create a dotenv file for production env.
(Please be careful NOT to expose private variables in commit. If you need to pass private variables, put them through env while launching docker image.)
```dotenv
NUXT_PUBLIC_PHASE=production
NUXT_PUBLIC_WEB_API_URL=https://xxx.com
```
### Dockerfile
Although it's not recommended by nuxt official. You can use hecky way to export dotenv file variables and then start the nitro server if your team relies on it to manage different environment variables. Let me show you how to do it.
Handle launching server command in dockerfile. Using a bash script to start server at entrypoint.
```dockerfile
# ./web-app.dockerfile
FROM node:18.19.1
# Pnpm Setup
ENV PNPM_HOME="/pnpm"
ENV PATH="$PNPM_HOME:$PATH"
RUN corepack enable
WORKDIR /app
ENTRYPOINT ["bash", "./entrypoint.sh"]
```
### Bash Script
Then, export env varirables by phase as NODE_ENV variables and start nitro server.
```bash
# ./entrypoint.sh
export $(cat .env.${PHASE})
pnpm start
```
## II. Github Action
Then, go further more to create a github action workflow to build web application and build docker image based on previous section.
### Workflow
The main concept is:
- Web application will be built every time.
- Docker image will be built and published if and only tags and push trunk branch triggering.
- Docker image is tagged with github sha.
- Web server is starting in `web-app.dockerfile`.
```yaml
# .github/workflows/pipeline.yaml
name: 🚦 Deployment
on:
push:
branches:
- 'trunk'
tags:
- 'beta'
- 'staging'
- '*.*.*'
pull_request:
jobs:
build-web-app:
shell: bash
name: build-web-app
runs-on: [ self-hosted, Linux ]
container: node:18.19.1
steps:
- name: Clone
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup pnpm
uses: pnpm/action-setup@v4
with:
version: 9
- name: Setup Node.js
uses: actions/setup-node@v3
with:
node-version: 18.19.1
cache: 'pnpm'
cache-dependency-path: pnpm-lock.yaml
- name: Install dependencies
run: pnpm install
- name: Coverage web app
run: pnpm coverage
- name: Build web app
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
run: pnpm build
- if: ${{ github.event_name != 'pull_request' }}
name: Setup Docker
run: |
apt-get update && apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://get.docker.com | sh
- if: ${{ github.event_name != 'pull_request' }}
name: Setup Docker Meta
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.IMAGE_BASE }}
- if: ${{ github.event_name != 'pull_request' }}
name: Setup QEMU
uses: docker/setup-qemu-action@v3
- if: ${{ github.event_name != 'pull_request' }}
name: Setup Docker Buildx
uses: docker/setup-buildx-action@v3
with:
version: latest
buildkitd-flags: --debug
buildkitd-config-inline: |
[registry."docker.io"]
mirrors = ["${{ vars.DOCKER_HUB_MIRROR }}"]
- if: ${{ github.event_name != 'pull_request' }}
name: Login to Image Registry
uses: docker/login-action@v3
with:
registry: ${{ vars.DOCKER_REGISTRY }}
username: ${{ secrets.HARBOR_USERNAME }}
password: ${{ secrets.HARBOR_PASSWORD }}
- if: ${{ github.event_name != 'pull_request' }}
name: Docker Build and Push to Registry
uses: docker/build-push-action@v5
with:
platforms: linux/amd64,linux/arm64
labels: ${{ steps.meta.outputs.labels }}
push: true
provenance: false
tags: ${{ vars.DOCKER_REGISTRY }}/${{ env.HARBOR_PROJECT_NAME }}/web-app:${GITHUB_SHA:0:7}
file: web-app.dockerfile
context: .
```
## III. K8S Manifest
Finally, pass `PHASE` while initializing a docker container so it can run the server with env variables.
Here is the ingress config in another k8s manifest repo.
```yaml
# overlays/production/apps/patches
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
template:
spec:
containers:
- name: web-app
image: harbor.xxx.com/web-app
env:
- name: PHASE
value: "production"
```
That's all! Feel free to copy the template and modify it as you wish.
###### tags: `Work` `Nuxt3` `Github Workflow` `Docker`