Merge pull request #12 from lancatlin/deployment

Deployment frontend
This commit is contained in:
Lin, Hung-Shin authored and GitHub committed 2023-08-23 10:58:59 +08:00
commit bdb979e608
31 files changed
+176 -77

No files matched your search

+2 -1
View File
@@ -1,2 +1,3 @@
node_modules */node_modules
.git .git
*/dist
+1
View File
@@ -2,3 +2,4 @@ vite.config.js
.gitignore .gitignore
data data
mongo-init.js mongo-init.js
app/dist
+19 -2
View File
@@ -19,12 +19,29 @@ jobs:
username: ${{ secrets.DOCKERHUB_USERNAME }} username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }} password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build and push Docker image - name: Build backend
uses: docker/build-push-action@v2 uses: docker/build-push-action@v2
with: with:
context: . context: .
file: ./server/Dockerfile
push: true push: true
tags: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/linux-odyssey:latest tags: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/linux-odyssey:backend
- name: Build app
uses: docker/build-push-action@v2
with:
context: .
file: ./app/Dockerfile
push: true
tags: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/linux-odyssey:app
- name: Build quest helloworld
uses: docker/build-push-action@v2
with:
context: .
file: ./quests/helloworld/Dockerfile
push: true
tags: docker.io/${{ secrets.DOCKERHUB_USERNAME }}/linux-odyssey:helloworld
deploy: deploy:
needs: build-and-push needs: build-and-push
+22
View File
@@ -0,0 +1,22 @@
name: ESLint Checks
on:
push:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- name: Install dependencies
run: yarn install
- name: Lint
run: yarn lint
+1
View File
@@ -1 +1,2 @@
data/* data/*
app/dist
+15 -33
View File
@@ -8,64 +8,47 @@
## Installation ## Installation
```
git clone https://github.com/lancatlin/linux-odyssey.git git clone https://github.com/lancatlin/linux-odyssey.git
cd linux-odyssey cd linux-odyssey
yarn install yarn install
```
## Create database ## Development
``` Run everything (frontend, backend, db, swagger, quests):
docker compose pull
docker compose up -d db
```
## Server
Source: `server/`
```
docker compose -f docker-compose.build.yml pull
docker compose up -d
# Open http://localhost:3000
```
### Build images
docker compose build docker compose build
docker compose push docker compose up -d
Game images: ### Deployment
``` docker compose -f docker-compose.prod.yml build
docker compose -f docker-compose.build.yml build docker compose -f docker-compose.prod.yml push
docker compose -f docker-compose.build.yml push
```
## App # Server side
docker compose -f docker-compose.prod.yml pull
docker compose -f docker-compose.prod.yml up -d
## Standalone App (without Docker)
Source: `app/` Source: `app/`
```
# Connect to dev server (https://odyssey.wancat.cc) # Connect to dev server (https://odyssey.wancat.cc)
yarn app yarn app
# Connect to localhost (http://localhost:3000) # Connect to localhost (http://localhost:3000)
yarn app:local yarn app:local
```
# Connect to anyhost
API_ENDPOINT=http://example.com yarn app:local
## Swagger ## Swagger
```
docker compose up -d swagger docker compose up -d swagger
```
Open http://localhost:8080 to open Swagger Open http://localhost:8080 to open Swagger
## CLI terminal client ## CLI terminal client (Docker not required)
```
yarn cli yarn cli
Usage: client [options] [command] Usage: client [options] [command]
@@ -77,7 +60,6 @@ Options:
Commands: Commands:
list List all sessions list List all sessions
```
connet to recent session: connet to recent session:
+14
View File
@@ -0,0 +1,14 @@
# Build stage
FROM node as build-stage
WORKDIR /app
COPY app/package.json yarn.lock ./
RUN yarn install
COPY app .
RUN yarn build
# Production stage
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY deployment/nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
+7
View File
@@ -0,0 +1,7 @@
FROM node
WORKDIR /app
COPY app/package.json yarn.lock ./
RUN yarn install --frozen-lockfile
COPY app .
CMD [ "yarn", "dev:docker", "--host", "0.0.0.0" ]
+1
View File
@@ -6,6 +6,7 @@
"scripts": { "scripts": {
"dev": "API_TARGET=https://odyssey.wancat.cc vite", "dev": "API_TARGET=https://odyssey.wancat.cc vite",
"dev:local": "vite", "dev:local": "vite",
"dev:docker": "API_TARGET=http://backend:3000 vite",
"build": "vite build", "build": "vite build",
"preview": "vite preview" "preview": "vite preview"
}, },
+1 -1
View File
@@ -1,7 +1,7 @@
import axios from 'axios' import axios from 'axios'
const api = axios.create({ const api = axios.create({
baseURL: '/api', baseURL: '/api/v1',
}) })
export default api export default api
+1 -2
View File
@@ -7,9 +7,8 @@ export default defineConfig({
server: { server: {
proxy: { proxy: {
'/api': { '/api': {
target: `${process.env.API_TARGET || 'http://localhost:3000'}/api/v1`, target: process.env.API_TARGET || 'http://localhost:3000',
changeOrigin: true, changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
}, },
'/socket.io': { '/socket.io': {
target: process.env.API_TARGET || 'ws://localhost:3000', target: process.env.API_TARGET || 'ws://localhost:3000',
-5
View File
@@ -1,5 +0,0 @@
#!/bin/sh
containers=$(docker ps -a | grep 'quest-' | awk '{print $1}')
echo $containers
docker rm -f $containers
+25
View File
@@ -0,0 +1,25 @@
server {
listen 80;
location / {
root /usr/share/nginx/html;
index index.html;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:3000;
}
location /api-docs/ {
proxy_pass http://backend:3000;
}
location /socket.io/ {
proxy_pass http://backend:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
}
}
-7
View File
@@ -1,7 +0,0 @@
version: '3'
services:
helloworld:
image: lancatlin/linux-odyssey:helloworld
build:
context: .
dockerfile: server/quests/helloworld/Dockerfile
+17 -4
View File
@@ -1,16 +1,23 @@
version: '3' version: '3'
services: services:
app: app:
image: lancatlin/linux-odyssey image: lancatlin/linux-odyssey:app
build:
context: .
dockerfile: app/Dockerfile
networks:
internal:
ports:
- 8080:80
backend:
image: lancatlin/linux-odyssey:backend
restart: on-failure restart: on-failure
build: build:
context: . context: .
dockerfile: Dockerfile dockerfile: server/Dockerfile
networks: networks:
- internal - internal
- players - players
ports:
- '3000:3000'
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
environment: environment:
@@ -33,6 +40,12 @@ services:
- MONGO_PASS=user-password - MONGO_PASS=user-password
- MONGO_DB=odyssey-test - MONGO_DB=odyssey-test
helloworld:
image: lancatlin/linux-odyssey:helloworld
build:
context: .
dockerfile: quests/helloworld/Dockerfile
networks: networks:
internal: internal:
players: players:
+21 -2
View File
@@ -1,10 +1,20 @@
version: '3' version: '3'
services: services:
app: app:
build:
context: .
dockerfile: app/Dockerfile.dev
ports:
- 5173:5173
networks:
- internal
volumes:
- ./app/src:/app/src
backend:
restart: on-failure restart: on-failure
build: build:
context: . context: .
dockerfile: Dockerfile.dev dockerfile: server/Dockerfile.dev
networks: networks:
- internal - internal
- players - players
@@ -12,10 +22,13 @@ services:
- '3000:3000' - '3000:3000'
volumes: volumes:
- /var/run/docker.sock:/var/run/docker.sock - /var/run/docker.sock:/var/run/docker.sock
- ./server:/app/server - ./server/src:/app/src
- ./server/swagger.yaml:/app/swagger.yaml
- ./quests:/app/quests
environment: environment:
- MONGO_URL=mongodb://db:27017/odyssey-test - MONGO_URL=mongodb://db:27017/odyssey-test
- DOCKER_NETWORK=linux-odyssey-players - DOCKER_NETWORK=linux-odyssey-players
- HOST_PWD=${PWD}
db: db:
image: mongo image: mongo
restart: always restart: always
@@ -35,6 +48,12 @@ services:
environment: environment:
- SWAGGER_FILE=/tmp/swagger.yaml - SWAGGER_FILE=/tmp/swagger.yaml
helloworld:
image: lancatlin/linux-odyssey:helloworld
build:
context: .
dockerfile: quests/helloworld/Dockerfile
networks: networks:
internal: internal:
players: players:
+17
View File
@@ -0,0 +1,17 @@
#!/bin/sh
inspect() {
# default to app, allow overriding by $1
SERVICE=${1:-app}
echo "Running docker-compose logs for service [$SERVICE]..."
docker compose logs $SERVICE -f --no-log-prefix
}
clean() {
containers=$(docker ps -a | grep 'quest-' | awk '{print $1}')
echo $containers
docker rm -f $containers
}
$@
-2
View File
@@ -1,2 +0,0 @@
#!/bin/sh
docker compose logs app -f --no-log-prefix
File renamed without changes.
@@ -22,6 +22,6 @@ USER rudeus
WORKDIR /home/rudeus WORKDIR /home/rudeus
COPY ./server/quests/helloworld/home /home/rudeus/ COPY ./quests/helloworld/home /home/rudeus/
CMD [ "/bin/zsh" ] CMD [ "/bin/zsh" ]
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+2 -5
View File
@@ -1,15 +1,12 @@
FROM node FROM node
WORKDIR /app WORKDIR /app
COPY package.json yarn.lock ./ COPY server/package.json yarn.lock ./
COPY server/package.json ./server/
RUN yarn install --frozen-lockfile --production RUN yarn install --frozen-lockfile --production
WORKDIR /app/server
COPY server/src ./src COPY server/src ./src
COPY server/quests ./quests
COPY server/swagger.yaml . COPY server/swagger.yaml .
COPY quests ./quests
ENV NODE_ENV=production ENV NODE_ENV=production
ENV HOST=0.0.0.0 ENV HOST=0.0.0.0
+1 -4
View File
@@ -1,12 +1,9 @@
FROM node FROM node
WORKDIR /app WORKDIR /app
COPY package.json yarn.lock ./ COPY server/package.json yarn.lock ./
COPY server/package.json ./server/
RUN yarn install --frozen-lockfile RUN yarn install --frozen-lockfile
WORKDIR /app/server
ARG DOCKER_GID=140 ARG DOCKER_GID=140
RUN groupadd -g $DOCKER_GID docker && usermod -aG docker node RUN groupadd -g $DOCKER_GID docker && usermod -aG docker node
+1 -1
View File
@@ -1,5 +1,5 @@
import { Server } from 'socket.io' import { Server } from 'socket.io'
import { getOrCreateContainer, attachContainer } from '../utils/docker.js' import { getOrCreateContainer, attachContainer } from '../containers/docker.js'
import Session from '../models/session.js' import Session from '../models/session.js'
import { defaultUser, genSessionJWT } from '../utils/auth.js' import { defaultUser, genSessionJWT } from '../utils/auth.js'
+1
View File
@@ -7,4 +7,5 @@ export default {
jwtSecret: get('JWT_SECRET', 'secret'), jwtSecret: get('JWT_SECRET', 'secret'),
dockerNetwork: get('DOCKER_NETWORK', 'linux-odyssey-players'), dockerNetwork: get('DOCKER_NETWORK', 'linux-odyssey-players'),
isProduction: process.env.NODE_ENV === 'production', isProduction: process.env.NODE_ENV === 'production',
hostPwd: get('HOST_PWD', ''),
} }
@@ -3,8 +3,6 @@ import config from '../config.js'
const engine = new Docker() const engine = new Docker()
const projectPath = '/home/zeko/src/linux-odyssey'
const containerOptions = { const containerOptions = {
Image: 'lancatlin/linux-odyssey:helloworld', Image: 'lancatlin/linux-odyssey:helloworld',
AttachStdin: true, AttachStdin: true,
@@ -14,11 +12,12 @@ const containerOptions = {
OpenStdin: true, OpenStdin: true,
StdinOnce: false, StdinOnce: false,
HostConfig: { HostConfig: {
Binds: config.isProduction Binds:
config.isProduction && config.hostPwd
? [] ? []
: [ : [
`${projectPath}/server/quests/helloworld/home:/home/rudeus`, `${config.hostPwd}/quests/helloworld/home:/home/rudeus`,
`${projectPath}/packages/container:/usr/local/lib/container`, `${config.hostPwd}/packages/container:/usr/local/lib/container`,
], ],
}, },
} }
@@ -60,7 +59,7 @@ export async function attachContainer(container, { token }) {
AttachStderr: true, AttachStderr: true,
Cmd: ['/bin/zsh'], Cmd: ['/bin/zsh'],
Tty: true, Tty: true,
Env: [`TOKEN=${token}`, `API_ENDPOINT=http://app:3000`], Env: [`TOKEN=${token}`, `API_ENDPOINT=http://backend:3000`],
}) })
const execOutput = await exec.start({ const execOutput = await exec.start({
+1 -1
View File
@@ -4269,7 +4269,7 @@ socket.io-adapter@~2.5.2:
dependencies: dependencies:
ws "~8.11.0" ws "~8.11.0"
socket.io-client@^4.7.2: socket.io-client@^4.7.1, socket.io-client@^4.7.2:
version "4.7.2" version "4.7.2"
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.7.2.tgz#f2f13f68058bd4e40f94f2a1541f275157ff2c08" resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.7.2.tgz#f2f13f68058bd4e40f94f2a1541f275157ff2c08"
integrity sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w== integrity sha512-vtA0uD4ibrYD793SOIAwlo8cj6haOeMHrGvwPxJsxH7CeIksqJ+3Zc06RvWTIFgiSqx4A3sOnTXpfAEE2Zyz6w==