BLOG-65 Establish beta environment (#66)
All checks were successful
Frontend CI / build (push) Successful in 1m4s

### Description

- Change some environment variables implementation
- Nginx configuration:

  ```nginx
  server {
      server_name beta.squidspirit.com;

      proxy_pass_request_headers on;
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;

      location / {
          proxy_pass http://127.0.0.1:10013/;
      }

      location /api/ {
          proxy_pass http://127.0.0.1:10014/;
      }

      listen 443 ssl; # managed by Certbot
      ssl_certificate /etc/letsencrypt/live/beta.squidspirit.com/fullchain.pem; # managed by Certbot
      ssl_certificate_key /etc/letsencrypt/live/beta.squidspirit.com/privkey.pem; # managed by Certbot
      include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
      ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
  }

  server {
      if ($host = beta.squidspirit.com) {
          return 301 https://$host$request_uri;
      } # managed by Certbot

      server_name beta.squidspirit.com;
      listen 80;
      return 404; # managed by Certbot
  }
  ```

- Podman kube configuration:

  ```yaml
    apiVersion: v1
  kind: Secret
  metadata:
    name: beta-blog-secret
  data:
    DATABASE_PASSWORD: {{BASE64_PASSWORD}}

  ---

  apiVersion: v1
  kind: Pod
  metadata:
    name: beta-blog
  spec:
    containers:
      - name: postgres
        image: docker.io/library/postgres:17-alpine
        imagePullPolicy: always
        env:
          - name: POSTGRES_PASSWORD
            valueFrom:
              secretKeyRef:
                name: beta-blog-secret
                key: DATABASE_PASSWORD
        volumeMounts:
          - name: beta-blog-postgres
            mountPath: /var/lib/postgresql/data
      - name: backend
        image: registry.squidspirit.com/squid/beta-blog-backend:latest
        imagePullPolicy: always
        env:
          - name: DATABASE_PASSWORD
            valueFrom:
              secretKeyRef:
                name: beta-blog-secret
                key: DATABASE_PASSWORD
        volumeMounts:
          - name: beta-blog-localtime
            mountPath: /etc/localtime
            readonly: true
        ports:
          - hostPort: 10014
            hostIP: 127.0.0.1
            containerPort: 8080
      - name: frontend
        image: registry.squidspirit.com/squid/beta-blog-frontend:latest
        imagePullPolicy: always
        env:
          - name: PUBLIC_API_BASE_URL
            value: https://beta.squidspirit.com/api/
        volumeMounts:
          - name: beta-blog-localtime
            mountPath: /etc/localtime
            readonly: true
        ports:
          - hostPort: 10013
            hostIP: 127.0.0.1
            containerPort: 3000
    volumes:
      - name: beta-blog-localtime
        hostPath:
          path: /etc/localtime
      - name: beta-blog-postgres
        persistentVolumeClaim:
          claimName: beta-blog-postgres
  ```

### Package Changes

_No response_

### Screenshots

_No response_

### Reference

Resolves #65

### Checklist

- [x] A milestone is set
- [x] The related issuse has been linked to this branch

Reviewed-on: #66
Co-authored-by: SquidSpirit <squid@squidspirit.com>
Co-committed-by: SquidSpirit <squid@squidspirit.com>
This commit is contained in:
SquidSpirit 2025-07-24 02:23:44 +08:00 committed by squid
parent c2462fe537
commit 4a924c1b92
5 changed files with 27 additions and 7 deletions

View File

@ -11,5 +11,12 @@ FROM alpine:latest AS runner
WORKDIR /app WORKDIR /app
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/server . COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/server .
EXPOSE 8080 EXPOSE 8080
ENV DATABASE_URL=postgres://postgres@localhost:5432/postgres ENV RUST_LOG=info
ENV HOST=0.0.0.0
ENV PORT=8080
ENV DATABASE_HOST=127.0.0.1
ENV DATABASE_PORT=5432
ENV DATABASE_USER=postgres
ENV DATABASE_PASSWORD=
ENV DATABASE_NAME=postgres
CMD ["./server"] CMD ["./server"]

View File

@ -16,15 +16,28 @@ async fn main() -> std::io::Result<()> {
let db_pool = init_database().await; let db_pool = init_database().await;
let host = env::var("HOST").unwrap_or_else(|_| "0.0.0.0".to_string());
let port = env::var("PORT")
.unwrap_or_else(|_| "8080".to_string())
.parse::<u16>()
.unwrap();
HttpServer::new(move || create_app(db_pool.clone())) HttpServer::new(move || create_app(db_pool.clone()))
.bind(("0.0.0.0", 8080))? .bind((host, port))?
.run() .run()
.await .await
} }
async fn init_database() -> Pool<Postgres> { async fn init_database() -> Pool<Postgres> {
let database_url = env::var("DATABASE_URL") let host = env::var("DATABASE_HOST").unwrap_or_else(|_| "127.0.0.1".to_string());
.unwrap_or_else(|_| "postgres://postgres@localhost:5432/postgres".to_string()); let port = env::var("DATABASE_PORT").unwrap_or_else(|_| "5432".to_string());
let user = env::var("DATABASE_USER").unwrap_or_else(|_| "postgres".to_string());
let password = env::var("DATABASE_PASSWORD").unwrap_or_else(|_| "".to_string());
let dbname = env::var("DATABASE_NAME").unwrap_or_else(|_| "postgres".to_string());
let database_url = format!(
"postgres://{}:{}@{}:{}/{}",
user, password, host, port, dbname
);
let db_pool = PgPoolOptions::new() let db_pool = PgPoolOptions::new()
.max_connections(5) .max_connections(5)

View File

@ -23,4 +23,5 @@ EXPOSE 3000
ENV NODE_ENV=production ENV NODE_ENV=production
ENV HOSTNAME=0.0.0.0 ENV HOSTNAME=0.0.0.0
ENV PORT=3000 ENV PORT=3000
ENV PUBLIC_API_BASE_URL=http://127.0.0.1:8080/
CMD ["node", "build"] CMD ["node", "build"]

View File

@ -1,5 +1,5 @@
import { env } from '$env/dynamic/public'; import { env } from '$env/dynamic/public';
export abstract class Environment { export abstract class Environment {
static readonly API_BASE_URL = env.PUBLIC_BACKEND_URL ?? 'http://localhost:5173/api'; static readonly API_BASE_URL = env.PUBLIC_API_BASE_URL ?? 'http://localhost:5173/api/';
} }

View File

@ -4,8 +4,7 @@ import { PostInfoResponseDto } from '$lib/post/adapter/gateway/postInfoResponseD
export class PostApiServiceImpl implements PostApiService { export class PostApiServiceImpl implements PostApiService {
async getAllPosts(): Promise<PostInfoResponseDto[]> { async getAllPosts(): Promise<PostInfoResponseDto[]> {
const url = new URL(Environment.API_BASE_URL); const url = new URL('post/all', Environment.API_BASE_URL);
url.pathname += '/post/all';
const response = await fetch(url.href); const response = await fetch(url.href);