Skip to content

Commit

Permalink
Feat Production Setup (#8)
Browse files Browse the repository at this point in the history
* Fixed the configurations

* Updated docker-compose.yml and added PostgreSQL docker setup

* Added dockerfile for production client, added nginx configuration, fixed dockerfile for backend

* Added github workflow

* Updated README.md
  • Loading branch information
MarkHmnv authored Jun 26, 2024
1 parent 2dafd05 commit 23614ea
Show file tree
Hide file tree
Showing 16 changed files with 223 additions and 22 deletions.
10 changes: 10 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
REDIS_USER=default
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_PASSWORD=

POSTGRES_USER=devuser
POSTGRES_PASSWORD=changeme
POSTGRES_DB=devdb
POSTGRES_HOST=postgres-db

SMTP_HOST=
SMTP_PORT=
SMTP_USER=
Expand Down
49 changes: 49 additions & 0 deletions .github/workflows/main_webeye.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
name: Build, Test, and Push Docker Image

on:
push:
branches:
- main

jobs:
test:
name: Test API
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Run tests
run: docker-compose run --rm api sh -c "pytest /api/tests"

build-and-push:
name: Build and Push Docker Image
needs: test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build client image
run: docker build -f client/Dockerfile-prod -t 17021702/webeye-client:latest client/

- name: Build API image
run: docker build -t 17021702/webeye-api:latest ./api

- name: Push client image
run: docker push 17021702/webeye-client:latest

- name: Push API image
run: docker push 17021702/webeye-api:latest
14 changes: 11 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,17 @@ This project is a notification system that allows users to subscribe to notifica

3. **Run the application**:

```bash
docker-compose up --build
```
For development purposes, use the default `docker-compose.yml`:

```bash
docker-compose up --build
```

For production deployment, use `docker-compose.prod.yml`:

```bash
docker-compose -f docker-compose.prod.yml up --build
```

## API Endpoints

Expand Down
4 changes: 3 additions & 1 deletion api/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ RUN python -m venv /py && \
ENV PATH="/py/bin:$PATH"
ENV PYTHONPATH "${PYTHONPATH}:/"

USER fastapi-user
USER fastapi-user

CMD ["/usr/bin/supervisord"]
2 changes: 1 addition & 1 deletion api/core/celery_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from api.core import config

broker_url = f'redis://{config.redis_host}:{config.redis_port}'
broker_url = f'redis://{config.redis_user}:{config.redis_password}@{config.redis_host}:{config.redis_port}'
celery_app = Celery('tasks', broker=broker_url, beat_max_loop_interval=5)
celery_app.autodiscover_tasks(
[
Expand Down
1 change: 1 addition & 0 deletions api/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
postgres_db = os.getenv('POSTGRES_DB', 'devdb')
postgres_host = os.getenv('POSTGRES_HOST', 'localhost')

redis_user = os.getenv('REDIS_USER', 'devuser')
redis_host = os.getenv('REDIS_HOST', 'localhost')
redis_port = os.getenv('REDIS_PORT', '6379')
redis_password = os.getenv('REDIS_PASSWORD', 'changeme')
Expand Down
2 changes: 1 addition & 1 deletion api/core/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
MSE_THRESHOLD = 30

options = Options()
options.add_argument('--headless=new')
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
2 changes: 1 addition & 1 deletion api/core/redis_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
from api.core import config

rd = redis.Redis(
password=config.redis_password,
host=config.redis_host,
port=config.redis_port,
db=0
)
2 changes: 1 addition & 1 deletion api/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from api.user.persistence import User
from api.user.schemas import CreateUser

DATABASE_URL = f'postgresql+asyncpg://{config.postgres_user}:{config.postgres_password}@{config.postgres_host}:5432/test_db'
DATABASE_URL = f'postgresql+asyncpg://{config.postgres_user}:{config.postgres_password}@{config.postgres_host}:5432/webeye_test_db'
engine = create_async_engine(DATABASE_URL, poolclass=NullPool)
factory = async_sessionmaker(engine, autoflush=False, autocommit=False, expire_on_commit=False)

Expand Down
17 changes: 17 additions & 0 deletions client/Dockerfile-prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
FROM node:20-alpine AS build

WORKDIR /client

COPY . .

RUN npm install && npm run build

FROM nginx:alpine

COPY --from=build /client/dist /usr/share/nginx/html

COPY nginx.conf /etc/nginx/nginx.conf

EXPOSE 8080

CMD ["nginx", "-g", "daemon off;"]
43 changes: 43 additions & 0 deletions client/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
user nginx;

worker_processes auto;

events { worker_connections 1024; }

http {
server {
server_tokens off;

listen 8080;
root /usr/share/nginx/html;
include /etc/nginx/mime.types;

location / {
try_files $uri $uri/ /index.html;
}

gzip on;
gzip_vary on;
gzip_http_version 1.0;
gzip_comp_level 5;
gzip_types
application/atom+xml
application/javascript
application/json
application/rss+xml
application/vnd.ms-fontobject
application/x-font-ttf
application/x-web-app-manifest+json
application/xhtml+xml
application/xml
font/opentype
image/svg+xml
image/x-icon
text/css
text/plain
text/x-component;
gzip_proxied no-cache no-store private expired auth;
gzip_min_length 256;
gunzip on;
}
}
1 change: 1 addition & 0 deletions client/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import react from '@vitejs/plugin-react'

export default defineConfig({
plugins: [react()],
base: './',
preview: {
port: 3000,
strictPort: true,
Expand Down
58 changes: 58 additions & 0 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
version: "3.9"

services:
api:
image: 17021702/webeye-api
restart: always
ports:
- "8000:8000"
environment:
- REDIS_USER=${REDIS_USER}
- REDIS_HOST=${REDIS_HOST}
- REDIS_PORT=${REDIS_PORT}
- REDIS_PASSWORD=${REDIS_PASSWORD}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_HOST=${POSTGRES_HOST}
- SMTP_HOST=${SMTP_HOST}
- SMTP_PORT=${SMTP_PORT}
- SMTP_USER=${SMTP_USER}
- SMTP_PASSWORD=${SMTP_PASSWORD}

client:
image: 17021702/webeye-client
ports:
- "80:8080"
volumes:
- ./client/nginx.conf:/etc/nginx/nginx.conf

# You can also use Docker containers for PostgreSQL and Redis instead of using serverless solutions
# postgres-db:
# build:
# context: ./postgres
# ports:
# - "5432:5432"
# volumes:
# - postgres-data:/var/lib/postgresql/data
# healthcheck:
# test: ["CMD-SHELL", "pg_isready -U devuser -d postgres"]
# interval: 1s
# timeout: 1s
# retries: 60
#
# redis:
# image: redis:7.0-alpine
# ports:
# - "6379:6379"
# volumes:
# - redis-data:/data
# healthcheck:
# test: redis-cli ping
# interval: 1s
# timeout: 1s
# retries: 60
#
#volumes:
# postgres-data:
# redis-data:
25 changes: 11 additions & 14 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,20 @@ services:
- ./api:/api
command: /usr/bin/supervisord
environment:
- REDIS_HOST=redis
- REDIS_PORT=6379
- REDIS_PASSWORD=changeme
- POSTGRES_USER=devuser
- POSTGRES_PASSWORD=changeme
- POSTGRES_DB=devdb
- POSTGRES_HOST=postgres-db
- REDIS_USER=${REDIS_USER}
- REDIS_HOST=${REDIS_HOST}
- REDIS_PORT=${REDIS_PORT}
- REDIS_PASSWORD=${REDIS_PASSWORD}
- POSTGRES_USER=${POSTGRES_USER}
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
- POSTGRES_DB=${POSTGRES_DB}
- POSTGRES_HOST=${POSTGRES_HOST}
- SMTP_HOST=${SMTP_HOST}
- SMTP_PORT=${SMTP_PORT}
- SMTP_USER=${SMTP_USER}
- SMTP_PASSWORD=${SMTP_PASSWORD}


client:
build:
context: ./client
Expand All @@ -38,11 +40,8 @@ services:
command: npm run dev

postgres-db:
image: postgres:16.1-alpine
environment:
- POSTGRES_USER=devuser
- POSTGRES_PASSWORD=changeme
- POSTGRES_DB=devdb
build:
context: ./postgres
ports:
- "5432:5432"
volumes:
Expand All @@ -55,8 +54,6 @@ services:

redis:
image: redis:7.0-alpine
environment:
- REDIS_PASSWORD=changeme
ports:
- "6379:6379"
volumes:
Expand Down
8 changes: 8 additions & 0 deletions postgres/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
FROM postgres:16.1-alpine

ENV POSTGRES_USER=devuser
ENV POSTGRES_PASSWORD=changeme

COPY init.sql /docker-entrypoint-initdb.d/

EXPOSE 5432
7 changes: 7 additions & 0 deletions postgres/init.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
-- Create main development database
CREATE DATABASE devdb;
GRANT ALL PRIVILEGES ON DATABASE devdb TO devuser;

-- Create test database
CREATE DATABASE webeye_test_db;
GRANT ALL PRIVILEGES ON DATABASE webeye_test_db TO devuser;

0 comments on commit 23614ea

Please sign in to comment.