Dream App (WIP - Work In Progress)
This is a small fun project to understand how to Dockerize a web app. It uses the OpenAI's DALL-E AI image generation model to generate image based on input text.
Index
- Technologies Used
- How to Install in Windows
- Backend
- Frontend
- Reverse Proxy
- Docker Compose
- References
- Further Development
Technologies Used
- Node.js
- Nodemon
- React
- Vite with Typescript + SWC
- Nginx
- Docker
How to Install in Windows
- Install WSL2
- Install Docker Desktop
- Clone repo
- Run
docker-compose up
- Open http://localhost:80
Backend
For backend I have used Node.js
to create a simple post API that can called with a prompt. This will then call OpenAI API to generate the image.
The Dockerfile here installs nodemon
in container, so that changes are automatically reflected without rebuilding the container.
Frontend
I have created a simple frontend application that call the backend API to generate the image and then shows the image. I have used React
+ Typescript
with Vite
.
Reverse Proxy
I have used Nginx
to create reverse proxy. Basically it gets the requests and forwards it to the actual server.
Location /
is mapped to frontend while /api
is mapped to backend.
For backend, I am rewriting the call so that server does not actually receive /api/dream
but just /dream
rewrite ^/api/(.*)$ /$1 break;
Docker Compose
This is the interesting part!!!
I have created 3 services:
nodeserver
I have created 2 replicas of node server using
deploy:
replicas: 2
Now, we can't specify the ports at which the servers will run in localhost, so just specify the container port at which it will run using:
ports:
- '8080'
# Not - '8080:8080'
Now if we make some changes locally, nodemon
should be updating the changes automatically BUT we are making changes locally and nodemon is running in container, so we have to mount the local files to container, so that container will use our files and not the copied ones. We can do this using:
volumes:
- ./server:/app
But I am on windows machine and docker is using linux based container, so my node_modules cannot be used there, so I created a volume for node_modules that will be used in container using:
services:
nodeserver:
...
volumes:
- ./server:/app
- serverNodeModules:/app/node_modules
...
volumes:
serverNodeModules:
Now we can use the following command to run nodemon. -L (legacy) is important otherwise it will not work from inside docker container
nodemon -L index.js
app
This is for the frontend. The same comcept used for nodeserver are used here. For frontend only 1 container is used.
Now for vite to work properly we need some extra config in vite.config.ts
file:
server: {
port: 5000,
host: true,
watch: {
usePolling: true
}
}
port
and host
are important otherwise vite will not allow to access from outside container.
usePolling
is required for hot reload to work from container.
nginx
This is the Nginx
container with port forwarding of 80:80
as 80
is the default nginx port.
References
TODO: Add references
Further Development
Frontend
- Adding theme switcher
- Improve design
- Showing errors
- Adding Tests
Backend
- Adding jwt based authentication
- Create seperate container for auth
- Adding Tests
- Switch to typescript?
Docker
- Pass environment variables to frontend
- Handle Production build
Others
- Deploy somewhere