You need to sign in or sign up before continuing.
Commit 78c35070 authored by 健杭 徐's avatar 健杭 徐
Browse files

docker

parent 4ab1ada5
FROM golang:1.24.3-alpine AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/main .
FROM alpine:latest
WORKDIR /app
COPY --from=builder /app/main .
EXPOSE 8080
CMD ["/app/main"]
version: '3.8'
services:
backend:
build: .
ports:
- "8080:8080"
environment:
- DB_HOST=db
- DB_PORT=5432
- DB_USER=chat_room_user
- DB_PASSWORD=secure_password
- DB_NAME=chat_room_db
depends_on:
- db
db:
image: postgres:13-alpine
environment:
- POSTGRES_USER=chat_room_user
- POSTGRES_PASSWORD=secure_password
- POSTGRES_DB=chat_room_db
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
......@@ -5,19 +5,29 @@ import (
"fmt"
"log"
"net/http"
"os"
"strconv"
"github.com/gin-gonic/gin"
_ "github.com/lib/pq"
)
const (
host = "localhost"
port = 5432
user = "chat_room_user"
password = "secure_password"
dbname = "chat_room_db"
)
// Helper to get env var or default
func getEnv(key, fallback string) string {
if value, ok := os.LookupEnv(key); ok {
return value
}
return fallback
}
// Helper to get env var as int or default
func getEnvAsInt(name string, defaultVal int) int {
valueStr := getEnv(name, "")
if value, err := strconv.Atoi(valueStr); err == nil {
return value
}
return defaultVal
}
type Message struct {
MessageId int `json:"message_id"`
......@@ -49,6 +59,12 @@ type RoomAddRes struct {
var db *sql.DB
func main() {
host := getEnv("DB_HOST", "localhost")
port := getEnvAsInt("DB_PORT", 5432)
user := getEnv("DB_USER", "chat_room_user")
password := getEnv("DB_PASSWORD", "secure_password")
dbname := getEnv("DB_NAME", "chat_room_db")
psqlInfo := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s sslmode=disable",
host, port, user, password, dbname)
......
FROM node:18-alpine AS builder
WORKDIR /app
COPY package.json package-lock.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine AS runner
WORKDIR /app
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
USER nextjs
EXPOSE 3000
ENV PORT 3000
CMD ["node", "server.js"]
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
/* config options here */
output: 'standalone',
};
export default nextConfig;
......@@ -209,7 +209,7 @@
display: flex;
flex-direction: column;
box-sizing: border-box;
background-image: url('../public/backGround.jpg');
background-color: #f0f0f0;
background-size: cover;
z-index: 2;
......
......@@ -242,7 +242,7 @@ function MessageItem (props: MessageProps & { onAddNewComment: (content: string)
// From Uiverse.io by adamgiebl
}
export function ChatRoomComponent({ userName }: { userName: string }) {
function ChatRoomComponent({ userName }: { userName: string }) {
const [rooms, setRooms] = useState<RoomEntryProps[]>([]);
const [currentRoom, setCurrentRoom] = useState<MessageProps | null>(null);
......
......@@ -16,7 +16,7 @@
min-height: 100vh;
width: 100vw;
background-size: cover;
background: url('../public/SetbackGround.jpg') no-repeat center;
background-color: grey;
}
.login-box
......
......@@ -3,14 +3,16 @@
import styles from"./Register.module.css"
import { MdLock, MdPerson } from "react-icons/md";
import { useState } from "react";
import { useRouter } from 'next/navigation';
const backEnd:string = "http://localhost:8080";
export default function Register({ onLogin }: { onLogin: (name: string) => void }) {
export default function Register() {
const [userName, setUserName] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [passwordError, setPasswordError] = useState('');
const router = useRouter();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
......@@ -40,10 +42,11 @@ export default function Register({ onLogin }: { onLogin: (name: string) => void
throw new Error('Failed to register');
}
const data = await response.json();
onLogin(data.userName);
alert('Registration successful! Redirecting to login page.');
router.push('/SetName');
} catch (error) {
console.error(error);
setPasswordError('Registration failed. Please try again.');
}
}
return (
......@@ -65,9 +68,9 @@ export default function Register({ onLogin }: { onLogin: (name: string) => void
<span className={styles["icon"]}>
<MdLock />
</span>
<input
type="password"
required
<input
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)} />
<label>Password</label>
......@@ -76,9 +79,9 @@ export default function Register({ onLogin }: { onLogin: (name: string) => void
<span className={styles["icon"]}>
<MdLock />
</span>
<input
type="password"
required
<input
type="password"
required
value={confirmPassword}
onChange={(e) => setConfirmPassword(e.target.value)} />
<label>Confirm Password</label>
......
......@@ -16,7 +16,7 @@
min-height: 100vh;
width: 100vw;
background-size: cover;
background: url('../public/SetbackGround.jpg') no-repeat center;
background-color: grey;
}
.login-box
......
......@@ -4,17 +4,18 @@ import styles from"./SetName.module.css"
import { MdLock, MdPerson } from "react-icons/md";
import { useState } from "react";
import Link from "next/link";
import { useRouter } from 'next/navigation';
const backEnd:string = "http://localhost:8080";
export default function SetName({ onLogin }: { onLogin: (name: string) => void }) {
export default function SetName() {
const [userName, setUserName] = useState('');
const [password, setPassword] = useState('');
const router = useRouter();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
e.preventDefault();
try {
const response = await fetch(`${backEnd}/login`, {
method: "POST",
......@@ -26,12 +27,14 @@ export default function SetName({ onLogin }: { onLogin: (name: string) => void }
const data = await response.json();
if (data.code === 0) {
onLogin(userName);
localStorage.setItem('userName', userName);
router.push('/ChatRoom');
} else {
alert(data.msg);
}
} catch (error) {
console.error("Error logging in:", error);
alert("Login failed. Please check the console for details.");
}
}
return (
......@@ -53,9 +56,9 @@ export default function SetName({ onLogin }: { onLogin: (name: string) => void }
<span className={styles["icon"]}>
<MdLock />
</span>
<input
type="password"
required
<input
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)} />
<label>Password</label>
......@@ -70,4 +73,4 @@ export default function SetName({ onLogin }: { onLogin: (name: string) => void }
</div>
</div>
);
}
\ No newline at end of file
}
'use client';
import React from 'react';
import SetName from './SetName/page';
import "./globals.css";
import { useEffect } from 'react';
import { useRouter } from 'next/navigation';
import "./globals.css";
export default function Page() {
const router = useRouter();
const handleLogin = (name: string) => {
localStorage.setItem('userName', name);
router.push('/ChatRoom');
};
useEffect(() => {
router.replace('/SetName');
}, [router]);
return (
<div className='root'>
<SetName onLogin={handleLogin} />
</div>
);
return null;
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment