WIP: System-api in docker container

This commit is contained in:
Nicolas Meienberger 2022-05-16 23:30:08 +02:00
parent 9901d480b7
commit 0e7b0a0a3e
14 changed files with 108 additions and 32 deletions

34
.github/workflows/build-images.yml vendored Normal file
View File

@ -0,0 +1,34 @@
name: Docker build
on:
push:
branches:
- 'master'
jobs:
docker:
runs-on: ubuntu-latest
steps:
-
name: Checkout
uses: actions/checkout@v3
-
name: Set up QEMU
uses: docker/setup-qemu-action@v1
-
name: Set up Docker Buildx
uses: docker/setup-buildx-action@v1
-
name: Login to DockerHub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
-
name: Build and push
uses: docker/build-push-action@v2
with:
context: ./packages/dashboard
platforms: linux/amd64,linux/arm64
push: true
tags: meienberger/tipi-dashboard:latest

1
.gitignore vendored
View File

@ -1,6 +1,7 @@
.pnpm-debug.log .pnpm-debug.log
.env .env
.env* .env*
github.secrets
node_modules/ node_modules/
nginx/* nginx/*
letsencrypt/* letsencrypt/*

View File

@ -13,21 +13,33 @@ services:
- /var/run/docker.sock:/var/run/docker.sock:ro - /var/run/docker.sock:/var/run/docker.sock:ro
- ${PWD}/traefik:/root/.config - ${PWD}/traefik:/root/.config
networks: networks:
- tipi_main_network tipi_main_network:
ipv4_address: 10.21.21.2
api:
image: meienberger/tipi-api:latest
container_name: api
ports:
- 3001:3001
volumes:
## Docker sock
- /var/run/docker.sock:/var/run/docker.sock:ro
- ${PWD}:/tipi
networks:
tipi_main_network:
ipv4_address: 10.21.21.3
dashboard: dashboard:
build: image: meienberger/tipi-dashboard:latest
context: ./packages/dashboard
dockerfile: Dockerfile
args:
INTERNAL_IP_ARG: ${INTERNAL_IP}
container_name: dashboard container_name: dashboard
volumes:
- ${PWD}/state:/app/state
ports: ports:
- 3000:3000 - 3000:3000
networks: networks:
- tipi_main_network tipi_main_network:
ipv4_address: 10.21.21.4
environment:
- INTERNAL_IP=${INTERNAL_IP}
labels: labels:
traefik.enable: true traefik.enable: true
traefik.http.routers.dashboard.rule: PathPrefix("/") # Host(`tipi.local`) && traefik.http.routers.dashboard.rule: PathPrefix("/") # Host(`tipi.local`) &&

View File

@ -4,7 +4,9 @@
"description": "A homeserver for everyone", "description": "A homeserver for everyone",
"scripts": { "scripts": {
"prepare": "husky install", "prepare": "husky install",
"act": "act --container-architecture linux/amd64 -j test-install" "act:test-install": "act --container-architecture linux/amd64 -j test-install",
"act:docker": "act --container-architecture linux/amd64 --secret-file github.secrets -j docker",
"docker:build": "docker build ./packages/system-api/ -t meienberger/tipi-api:latest && docker build ./packages/dashboard/ -t meienberger/tipi-dashboard:latest"
}, },
"dependencies": { "dependencies": {
"eslint": "^8.15.0", "eslint": "^8.15.0",

View File

@ -1,2 +1,3 @@
*.config.js *.config.js
.eslintrc.js .eslintrc.js
next.config.js

View File

@ -8,9 +8,6 @@ RUN yarn
COPY ./ ./ COPY ./ ./
ARG INTERNAL_IP_ARG
ENV INTERNAL_IP $INTERNAL_IP_ARG
RUN yarn build RUN yarn build
CMD ["yarn", "start"] CMD ["yarn", "start"]

View File

@ -2,7 +2,7 @@
const { NODE_ENV, INTERNAL_IP } = process.env; const { NODE_ENV, INTERNAL_IP } = process.env;
const nextConfig = { const nextConfig = {
reactStrictMode: true, reactStrictMode: false,
env: { env: {
INTERNAL_IP: NODE_ENV === 'development' ? 'localhost' : INTERNAL_IP, INTERNAL_IP: NODE_ENV === 'development' ? 'localhost' : INTERNAL_IP,
}, },

View File

@ -1,6 +1,6 @@
import axios, { Method } from 'axios'; import axios, { Method } from 'axios';
export const BASE_URL = `http://${process.env.INTERNAL_IP}:3001`; export const BASE_URL = 'http://localhost:3001';
interface IFetchParams { interface IFetchParams {
endpoint: string; endpoint: string;

View File

@ -0,0 +1,2 @@
node_modules/
dist/

View File

@ -0,0 +1,38 @@
FROM ubuntu:20.04
ARG DEBIAN_FRONTEND=noninteractive
WORKDIR /app
# Install docker
RUN apt-get update && apt-get install -y \
ca-certificates \
curl \
gnupg \
lsb-release
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
RUN echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
RUN apt-get update
RUN apt-get install -y docker-ce docker-ce-cli containerd.io
# Install node
RUN curl -sL https://deb.nodesource.com/setup_14.x | bash -
RUN apt-get install -y nodejs
# Install docker-compose
RUN curl -L "https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
RUN chmod +x /usr/local/bin/docker-compose
COPY ./package.json ./
RUN npm install
COPY ./ ./
RUN npm run build
CMD ["npm", "run", "start"]

View File

@ -12,7 +12,7 @@
"lint": "eslint . --ext .ts", "lint": "eslint . --ext .ts",
"test": "jest", "test": "jest",
"test:watch": "jest --watch", "test:watch": "jest --watch",
"build-prod": "esbuild --bundle src/server.ts --outdir=dist --allow-overwrite --sourcemap --platform=node --minify --analyze=verbose --external:./node_modules/* --format=esm", "build": "esbuild --bundle src/server.ts --outdir=dist --allow-overwrite --sourcemap --platform=node --minify --analyze=verbose --external:./node_modules/* --format=esm",
"build:watch": "esbuild --bundle src/server.ts --outdir=dist --allow-overwrite --sourcemap --platform=node --external:./node_modules/* --format=esm --watch", "build:watch": "esbuild --bundle src/server.ts --outdir=dist --allow-overwrite --sourcemap --platform=node --external:./node_modules/* --format=esm --watch",
"start:dev": "NODE_ENV=development nodemon --trace-deprecation --trace-warnings --watch dist dist/server.js", "start:dev": "NODE_ENV=development nodemon --trace-deprecation --trace-warnings --watch dist dist/server.js",
"dev": "concurrently \"yarn build:watch\" \"yarn start:dev\"", "dev": "concurrently \"yarn build:watch\" \"yarn start:dev\"",
@ -22,7 +22,6 @@
"license": "ISC", "license": "ISC",
"dependencies": { "dependencies": {
"argon2": "^0.28.5", "argon2": "^0.28.5",
"bcrypt": "^5.0.1",
"compression": "^1.7.4", "compression": "^1.7.4",
"cookie-parser": "^1.4.6", "cookie-parser": "^1.4.6",
"cors": "^2.8.5", "cors": "^2.8.5",
@ -44,7 +43,6 @@
"tcp-port-used": "^1.0.2" "tcp-port-used": "^1.0.2"
}, },
"devDependencies": { "devDependencies": {
"@types/bcrypt": "^5.0.0",
"@types/compression": "^1.7.2", "@types/compression": "^1.7.2",
"@types/cookie-parser": "^1.4.3", "@types/cookie-parser": "^1.4.3",
"@types/cors": "^2.8.12", "@types/cors": "^2.8.12",

View File

@ -9,21 +9,13 @@ interface IConfig {
dotenv.config(); dotenv.config();
const { NODE_ENV = 'development', ROOT_FOLDER = '', JWT_SECRET = '', INTERNAL_IP = '' } = process.env; const { NODE_ENV = 'development', JWT_SECRET = '' } = process.env;
const missing = [];
if (!ROOT_FOLDER) missing.push('ROOT_FOLDER');
if (missing.length > 0) {
throw new Error(`Missing environment variables: ${missing.join(', ')}`);
}
const config: IConfig = { const config: IConfig = {
NODE_ENV, NODE_ENV,
ROOT_FOLDER, ROOT_FOLDER: '/tipi',
JWT_SECRET, JWT_SECRET,
CLIENT_URLS: ['http://locahost:3000', `http://${INTERNAL_IP}`, `http://${INTERNAL_IP}:3000`], CLIENT_URLS: ['http://locahost:3000', 'http://10.21.21.4', 'http://10.21.21.4:3000'],
}; };
export default config; export default config;

View File

@ -1,5 +1,4 @@
import fs from 'fs'; import fs from 'fs';
// import bcrypt from 'bcrypt';
import jsonwebtoken from 'jsonwebtoken'; import jsonwebtoken from 'jsonwebtoken';
import * as argon2 from 'argon2'; import * as argon2 from 'argon2';
import config from '../../../config'; import config from '../../../config';

View File

@ -30,7 +30,7 @@ const register = async (email: string, password: string, name: string) => {
throw new Error('User already exists'); throw new Error('User already exists');
} }
const hash = await argon2.hash(password); // bcrypt.hash(password, 10); const hash = await argon2.hash(password);
const newuser: IUser = { email, name, password: hash }; const newuser: IUser = { email, name, password: hash };
const token = await AuthHelpers.getJwtToken(newuser, password); const token = await AuthHelpers.getJwtToken(newuser, password);