DEV Community

Cover image for Vite, Yarn and Vue with Docker
Ilya N. Zykin
Ilya N. Zykin

Posted on

Vite, Yarn and Vue with Docker

Today I'm starting learning a new project and its' frontend part. I should say I never worked with Vue before and I need to make a playground to experiment with it and learn it from practice.

My first idea is to setup a Docker container with some specific versions of Javascript based tools and play with the code a bit. Later I can extend my experience on a real project.

Let's start.

Step 1. Create a Project

mkdir docker-vite and cd docker-vite

Step 2. Create Project's structure

├── README.md
├── Vite.Dockerfile
├── docker-compose.yml
└── shell
    └── build.sh
Enter fullscreen mode Exit fullscreen mode

shell folder will contain some shell helpers to automate some routine processes. Like build a docker image or push an image to hub.docker.com

Step 3. Prepare a Docker Image

In Vite.Dockerfile I have the following

Original image I found here jitesoft/node-yarn

# VITE | NODE 20 + YARN 3.5+
FROM --platform=$BUILDPLATFORM jitesoft/node-yarn:20

ARG TARGETARCH
ARG BUILDPLATFORM

RUN echo "$BUILDPLATFORM" > /BUILDPLATFORM
RUN echo "$TARGETARCH" > /TARGETARCH

RUN yarn set version berry
RUN mkdir -p /home/app
WORKDIR /home/app

EXPOSE 4000

CMD ["/bin/sh"]
Enter fullscreen mode Exit fullscreen mode

Step 4. Building the Image

Now I'm building the image

docker build \
  -t iamteacher/vite:arm64 \
  -f Vite.Dockerfile \
  --build-arg BUILDPLATFORM="linux/arm64" \
  --build-arg TARGETARCH="arm64" \
  .
Enter fullscreen mode Exit fullscreen mode

console output is:

the-teacher@macbook docker-vite:: $ docker build \
>   -t iamteacher/vite:arm64 \
>   -f Vite.Dockerfile \
>   --build-arg BUILDPLATFORM="linux/arm64" \
>   --build-arg TARGETARCH="arm64" \
>   .
[+] Building 0.1s (10/10) FINISHED
 => [internal] load build definition from Vite.Dockerfile                                                               0.0s
 => => transferring dockerfile: 42B                                                                                     0.0s
 => [internal] load .dockerignore                                                                                       0.0s
 => => transferring context: 2B                                                                                         0.0s
 => [internal] load metadata for docker.io/jitesoft/node-yarn:20                                                        0.0s
 => [1/6] FROM docker.io/jitesoft/node-yarn:20                                                                          0.0s
 => CACHED [2/6] RUN echo "linux/arm64" > /BUILDPLATFORM                                                                0.0s
 => CACHED [3/6] RUN echo "arm64" > /TARGETARCH                                                                         0.0s
 => CACHED [4/6] RUN yarn set version berry                                                                             0.0s
 => CACHED [5/6] RUN mkdir -p /home/app                                                                                 0.0s
 => CACHED [6/6] WORKDIR /home/app                                                                                      0.0s
 => exporting to image                                                                                                  0.0s
 => => exporting layers                                                                                                 0.0s
 => => writing image sha256:d99d23d1ac58af0fad10c7c0868e7bb7f4d1636e7627f999a9e7b2a1f071e328                            0.0s
 => => naming to docker.io/iamteacher/vite:arm64
Enter fullscreen mode Exit fullscreen mode

Step 5. Simple Image Building Automatization

To make re-building process simpler I create a bash file that I'm going to use later

shell/build.sh

# Run from the root of the project
#
# source shell/build.sh

docker build \
  -t iamteacher/vite:arm64 \
  -f Vite.Dockerfile \
  --build-arg BUILDPLATFORM="linux/arm64" \
  --build-arg TARGETARCH="arm64" \
  .

docker build \
  -t iamteacher/vite:amd64 \
  -f Vite.Dockerfile \
  --build-arg BUILDPLATFORM="linux/amd64" \
  --build-arg TARGETARCH="amd64" \
  .
Enter fullscreen mode Exit fullscreen mode

Step 6. Checking the Image and Software

Let's jump in to the container and check if it works correctly.

docker run -ti iamteacher/vite:arm64
Enter fullscreen mode Exit fullscreen mode

Step 7. In the Container

/home/app # pwd
/home/app

/home/app # node -v
v20.0.0

/home/app # yarn -v
3.5.0

/home/app # npm -v
9.6.4

/home/app # exit
Enter fullscreen mode Exit fullscreen mode

Step 8. Docker compose

Now it is time for writing docker-compose.yml.

For now I have nothing to run with node in my project. I want just to start a container, link with my current folder and initiate a node project.

# docker compose -f docker-compose.yml up

version: '3.9'

name: vite_docker

services:
  # Port: 4000
  vite:
    tty: true
    image: iamteacher/vite:arm64
    ports:
      - 4000:4000
    volumes:
      - .:/home/app
Enter fullscreen mode Exit fullscreen mode

And now let's run the container with using docker compose

