3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-03-15 05:41:51 +00:00

Simplify dev docker setup

This commit is contained in:
Dragory 2022-06-26 19:30:46 +03:00
parent b655085115
commit ce2255b6b7
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
13 changed files with 65 additions and 97 deletions

View file

@ -1,36 +1,39 @@
KEY=32_character_encryption_key # 32 character encryption key
KEY=
# Values from the Discord developer portal
CLIENT_ID= CLIENT_ID=
CLIENT_SECRET= CLIENT_SECRET=
BOT_TOKEN= BOT_TOKEN=
OAUTH_CALLBACK_URL= DASHBOARD_URL=https://localhost:3300
DASHBOARD_DOMAIN= API_URL=https://localhost:3300/api
API_DOMAIN=
# When using the Docker-based development environment, this is only used internally. The API will be available at localhost:DOCKER_DEV_WEB_PORT/api.
API_PORT=3000 API_PORT=3000
# Only required if relevant feature is used
#PHISHERMAN_API_KEY=
# #
# DOCKER (DEVELOPMENT) # DOCKER (DEVELOPMENT)
# #
DOCKER_WEB_PORT=443 DOCKER_DEV_WEB_PORT=3300
# The MySQL database running in the container is exposed to the host on this port, # The MySQL database running in the container is exposed to the host on this port,
# allowing access with database tools such as DBeaver # allowing access with database tools such as DBeaver
DOCKER_MYSQL_PORT=3001 DOCKER_DEV_MYSQL_PORT=3001
# Password for the Zeppelin database user # Password for the Zeppelin database user
DOCKER_MYSQL_PASSWORD= DOCKER_DEV_MYSQL_PASSWORD=
# Password for the MySQL root user # Password for the MySQL root user
DOCKER_MYSQL_ROOT_PASSWORD= DOCKER_DEV_MYSQL_ROOT_PASSWORD=
# The development environment container has an SSH server that you can connect to. # The development environment container has an SSH server that you can connect to.
# This is the port that server is exposed to the host on. # This is the port that server is exposed to the host on.
DOCKER_DEV_SSH_PORT=3002 DOCKER_DEV_SSH_PORT=3002
DOCKER_DEV_SSH_PASSWORD=password DOCKER_DEV_SSH_PASSWORD=password
# Only required if relevant feature is used
#PHISHERMAN_API_KEY=
# #
# PRODUCTION # PRODUCTION
# #

View file

