diff --git a/.github/workflows/docker-image.yml b/.github/workflows/docker-image.yml index 047470a..35de1e9 100644 --- a/.github/workflows/docker-image.yml +++ b/.github/workflows/docker-image.yml @@ -32,4 +32,4 @@ jobs: with: context: . push: true - tags: wongsaang/chatgpt-ui:latest,wongsaang/chatgpt-ui:${{ github.ref_name }} + tags: wongsaang/chatgpt-ui-client:latest,wongsaang/chatgpt-ui-client:${{ github.ref_name }} diff --git a/Dockerfile b/Dockerfile index 2e4a925..73e42d1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -8,18 +8,15 @@ RUN yarn install COPY . . -RUN yarn build +RUN yarn generate -FROM node:18-alpine3.16 - -ENV NITRO_HOST=0.0.0.0 -ENV NITRO_PORT=80 +FROM nginx:alpine WORKDIR /app -COPY --from=builder /app/.output . +COPY --from=builder /app/.output/public . -EXPOSE 80 +COPY nginx.conf /etc/nginx/templates/default.conf.template -ENTRYPOINT ["node", "server/index.mjs"] \ No newline at end of file +EXPOSE 80 \ No newline at end of file diff --git a/README.md b/README.md index c823fe9..39a9ea5 100644 --- a/README.md +++ b/README.md @@ -4,17 +4,81 @@ # ChatGPT UI -A web client for ChatGPT, using OpenAI's API. The implementation of the interface part uses [waylaidwanderer/node-chatgpt-api](https://github.com/waylaidwanderer/node-chatgpt-api) +--- -This project is based on [nuxt3](https://nuxt.com/docs/getting-started/introduction) +A web client for ChatGPT, using OpenAI's API. -## Quick start with docker -```bash -docker run -p 80:80 wongsaang/chatgpt-ui:latest +## πŸ“’Updates + +--- + +Version 2 is a major update that separates the backend functionality as an independent project, hosted at [chatgpt-ui-server](https://github.com/WongSaang/chatgpt-ui-server). + +If you still wish to use the old version, please visit the [v1 branch](https://github.com/WongSaang/chatgpt-ui/tree/v1). + +Version 2 introduces the following new features: + +- πŸ˜‰ Separation of the frontend and backend, with the backend now using the Python-based Django framework. +- 😘 User authentication, supporting multiple users. +- πŸ˜€ Ability to store data in an external database (defaulting to Sqlite). +- 😎 Session persistence, allowing the API to answer questions based on your context. + + +## Quick start with Docker Compose + +--- +### Run services + +Below is a docker-compose.yml template: + +```yaml +version: '3' +services: + client: + image: wongsaang/chatgpt-ui-client:latest + environment: + - SERVER_DOMAIN=http://backend:8000 + depends_on: + - backend + volumes: + - backend_static:/app/static + ports: + - '80:80' + networks: + - chatgpt_ui_network + backend: + image: wongsaang/chatgpt-ui-server:latest + environment: + # - DB_URL=postgres://postgres:postgrespw@localhost:49153/chatgpt # If this parameter is not set, the built-in Sqlite will be used by default. It should be noted that if you do not connect to an external database, the data will be lost after the container is destroyed. + - DJANGO_SUPERUSER_USERNAME=admin # default superuser name + - DJANGO_SUPERUSER_PASSWORD=password # default superuser password + - DJANGO_SUPERUSER_EMAIL=admin@example.com # default superuser email + volumes: + - backend_static:/app/static + ports: + - '8000:8000' + networks: + - chatgpt_ui_network + +networks: + chatgpt_ui_network: + driver: bridge + +volumes: + backend_static: ``` +### After running + +After running the services, you can access the web client at http://localhost, and an admin panel at http://localhost/admin. + +Before you can start chatting, you need to log in to the admin panel to add an OpenAI API key. In the Settings model, add a record with the name "openai_api_key" and the value as your API key. + + ## Development +--- + ### Setup Make sure to install the dependencies: diff --git a/app.vue b/app.vue deleted file mode 100644 index 93e1cea..0000000 --- a/app.vue +++ /dev/null @@ -1,108 +0,0 @@ - - - \ No newline at end of file diff --git a/composables/states.js b/composables/states.js index d40c2db..e2a228d 100644 --- a/composables/states.js +++ b/composables/states.js @@ -1,5 +1,10 @@ + export const useModels = () => useState('models', () => getStoredModels()) export const useCurrentModel = () => useState('currentModel', () => getCurrentModel()) -export const useApiKey = () => useState('apiKey', () => getStoredApiKey()) \ No newline at end of file +export const useApiKey = () => useState('apiKey', () => getStoredApiKey()) + +export const useConversion = () => useState('conversion', () => getDefaultConversionData()) + +export const useConversions = () => useState('conversions', () => []) \ No newline at end of file diff --git a/composables/useAuthFetch.js b/composables/useAuthFetch.js new file mode 100644 index 0000000..9e95d4a --- /dev/null +++ b/composables/useAuthFetch.js @@ -0,0 +1,21 @@ +export const useAuthFetch = async (url, options = {}) => { + const { $auth } = useNuxtApp() + + const token = await $auth.retrieveToken() + + if (!token) { + return await $auth.redirectToLogin() + } + + options = Object.assign(options, { + headers: { + 'Authorization': 'Bearer ' + token + } + }) + + const res = await useFetch(url, options) + if (res.error.value && res.error.value.status === 401) { + await $auth.logout() + } + return res +} diff --git a/docker-compose.pro.yml b/docker-compose.pro.yml new file mode 100644 index 0000000..bdf9260 --- /dev/null +++ b/docker-compose.pro.yml @@ -0,0 +1,34 @@ +version: '3' +services: + client: + image: wongsaang/chatgpt-ui-client:latest + environment: + - SERVER_DOMAIN=http://backend:8000 + depends_on: + - backend + volumes: + - backend_static:/app/static + ports: + - '80:80' + networks: + - chatgpt_ui_network + backend: + image: wongsaang/chatgpt-ui-server:latest + environment: +# - DB_URL=postgres://postgres:postgrespw@localhost:49153/chatgpt # If this parameter is not set, the built-in Sqlite will be used by default. It should be noted that if you do not connect to an external database, the data will be lost after the container is destroyed. + - DJANGO_SUPERUSER_USERNAME=admin # default superuser name + - DJANGO_SUPERUSER_PASSWORD=password # default superuser password + - DJANGO_SUPERUSER_EMAIL=admin@example.com # default superuser email + volumes: + - backend_static:/app/static + ports: + - '8000:8000' + networks: + - chatgpt_ui_network + +networks: + chatgpt_ui_network: + driver: bridge + +volumes: + backend_static: \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml index 86480ad..a4a1fb3 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,8 +1,31 @@ version: '3' services: - app: + client: build: context: . dockerfile: ./Dockerfile + environment: + - SERVER_DOMAIN=http://backend:8000 + depends_on: + - backend + volumes: + - backend_static:/app/static ports: - - '${APP_PORT:-80}:80' \ No newline at end of file + - '80:80' + networks: + - chatgpt_ui_network + backend: + image: 'wongsaang/chatgpt-ui-server:latest' + volumes: + - backend_static:/app/static + ports: + - '8000:8000' + networks: + - chatgpt_ui_network + +networks: + chatgpt_ui_network: + driver: bridge + +volumes: + backend_static: \ No newline at end of file diff --git a/layouts/default.vue b/layouts/default.vue new file mode 100644 index 0000000..2a87f8d --- /dev/null +++ b/layouts/default.vue @@ -0,0 +1,149 @@ + + + + + \ No newline at end of file diff --git a/layouts/vuetifyApp.vue b/layouts/vuetifyApp.vue new file mode 100644 index 0000000..d081486 --- /dev/null +++ b/layouts/vuetifyApp.vue @@ -0,0 +1,7 @@ + \ No newline at end of file diff --git a/nginx.conf b/nginx.conf new file mode 100644 index 0000000..9c37166 --- /dev/null +++ b/nginx.conf @@ -0,0 +1,23 @@ +server { + listen 80; + listen [::]:80; + server_name localhost; + + location / { + root /app; + index index.html; + } + + location /api/ + { + proxy_pass ${SERVER_DOMAIN}; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + location /admin/ { + proxy_pass ${SERVER_DOMAIN}; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} diff --git a/nuxt.config.ts b/nuxt.config.ts index 8c0c401..a7ca469 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -48,5 +48,14 @@ export default defineNuxtConfig({ vueI18n: { fallbackLocale: 'en', }, - } + }, + nitro: { + devProxy: { + "/api": { + target: "http://localhost:8000/api", + prependPath: true + } + + } + }, }) diff --git a/package.json b/package.json index 5f3e93c..6859e83 100644 --- a/package.json +++ b/package.json @@ -15,7 +15,6 @@ }, "dependencies": { "@microsoft/fetch-event-source": "^2.0.1", - "@waylaidwanderer/chatgpt-api": "^1.12.2", "highlight.js": "^11.7.0", "is-mobile": "^3.1.1", "marked": "^4.2.12", diff --git a/pages/index.vue b/pages/index.vue index 3b832c4..1972cf4 100644 --- a/pages/index.vue +++ b/pages/index.vue @@ -1,7 +1,10 @@