docker-vite:: $ docker compose -f docker-compose.yml up
[+] Running 1/0
 ⠿ Container vite_docker-vite-1  Created                                                                                0.0s
Attaching to vite_docker-vite-1
Enter fullscreen mode Exit fullscreen mode

Step 9. Initiate Yarn/Vue Project

$ docker exec -ti vite_docker-vite-1 sh
Enter fullscreen mode Exit fullscreen mode

Now we are inside the container. Let's check that container is linked to our HOST filesystem.

Yes, inside the container we see all files of our project.

Command: ls

/home/app # ls
  README.md
  Vite.Dockerfile
  docker-compose.yml
  shell
Enter fullscreen mode Exit fullscreen mode

Command: yarn create vite

/home/app # yarn create vite

➤ YN0000: ┌ Resolution step
➤ YN0000: └ Completed in 5s 66ms
➤ YN0000: ┌ Fetch step
➤ YN0013: │ create-vite@npm:4.2.0 can't be found in the cache and will be fetched from the remote registry
➤ YN0000: └ Completed in 0s 407ms
➤ YN0000: ┌ Link step
➤ YN0000: │ ESM support for PnP uses the experimental loader API and is therefore experimental
➤ YN0000: └ Completed
➤ YN0000: Done with warnings in 5s 520ms
Enter fullscreen mode Exit fullscreen mode
  • Project name: vite-project
  • Framework: Vue
  • Variant: TypeScript
✔ Project name: … vite-project
? Select a framework: › - Use arrow-keys. Return to submit.
    Vanilla
❯   Vue
    React
    Preact
    Lit
    Svelte
    Others
Enter fullscreen mode Exit fullscreen mode
? Select a variant: › - Use arrow-keys. Return to submit.
    JavaScript
❯   TypeScript
    Customize with create-vue ↗
    Nuxt ↗
Enter fullscreen mode Exit fullscreen mode

On this step I have the following error:

LibzipError [Libzip Error]: Can't open file: No file descriptors available
    at ZipFS.makeLibzipError (/tmp/xfs-eed97368/dlx-1414/.pnp.cjs:1675:25)
    at new ZipFS (/tmp/xfs-eed97368/dlx-1414/.pnp.cjs:1650:20)
    at ZipOpenFS.getZipSync (/tmp/xfs-eed97368/dlx-1414/.pnp.cjs:3840:18)
    at ZipOpenFS.makeCallSync (/tmp/xfs-eed97368/dlx-1414/.pnp.cjs:3720:17)
    at ZipOpenFS.readdirSync (/tmp/xfs-eed97368/dlx-1414/.pnp.cjs:3613:17)
    at VirtualFS.readdirSync (/tmp/xfs-eed97368/dlx-1414/.pnp.cjs:2861:24)
    at PosixFS.readdirSync (/tmp/xfs-eed97368/dlx-1414/.pnp.cjs:2861:24)
    at NodePathFS.readdirSync (/tmp/xfs-eed97368/dlx-1414/.pnp.cjs:2861:24)
    at Jr (file:///root/.yarn/berry/cache/create-vite-npm-4.2.0-11226b5ec8-8.zip/node_modules/create-vite/dist/index.mjs:49:180)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
  code: 'ZIP_ER_OPEN'
}
Enter fullscreen mode Exit fullscreen mode

Step 10. Second Attempt

After having the error I'm trying to rerun the create command. This time everything goes successfully.

/home/app # yarn create vite
Enter fullscreen mode Exit fullscreen mode
✔ Project name: … vite-project
✔ Select a framework: › Vue
✔ Select a variant: › TypeScript

Scaffolding project in /home/app/vite-project...

Done. Now run:

  cd vite-project
  yarn
  yarn dev
Enter fullscreen mode Exit fullscreen mode
/home/app # ls -al vite-project/
total 28
drwxr-xr-x   12 root     root           384 Apr 20 10:30 .
drwxr-xr-x    9 root     root           288 Apr 20 10:27 ..
-rw-r--r--    1 root     root           253 Apr 20 10:30 .gitignore
drwxr-xr-x    3 root     root            96 Apr 20 10:30 .vscode
-rw-r--r--    1 root     root          1527 Apr 20 10:30 README.md
-rw-r--r--    1 root     root           362 Apr 20 10:30 index.html
-rw-r--r--    1 root     root           381 Apr 20 10:30 package.json
drwxr-xr-x    3 root     root            96 Apr 20 10:30 public
drwxr-xr-x    8 root     root           256 Apr 20 10:30 src
-rw-r--r--    1 root     root           488 Apr 20 10:30 tsconfig.json
-rw-r--r--    1 root     root           184 Apr 20 10:30 tsconfig.node.json
-rw-r--r--    1 root     root           157 Apr 20 10:30 vite.config.ts
Enter fullscreen mode Exit fullscreen mode

Step 11. The issue with yarn .lock

When I do

  cd vite-project
  yarn
Enter fullscreen mode Exit fullscreen mode

I see the following:

Usage Error: The nearest package directory (/home/app/vite-project) doesn't seem to be part of the project declared in /.

