Added ARM support
This commit is contained in:
15
.github/workflows/docker-image.yml
vendored
15
.github/workflows/docker-image.yml
vendored
@@ -29,14 +29,14 @@ jobs:
|
|||||||
npm ci
|
npm ci
|
||||||
npm run build
|
npm run build
|
||||||
|
|
||||||
- name: Setup Docker Buildx
|
- name: Setup QEMU
|
||||||
uses: docker/setup-buildx-action@v1
|
uses: docker/setup-qemu-action@v2
|
||||||
|
|
||||||
- name: Set up QEMU
|
- name: Setup Docker Buildx
|
||||||
uses: docker/setup-qemu-action@v1
|
uses: docker/setup-buildx-action@v2
|
||||||
|
|
||||||
- name: Login to Docker Registry
|
- name: Login to Docker Registry
|
||||||
uses: docker/login-action@v1
|
uses: docker/login-action@v2
|
||||||
with:
|
with:
|
||||||
registry: ghcr.io
|
registry: ghcr.io
|
||||||
username: ${{ github.actor }}
|
username: ${{ github.actor }}
|
||||||
@@ -52,12 +52,13 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
|
echo "IMAGE_TAG=$IMAGE_TAG" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Build and Push Docker Image
|
- name: Build and Push Multi-Arch Docker Image
|
||||||
uses: docker/build-push-action@v2
|
uses: docker/build-push-action@v4
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
file: ./docker/Dockerfile
|
file: ./docker/Dockerfile
|
||||||
push: true
|
push: true
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
tags: ghcr.io/${{ env.REPO_OWNER }}/termix:${{ env.IMAGE_TAG }}
|
tags: ghcr.io/${{ env.REPO_OWNER }}/termix:${{ env.IMAGE_TAG }}
|
||||||
labels: org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
labels: org.opencontainers.image.source=https://github.com/${{ github.repository }}
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,30 @@
|
|||||||
# Build everything in one stage
|
# Use Node.js base image for building frontend
|
||||||
FROM node:18-alpine
|
FROM --platform=$BUILDPLATFORM node:18-alpine AS builder
|
||||||
|
|
||||||
# Install nginx and dependencies
|
# Install dependencies
|
||||||
RUN apk add --no-cache nginx npm
|
RUN apk add --no-cache npm
|
||||||
|
|
||||||
# Set working directory
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
# Copy package files and install dependencies
|
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
RUN npm install
|
RUN npm install
|
||||||
|
|
||||||
# Copy the entire project (frontend and backend)
|
# Copy project files and build frontend
|
||||||
COPY ./ ./
|
COPY ./ ./
|
||||||
|
|
||||||
# Build the frontend
|
|
||||||
RUN npm run build
|
RUN npm run build
|
||||||
|
|
||||||
# Configure nginx
|
# Final stage with nginx
|
||||||
COPY docker/nginx.conf /etc/nginx/nginx.conf
|
FROM --platform=$TARGETPLATFORM nginx:alpine
|
||||||
|
|
||||||
# Copy built frontend to nginx's web directory
|
# Copy built frontend from builder stage
|
||||||
COPY ./dist /usr/share/nginx/html
|
COPY --from=builder /app/dist /usr/share/nginx/html
|
||||||
|
|
||||||
|
# Copy nginx config
|
||||||
|
COPY docker/nginx.conf /etc/nginx/nginx.conf
|
||||||
|
|
||||||
# Expose necessary ports
|
# Expose necessary ports
|
||||||
EXPOSE 8080
|
EXPOSE 8080
|
||||||
EXPOSE 8081
|
EXPOSE 8081
|
||||||
|
|
||||||
# Use entrypoint.sh to run both the backend and nginx
|
# Use entrypoint.sh to start backend and nginx
|
||||||
|
COPY --from=builder /app/src/backend/entrypoint.sh /app/src/backend/entrypoint.sh
|
||||||
RUN chmod +x /app/src/backend/entrypoint.sh
|
RUN chmod +x /app/src/backend/entrypoint.sh
|
||||||
ENTRYPOINT ["/app/src/backend/entrypoint.sh"]
|
ENTRYPOINT ["/app/src/backend/entrypoint.sh"]
|
||||||
17
src/App.css
17
src/App.css
@@ -44,6 +44,8 @@
|
|||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
padding: 4px;
|
padding: 4px;
|
||||||
flex-shrink: 0; /* Prevent tabs from shrinking */
|
flex-shrink: 0; /* Prevent tabs from shrinking */
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-item button {
|
.tab-item button {
|
||||||
@@ -54,13 +56,24 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.tab-item button:hover {
|
||||||
|
background: #1a1a1a;
|
||||||
|
border: white 1px solid;
|
||||||
|
}
|
||||||
|
|
||||||
.tab-close {
|
.tab-close {
|
||||||
padding: 2px 6px !important;
|
padding: 2px 6px !important;
|
||||||
border-radius: 50%;
|
border-radius: 20%;
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: center;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 1;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-close:hover {
|
.tab-close:hover {
|
||||||
background: #ff5555 !important;
|
background: #1a1a1a !important;
|
||||||
|
border: white 1px solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
.active-tab {
|
.active-tab {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import PropTypes from "prop-types";
|
|||||||
|
|
||||||
export function NewTerminal({ hostConfig }) {
|
export function NewTerminal({ hostConfig }) {
|
||||||
const terminalRef = useRef(null);
|
const terminalRef = useRef(null);
|
||||||
|
const socketRef = useRef(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!hostConfig || !terminalRef.current) return;
|
if (!hostConfig || !terminalRef.current) return;
|
||||||
@@ -46,8 +47,8 @@ export function NewTerminal({ hostConfig }) {
|
|||||||
fitAddon.fit();
|
fitAddon.fit();
|
||||||
const { cols, rows } = terminal;
|
const { cols, rows } = terminal;
|
||||||
|
|
||||||
if (socket) {
|
if (socketRef.current) {
|
||||||
socket.emit("resize", { cols, rows });
|
socketRef.current.emit("resize", { cols, rows });
|
||||||
console.log(`Terminal resized: cols=${cols}, rows=${rows}`);
|
console.log(`Terminal resized: cols=${cols}, rows=${rows}`);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -71,31 +72,36 @@ export function NewTerminal({ hostConfig }) {
|
|||||||
const isSecure = window.location.protocol === "https:";
|
const isSecure = window.location.protocol === "https:";
|
||||||
let ioUrl = `${isSecure ? "https" : "http"}://${window.location.hostname}:8081/socket.io/`;
|
let ioUrl = `${isSecure ? "https" : "http"}://${window.location.hostname}:8081/socket.io/`;
|
||||||
|
|
||||||
if(window.location.hostname === "localhost") {
|
if (window.location.hostname === "localhost") {
|
||||||
ioUrl = "http://localhost:8081";
|
ioUrl = "http://localhost:8081";
|
||||||
}
|
}
|
||||||
|
|
||||||
const socket = io(ioUrl);
|
const socket = io(ioUrl);
|
||||||
|
socketRef.current = socket;
|
||||||
|
|
||||||
|
socket.off("connect");
|
||||||
|
socket.off("data");
|
||||||
|
socket.off("disconnect");
|
||||||
|
|
||||||
// Emit hostConfig to start SSH connection
|
|
||||||
socket.on("connect", () => {
|
socket.on("connect", () => {
|
||||||
fitAddon.fit();
|
fitAddon.fit();
|
||||||
resizeTerminal(); // Ensure proper size on connection
|
resizeTerminal(); // Ensure proper size on connection
|
||||||
const { cols, rows } = terminal;
|
const { cols, rows } = terminal;
|
||||||
socket.emit("connectToHost", cols, rows, hostConfig);
|
socket.emit("connectToHost", cols, rows, hostConfig);
|
||||||
terminal.write("\r\n*** Connected to backend ***\r\n");
|
terminal.write("\r\n*** Connected to backend ***\r\n");
|
||||||
|
});
|
||||||
|
|
||||||
terminal.onKey((key) => {
|
socket.on("data", (data) => {
|
||||||
socket.emit("data", key.key);
|
terminal.write(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("data", (data) => {
|
socket.on("disconnect", () => {
|
||||||
terminal.write(data);
|
terminal.write("\r\n*** Disconnected from backend ***\r\n");
|
||||||
});
|
});
|
||||||
|
|
||||||
socket.on("disconnect", () => {
|
// Capture and send keystrokes
|
||||||
terminal.write("\r\n*** Disconnected from backend ***\r\n");
|
terminal.onKey(({ key }) => {
|
||||||
});
|
socket.emit("data", key);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Cleanup on component unmount
|
// Cleanup on component unmount
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ button {
|
|||||||
transition: border-color 0.25s;
|
transition: border-color 0.25s;
|
||||||
}
|
}
|
||||||
button:hover {
|
button:hover {
|
||||||
border-color: #646cff;
|
border-color: #ffffff;
|
||||||
}
|
}
|
||||||
button:focus,
|
button:focus,
|
||||||
button:focus-visible {
|
button:focus-visible {
|
||||||
|
|||||||
Reference in New Issue
Block a user