@ -88,7 +88,7 @@ export function initAuth(app: express.Express) {
tokenURL: "https://discord.com/api/oauth2/token", tokenURL: "https://discord.com/api/oauth2/token",
clientID: env.CLIENT_ID, clientID: env.CLIENT_ID,
clientSecret: env.CLIENT_SECRET, clientSecret: env.CLIENT_SECRET,
callbackURL: env.OAUTH_CALLBACK_URL, callbackURL: `${env.API_URL}/auth/oauth-callback`,
scope: ["identify"], scope: ["identify"],
}, },
async (accessToken, refreshToken, profile, cb) => { async (accessToken, refreshToken, profile, cb) => {
@ -117,9 +117,9 @@ export function initAuth(app: express.Express) {
passport.authenticate("oauth2", { failureRedirect: "/", session: false }), passport.authenticate("oauth2", { failureRedirect: "/", session: false }),
(req: Request, res: Response) => { (req: Request, res: Response) => {
if (req.user && req.user.apiKey) { if (req.user && req.user.apiKey) {
res.redirect(`https://${env.DASHBOARD_DOMAIN}/login-callback/?apiKey=${req.user.apiKey}`); res.redirect(`${env.DASHBOARD_URL}/login-callback/?apiKey=${req.user.apiKey}`);
} else { } else {
res.redirect(`https://${env.DASHBOARD_DOMAIN}/login-callback/?error=noAccess`); res.redirect(`${env.DASHBOARD_URL}/login-callback/?error=noAccess`);
} }
}, },
); );

View file

@ -14,7 +14,7 @@ const app = express();
app.use( app.use(
cors({ cors({
origin: `https://${env.DASHBOARD_DOMAIN}`, origin: env.DASHBOARD_URL,
}), }),
); );
app.use( app.use(

View file

@ -11,17 +11,15 @@ const envType = z.object({
CLIENT_SECRET: z.string().length(32), CLIENT_SECRET: z.string().length(32),
BOT_TOKEN: z.string().min(50), BOT_TOKEN: z.string().min(50),
OAUTH_CALLBACK_URL: z.string().url(), DASHBOARD_URL: z.string().url(),
DASHBOARD_DOMAIN: z.string(), API_URL: z.string().url(),
API_DOMAIN: z.string(), API_PORT: z.preprocess((v) => Number(v), z.number().min(1).max(65535)).default(3000),
STAFF: z.preprocess((v) => String(v).split(","), z.array(z.string())).optional(), STAFF: z.preprocess((v) => String(v).split(","), z.array(z.string())).optional(),
PHISHERMAN_API_KEY: z.string().optional(), PHISHERMAN_API_KEY: z.string().optional(),
API_PORT: z.preprocess((v) => Number(v), z.number().min(1).max(65535)), DOCKER_DEV_MYSQL_PASSWORD: z.string().optional(), // Included here for the DB_PASSWORD default in development
DOCKER_MYSQL_PASSWORD: z.string().optional(), // Included here for the DB_PASSWORD default in development
DB_HOST: z.string().optional().default("mysql"), DB_HOST: z.string().optional().default("mysql"),
DB_PORT: z DB_PORT: z
@ -42,6 +40,6 @@ if (fs.existsSync(envPath)) {
export const env = envType.parse(toValidate); export const env = envType.parse(toValidate);
if (env.DOCKER_MYSQL_PASSWORD && !env.DB_PASSWORD) { if (env.DOCKER_DEV_MYSQL_PASSWORD && !env.DB_PASSWORD) {
env.DB_PASSWORD = env.DOCKER_MYSQL_PASSWORD; env.DB_PASSWORD = env.DOCKER_DEV_MYSQL_PASSWORD;
} }

View file

@ -1,5 +1,5 @@
import { RootStore } from "./store"; import { RootStore } from "./store";
const apiUrl = `https://${process.env.API_DOMAIN}`; const apiUrl = process.env.API_URL;
type QueryParamObject = { [key: string]: string | null }; type QueryParamObject = { [key: string]: string | null };

View file

@ -11,7 +11,7 @@ const isAuthenticated = async () => {
export const authGuard: NavigationGuard = async (to, from, next) => { export const authGuard: NavigationGuard = async (to, from, next) => {
if (await isAuthenticated()) return next(); if (await isAuthenticated()) return next();
window.location.href = `https://${process.env.API_DOMAIN}/auth/login`; window.location.href = `${process.env.API_URL}/auth/login`;
}; };
export const loginCallbackGuard: NavigationGuard = async (to, from, next) => { export const loginCallbackGuard: NavigationGuard = async (to, from, next) => {
@ -25,5 +25,5 @@ export const loginCallbackGuard: NavigationGuard = async (to, from, next) => {
export const authRedirectGuard: NavigationGuard = async (to, form, next) => { export const authRedirectGuard: NavigationGuard = async (to, form, next) => {
if (await isAuthenticated()) return next("/dashboard"); if (await isAuthenticated()) return next("/dashboard");
window.location.href = `https://${process.env.API_DOMAIN}/auth/login`; window.location.href = `${process.env.API_URL}/auth/login`;
}; };

View file

@ -20,7 +20,7 @@ Vue.mixin({
return { return {
get env() { get env() {
return Object.freeze({ return Object.freeze({
API_URL: `https://${process.env.API_DOMAIN}`, API_URL: process.env.API_URL,
}); });
}, },
}; };

View file

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
DOCKER_UID="$(id -u)" DOCKER_GID="$(id -g)" docker-compose --env-file ./.env -f ./docker/development/docker-compose.yml "$@" DOCKER_UID="$(id -u)" DOCKER_STAY_RUNNING=1 docker-compose --env-file ./.env -f ./docker/development/docker-compose.yml "$@"

View file

@ -7,7 +7,7 @@
## Connecting with VSCode ## Connecting with VSCode
1. Install the `Remote - SSH` plugin 1. Install the `Remote - SSH` plugin
2. Run `Remote-SSH: Connect to Host...` 2. Run `Remote-SSH: Connect to Host...`
* As the address, use `ubuntu@127.0.0.1:3002` where `3002` matches `DOCKER_DEV_SSH_PORT` in `.env` * As the address, use `ubuntu@127.0.0.1:3002` (where `3002` matches `DOCKER_DEV_SSH_PORT` in `.env`)
* Use the password specified in `.env` as `DOCKER_DEV_SSH_PASSWORD` * Use the password specified in `.env` as `DOCKER_DEV_SSH_PASSWORD`
3. Once connected, click `Open folder...` and select `/home/ubuntu/zeppelin` 3. Once connected, click `Open folder...` and select `/home/ubuntu/zeppelin`
@ -25,3 +25,6 @@ These commands are run inside the dev container. You should be able to just open
1. `cd ~/zeppelin/dashboard` 1. `cd ~/zeppelin/dashboard`
2. `npm ci` 2. `npm ci`
3. `npm run watch-build` 3. `npm run watch-build`
## Opening the dashboard
Browse to https://localhost:3300 to view the dashboard

View file

@ -1,6 +1,6 @@
FROM ubuntu:20.04 FROM ubuntu:20.04
ARG DOCKER_UID ARG DOCKER_UID=1000
ARG DOCKER_DEV_SSH_PASSWORD ARG DOCKER_DEV_SSH_PASSWORD
ENV DEBIAN_FRONTEND=noninteractive ENV DEBIAN_FRONTEND=noninteractive
@ -13,7 +13,7 @@ RUN apt-get install -y sudo git curl
# Set up SSH access # Set up SSH access
RUN apt-get install -y openssh-server iptables RUN apt-get install -y openssh-server iptables
RUN mkdir /var/run/sshd RUN mkdir /var/run/sshd
RUN useradd -rm -d /home/ubuntu -s /bin/bash -g root -G sudo -u "${DOCKER_UID}" ubuntu RUN useradd -rm -d /home/ubuntu -s /bin/bash -g root -G sudo -u $DOCKER_UID ubuntu
RUN echo "ubuntu:${DOCKER_DEV_SSH_PASSWORD}" | chpasswd RUN echo "ubuntu:${DOCKER_DEV_SSH_PASSWORD}" | chpasswd
# Set up proper permissions for volumes # Set up proper permissions for volumes

View file

@ -9,54 +9,33 @@ services:
build: build:
context: ./nginx context: ./nginx
args: args:
API_DOMAIN: ${API_DOMAIN:?Missing API_DOMAIN} DOCKER_DEV_WEB_PORT: ${DOCKER_DEV_WEB_PORT:?Missing DOCKER_DEV_WEB_PORT}
API_PORT: ${API_PORT:?Missing API_PORT} API_PORT: ${API_PORT:?Missing API_PORT}
DASHBOARD_DOMAIN: ${DASHBOARD_DOMAIN:?Missing DASHBOARD_DOMAIN}
ports: ports:
- ${DOCKER_WEB_PORT:?Missing DOCKER_WEB_PORT}:443 - "${DOCKER_DEV_WEB_PORT:?Missing DOCKER_DEV_WEB_PORT}:443"
volumes: volumes:
- ../../:/zeppelin - ../../:/zeppelin
mysql: mysql:
image: mysql:8.0 image: mysql:8.0
environment: environment:
MYSQL_ROOT_PASSWORD: ${DOCKER_MYSQL_ROOT_PASSWORD?:Missing DOCKER_MYSQL_ROOT_PASSWORD} MYSQL_ROOT_PASSWORD: ${DOCKER_DEV_MYSQL_ROOT_PASSWORD?:Missing DOCKER_DEV_MYSQL_ROOT_PASSWORD}
MYSQL_DATABASE: zeppelin MYSQL_DATABASE: zeppelin
MYSQL_USER: zeppelin MYSQL_USER: zeppelin
MYSQL_PASSWORD: ${DOCKER_MYSQL_PASSWORD?:Missing DOCKER_MYSQL_PASSWORD} MYSQL_PASSWORD: ${DOCKER_DEV_MYSQL_PASSWORD?:Missing DOCKER_DEV_MYSQL_PASSWORD}
ports: ports:
- ${DOCKER_MYSQL_PORT:?Missing DOCKER_MYSQL_PORT}:3306 - ${DOCKER_DEV_MYSQL_PORT:?Missing DOCKER_DEV_MYSQL_PORT}:3306
volumes: volumes:
- mysql-data:/var/lib/mysql - mysql-data:/var/lib/mysql
command: --authentication-policy=mysql_native_password command: --authentication-policy=mysql_native_password
#
# backend:
# image: node:16
# user: "${UID:?Missing UID}:${GID:?Missing GID}"
# working_dir: /zeppelin/backend
# restart: always
# depends_on:
# - mysql
# volumes:
# - ./:/zeppelin
# command: sh -c "npm run migrate-dev && npm run watch"
#
# dashboard:
# image: node:16
# user: "${UID:?Missing UID}:${GID:?Missing GID}"
# working_dir: /zeppelin/dashboard
# restart: always
# volumes:
# - ./:/zeppelin
# command: sh -c "npm run watch-build"
devenv: devenv:
build: build:
context: ./devenv context: ./devenv
args: args:
DOCKER_UID: ${DOCKER_UID:?Missing DOCKER_UID}
DOCKER_GID: ${DOCKER_GID:?Missing DOCKER_GID}
DOCKER_DEV_SSH_PASSWORD: ${DOCKER_DEV_SSH_PASSWORD:?Missing DOCKER_DEV_SSH_PASSWORD} DOCKER_DEV_SSH_PASSWORD: ${DOCKER_DEV_SSH_PASSWORD:?Missing DOCKER_DEV_SSH_PASSWORD}
DOCKER_UID: ${DOCKER_UID:?Missing DOCKER_UID}
DOCKER_STAY_RUNNING: ${DOCKER_STAY_RUNNING}
ports: ports:
- "${DOCKER_DEV_SSH_PORT:?Missing DOCKER_DEV_SSH_PORT}:22" - "${DOCKER_DEV_SSH_PORT:?Missing DOCKER_DEV_SSH_PORT}:22"
volumes: volumes:

View file

@ -1,14 +1,11 @@
FROM nginx FROM nginx
ARG API_DOMAIN
ARG DASHBOARD_DOMAIN
ARG API_PORT ARG API_PORT
ARG DOCKER_DEV_API_PORT
ARG DOCKER_DEV_DASHBOARD_PORT
RUN apt-get update && apt-get install -y openssl RUN apt-get update && apt-get install -y openssl
RUN openssl req -x509 -newkey rsa:4096 -keyout /etc/ssl/private/api-cert.key -out /etc/ssl/certs/api-cert.pem -days 3650 -subj '/CN=*.${API_DOMAIN}' -nodes RUN openssl req -x509 -newkey rsa:4096 -keyout /etc/ssl/private/localhost-cert.key -out /etc/ssl/certs/localhost-cert.pem -days 3650 -subj '/CN=localhost' -nodes
RUN openssl req -x509 -newkey rsa:4096 -keyout /etc/ssl/private/dashboard-cert.key -out /etc/ssl/certs/dashboard-cert.pem -days 3650 -subj '/CN=*.${DASHBOARD_DOMAIN}' -nodes
COPY ./default.conf /etc/nginx/conf.d/default.conf COPY ./default.conf /etc/nginx/conf.d/default.conf
RUN sed -ir "s/_API_DOMAIN_/$(echo ${API_DOMAIN} | sed 's/\./\\./g')/g" /etc/nginx/conf.d/default.conf
RUN sed -ir "s/_DASHBOARD_DOMAIN_/$(echo ${DASHBOARD_DOMAIN} | sed 's/\./\\./g')/g" /etc/nginx/conf.d/default.conf
RUN sed -ir "s/_API_PORT_/${API_PORT}/g" /etc/nginx/conf.d/default.conf RUN sed -ir "s/_API_PORT_/${API_PORT}/g" /etc/nginx/conf.d/default.conf

View file

@ -1,36 +1,7 @@
server { server {
listen 443 ssl http2; listen 443 ssl http2;
listen [::]:443 ssl http2; listen [::]:443 ssl http2;
server_name _API_DOMAIN_; server_name localhost;
location / {
# Using a variable here stops nginx from crashing if the dev container is restarted or becomes otherwise unavailable
set $backend_upstream "http://devenv:_API_PORT_";
# Using a variable in proxy_pass also requires resolver to be set.
# This is the address of the internal docker compose DNS server.
resolver 127.0.0.11;
proxy_pass $backend_upstream;
client_max_body_size 200M;
}
ssl_certificate /etc/ssl/certs/api-cert.pem;
ssl_certificate_key /etc/ssl/private/api-cert.key;
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m;
ssl_session_tickets off;
ssl_protocols TLSv1.3;
ssl_prefer_server_ciphers off;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name _DASHBOARD_DOMAIN_;
root /zeppelin/dashboard/dist; root /zeppelin/dashboard/dist;
@ -39,8 +10,25 @@ server {
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
} }
ssl_certificate /etc/ssl/certs/dashboard-cert.pem; # Using a variable here stops nginx from crashing if the dev container is restarted or becomes otherwise unavailable
ssl_certificate_key /etc/ssl/private/dashboard-cert.key; set $backend_upstream "http://devenv:_API_PORT_";
location /api {
# Remove /api/ from the beginning when passing the path to the API process
rewrite /api(/.*)$ $1 break;
# Using a variable in proxy_pass also requires resolver to be set.
# This is the address of the internal docker compose DNS server.
resolver 127.0.0.11;
proxy_pass $backend_upstream$uri$is_args$args;
proxy_redirect off;
client_max_body_size 200M;
}
ssl_certificate /etc/ssl/certs/localhost-cert.pem;
ssl_certificate_key /etc/ssl/private/localhost-cert.key;
ssl_session_timeout 1d; ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; ssl_session_cache shared:MozSSL:10m;