- If / isn't intended to be a project, remove any yarn.lock and/or package.json file there.
- If / is intended to be a project, it might be that you forgot to list home/app/vite-project in its workspace configuration.
- Finally, if / is fine and you intend home/app/vite-project to be treated as a completely separate project (not even a workspace), create an empty yarn.lock file in it.
Enter fullscreen mode Exit fullscreen mode

I use the last one option - creating an empty yarn.lock

Command: touch yarn.lock

  touch yarn.lock
  yarn install
Enter fullscreen mode Exit fullscreen mode

Now I see:

/home/app/vite-project # yarn install
➤ YN0000: ┌ Resolution step
➤ YN0061: │ sourcemap-codec@npm:1.4.8 is deprecated: Please use @jridgewell/sourcemap-codec instead
➤ YN0032: │ fsevents@npm:2.3.2: Implicit dependencies on node-gyp are discouraged
➤ YN0061: │ @npmcli/move-file@npm:2.0.1 is deprecated: This functionality has been moved to @npmcli/fs
➤ YN0002: │ @volar/vue-typescript@npm:1.3.19 doesn't provide typescript (p5c1ac), requested by @volar/typescript
➤ YN0000: │ Some peer dependencies are incorrectly met; run yarn explain peer-requirements <hash> for details, where <hash> is the six-letter p-prefixed code
➤ YN0000: └ Completed in 3s 997ms
➤ YN0000: ┌ Fetch step
➤ YN0013: │ which@npm:2.0.2 can't be found in the cache and will be fetched from the remote registry
➤ YN0013: │ wide-align@npm:1.1.5 can't be found in the cache and will be fetched from the remote registry
➤ YN0013: │ wrappy@npm:1.0.2 can't be found in the cache and will be fetched from the remote registry
➤ YN0013: │ yallist@npm:4.0.0 can't be found in the cache and will be fetched from the remote registry
➤ YN0013: │ typescript@npm:4.9.5 can't be found in the cache and will be fetched from the remote registry
➤ YN0000: └ Completed in 29s 909ms
➤ YN0000: ┌ Link step
➤ YN0000: │ ESM support for PnP uses the experimental loader API and is therefore experimental
➤ YN0007: │ esbuild@npm:0.17.17 must be built because it never has been before or the last one failed
➤ YN0000: └ Completed in 1s 70ms
➤ YN0000: Done with warnings in 35s 8ms
Enter fullscreen mode Exit fullscreen mode

Step 12. Running VITE

Now I'm running VITE:

Command: yarn dev

# yarn dev

  VITE v4.3.0  ready in 604 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: use --host to expose
  ➜  press h to show help
Enter fullscreen mode Exit fullscreen mode

From it I decide I need to change the port and expose my app. Let's try the following:

Command: yarn dev --host --port 4000

# yarn dev --host --port 4000

  VITE v4.3.0  ready in 584 ms

  ➜  Local:   http://localhost:4000/
  ➜  Network: http://172.22.0.2:4000/
Enter fullscreen mode Exit fullscreen mode

Great! It's alive!

Image description

We can stop the project. CMD+C

Step 13. Updating docker-compose.yml

Now, when we have a VITE project and it works I want to update my docker-compose.yml to make things more adjusted to each other.

I add a new line

command: yarn dev --host --port 4000
Enter fullscreen mode Exit fullscreen mode

and also change volumes section

volumes:
  - ./vite-project:/home/app
Enter fullscreen mode Exit fullscreen mode

For now docker-compose.yml looks so:

# docker compose -f docker-compose.yml up

version: '3.9'

name: vite_docker

services:
  # Port: 4000
  vite:
    tty: true
    image: iamteacher/vite:arm64
    command: yarn dev --host --port 4000
    ports:
      - 4000:4000
    volumes:
      - ./vite-project:/home/app
Enter fullscreen mode Exit fullscreen mode

Step 14. Running and saving the results

I'm going to run the project one more time to check if everything goes well.


$ docker compose -f docker-compose.yml up

[+] Running 1/1
 ⠿ Container vite_docker-vite-1

vite_docker-vite-1  |   VITE v4.3.0  ready in 619 ms
vite_docker-vite-1  |
vite_docker-vite-1  |   ➜  Local:   http://localhost:4000/
vite_docker-vite-1  |   ➜  Network: http://172.22.0.2:4000/
vite_docker-vite-1  |   ➜  press h to show help
Enter fullscreen mode Exit fullscreen mode

The project is available on http://localhost:4000 without any additional actions.

Let's add some lines in .gitignore

node_modules
.yarn
Enter fullscreen mode Exit fullscreen mode

And save with git and push to github -- docker-vite

UPD

If you want to integrate your Vite project into an existed App, you probably need to have a manifest.json file.

To have it you should add --manifest flag when you compile production build, or add the same flag in vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

const viteConfig = defineConfig({
  build: {
    manifest: true
  },
  plugins: [vue()],
})

export default viteConfig
Enter fullscreen mode Exit fullscreen mode

Top comments (0)