Skip to content

Commit

Permalink
chore: improve environment handling and docker setup, remove .env val…
Browse files Browse the repository at this point in the history
…idation (#7)

## Summary

This PR includes a series of updates and improvements aimed at refining
both the development and production environments:

- **Environment Handling**:
- Improved environment variable loading and usage within various
commands.
- Removed the validation check for the `.env` file. This change was
necessary because in production environments using Docker, the `.env`
file is not utilized, which was causing unnecessary errors.
- **Dockerfile Enhancements**:
- Improved the Dockerfile to better accommodate both development and
production environments, ensuring smoother transitions between these
setups.
- **App Configuration**:
- Updated application settings specifically for the development
environment, optimizing for local development workflows.
- **CI/CD**:
- Added Dependabot configuration for weekly dependency updates,
enhancing project maintenance and security.

relates to basementdevs/twitch-better-profile#56
  • Loading branch information
gvieira18 authored Sep 4, 2024
1 parent 8308050 commit ba90085
Show file tree
Hide file tree
Showing 12 changed files with 173 additions and 78 deletions.
46 changes: 17 additions & 29 deletions .docker/Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -1,44 +1,32 @@
ARG DEBIAN_FRONTEND=noninteractive
# rust:1.80.1-alpine3.20
FROM rust@sha256:1f5aff501e02c1384ec61bb47f89e3eebf60e287e6ed5d1c598077afc82e83d5 AS dev

ARG INIT_PATH=/usr/local/bin/dumb-init
ARG INIT_URL=https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_x86_64
ARG USERNAME=rust
ARG USER=rust
ARG USER_UID=1000
ARG USER_GID=$USER_UID
ARG USER_GID=${USER_UID}
ARG WORK_DIR=/usr/src/app

FROM rust:1.80.1 AS dev

ARG DEBIAN_FRONTEND
ARG INIT_PATH
ARG INIT_URL
ARG USERNAME
ARG USER_UID
ARG USER_GID
ARG WORK_DIR

ENV TZ=America/Sao_Paulo TERM=xterm-256color LANG=C.UTF-8 LC_ALL=C.UTF-8

SHELL [ "/bin/bash", "-c" ]

RUN set -euxo pipefail;\
apt-get -qq update;\
apt-get -qq install -y nano sudo apt-utils build-essential tzdata curl cmake g++ libpcre3-dev libssl-dev make openssl libgmp-dev git curl ca-certificates software-properties-common wget zip unzip busybox > /dev/null;\
curl --fail --silent --show-error --location ${INIT_URL} --output ${INIT_PATH};\
apt-get -qq clean;\
chmod +x ${INIT_PATH};\
RUN set -euxo pipefail; \
apk add --no-cache nano sudo build-base tzdata curl cmake g++ pcre-dev openssl-dev make gmp-dev git ca-certificates wget zip unzip busybox; \
curl --fail --silent --show-error --location ${INIT_URL} --output ${INIT_PATH}; \
chmod +x ${INIT_PATH}; \
cargo install cargo-watch;

RUN set -euxo pipefail;\
groupadd --gid $USER_GID $USERNAME;\
useradd --uid $USER_UID --gid $USER_GID -m $USERNAME;\
echo $USERNAME ALL=\(root\) NOPASSWD:ALL > /etc/sudoers.d/$USERNAME;\
chmod 0440 /etc/sudoers.d/$USERNAME;
RUN set -euxo pipefail; \
addgroup -g ${USER_GID} ${USER}; \
adduser -u ${USER_UID} -G ${USER} -h /home/${USER} -D ${USER}; \
echo "${USER} ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/${USER}; \
chmod 0440 /etc/sudoers.d/${USER};

USER ${USERNAME}
USER ${USER}

ENV CARGO_HOME="/home/${USERNAME}/.cargo"
ENV CARGO_HOME="/home/${USER}/.cargo"

WORKDIR $WORK_DIR
WORKDIR ${WORK_DIR}

EXPOSE 3000

Expand Down
66 changes: 66 additions & 0 deletions .docker/Dockerfile.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
ARG INIT_PATH=/usr/local/bin/dumb-init
ARG INIT_URL=https://github.com/Yelp/dumb-init/releases/download/v1.2.5/dumb-init_1.2.5_x86_64
ARG USER=rust
ARG USER_UID=1000
ARG USER_GID=${USER_UID}
ARG WORK_DIR=/usr/src/app

# rust:1.80.1-alpine3.20
FROM rust@sha256:1f5aff501e02c1384ec61bb47f89e3eebf60e287e6ed5d1c598077afc82e83d5 AS builder

ARG INIT_PATH
ARG INIT_URL
ARG USER
ARG USER_UID
ARG USER_GID
ARG WORK_DIR

ENV CI=true LANG=C.UTF-8 LC_ALL=C.UTF-8

WORKDIR ${WORK_DIR}

RUN set -euxo pipefail; \
apk add --no-cache build-base cmake g++ pcre-dev openssl-dev gmp-dev curl ca-certificates; \
curl --fail --silent --show-error --location ${INIT_URL} --output ${INIT_PATH}; \
chmod +x ${INIT_PATH};

COPY Cargo.toml Cargo.lock Makefile ${WORK_DIR}/
COPY src ${WORK_DIR}/src

RUN set -euxo pipefail; \
make clean; \
make release;

# alpine:3.20
FROM alpine@sha256:0a4eaa0eecf5f8c050e5bba433f58c052be7587ee8af3e8b3910ef9ab5fbe9f5 AS main

ARG INIT_PATH
ARG INIT_URL
ARG USER
ARG USER_UID
ARG USER_GID
ARG WORK_DIR

ENV LANG=C.UTF-8 LC_ALL=C.UTF-8

RUN set -euxo pipefail; \
addgroup -g ${USER_GID} ${USER}; \
adduser -u ${USER_UID} -G ${USER} -D ${USER}; \
apk update --no-cache; \
apk upgrade --no-cache;

COPY --from=builder --chown=${USER}:${USER} ${INIT_PATH} ${INIT_PATH}

WORKDIR ${WORK_DIR}

COPY --from=builder --chown=${USER}:${USER} ${WORK_DIR}/target/release/twitch-extension-api ${WORK_DIR}/twitch-extension-api

COPY --chown=${USER}:${USER} static ${WORK_DIR}/static

USER ${USER}

EXPOSE 3000

ENTRYPOINT [ "/usr/local/bin/dumb-init", "--" ]

CMD [ "/usr/src/app/twitch-extension-api" ]
23 changes: 12 additions & 11 deletions .env.docker
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
# Rust
RUST_LOG=info
RUST_LOG=twitch_extension_api=debug
RUST_BACKTRACE=1

# Http
MAX_WORKERS=2

# App Config
APP_NAME="Twitch Better Chat API"
APP_VERSION="0.1.0"
APP_URL="0.0.0.0"
APP_PORT="8001"
APP_TLS_ENABLED="false"
APP_TLS_CERT="/your/path/to/cert.pem"
APP_TLS_KEY="/your/path/to/key.pem"
APP_PLATFORM_SECRET="secret"
APP_VERSION=0.1.0
APP_URL=0.0.0.0
APP_PORT=3000
APP_ENV=dev
APP_TLS_ENABLED=false
APP_TLS_CERT=/your/path/to/cert.pem
APP_TLS_KEY=/your/path/to/key.pem
APP_PLATFORM_SECRET=secret

# Database Config
SCYLLA_NODES="host:port"
SCYLLA_NODES=scylla-1:9042
SCYLLA_USERNAME=
SCYLLA_PASSWORD=
SCYLLA_CACHED_QUERIES="15"
SCYLLA_KEYSPACE="twitch"
SCYLLA_CACHED_QUERIES=15
SCYLLA_KEYSPACE=twitch
27 changes: 14 additions & 13 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
# Rust
RUST_LOG=info
RUST_LOG=twitch_extension_api=info
RUST_BACKTRACE=1

# Http
MAX_WORKERS=4

# App Config
APP_NAME="Twitch Better Chat API"
APP_VERSION="0.1.0"
APP_URL="0.0.0.0"
APP_PORT="8001"
APP_TLS_ENABLED="false"
APP_TLS_CERT="/your/path/to/cert.pem"
APP_TLS_KEY="/your/path/to/key.pem"
APP_PLATFORM_SECRET="secret"
APP_NAME='Twitch Better Chat API'
APP_VERSION=0.1.0
APP_URL=0.0.0.0
APP_PORT=3000
APP_ENV=dev
APP_TLS_ENABLED=false
APP_TLS_CERT=/your/path/to/cert.pem
APP_TLS_KEY=/your/path/to/key.pem
APP_PLATFORM_SECRET=secret

# Database Config
SCYLLA_NODES="localhost:9042"
SCYLLA_USERNAME="scylla"
SCYLLA_NODES=localhost:9042
SCYLLA_USERNAME=
SCYLLA_PASSWORD=
SCYLLA_CACHED_QUERIES="15"
SCYLLA_KEYSPACE="twitch"
SCYLLA_CACHED_QUERIES=15
SCYLLA_KEYSPACE=twitch
13 changes: 13 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
version: 2

updates:
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
target-branch: "develop"
- package-ecosystem: "cargo"
directory: "/"
schedule:
interval: "weekly"
target-branch: "develop"
22 changes: 16 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,19 @@ on:
- main
- develop

concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
setup:
name: Setup rust
runs-on: ubuntu-24.04
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup rust
uses: actions-rust-lang/setup-rust-toolchain@v1
uses: actions-rust-lang/setup-rust-toolchain@1fbea72663f6d4c03efaab13560c8a24cfd2a7cc # v1.9.0
with:
toolchain: stable
target: x86_64-unknown-linux-gnu
Expand All @@ -34,10 +38,16 @@ jobs:
- setup
steps:
- name: Checkout code
uses: actions/checkout@v4
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup rust
uses: actions-rust-lang/setup-rust-toolchain@1fbea72663f6d4c03efaab13560c8a24cfd2a7cc # v1.9.0
with:
toolchain: stable
target: x86_64-unknown-linux-gnu
components: clippy, rustfmt
- name: Run formatter
uses: actions-rust-lang/rustfmt@v1
uses: actions-rust-lang/rustfmt@2d1d4e9f72379428552fa1def0b898733fb8472d # v1.1.0
- name: Run linter
uses: clechasseur/rs-clippy-check@v3
uses: clechasseur/rs-clippy-check@a2a93bdcf05de7909aabd62eca762179ad3dbe50 # v3.0.5
with:
args: --all-targets --all-features
args: --all-features
19 changes: 7 additions & 12 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,28 +37,23 @@ release: clean ## Cleans up the project and compiles it for release.
test: ## Runs the test suite.
@$(CARGO) test

# Load specific variables from .env file
ifneq (,$(wildcard .env))
export SCYLLA_NODES := $(shell grep -E '^SCYLLA_NODES=' .env | awk -F '=' '{gsub(/^[[:space:]]*|[[:space:]]*$$/, "", $$2); print substr($$2, 2, length($$2)-2)}')
export SCYLLA_KEYSPACE := $(shell grep -E '^SCYLLA_KEYSPACE=' .env | awk -F '=' '{gsub(/^[[:space:]]*|[[:space:]]*$$/, "", $$2); print substr($$2, 2, length($$2)-2)}')
export SCYLLA_USERNAME := $(shell grep -E '^SCYLLA_USERNAME=' .env | awk -F '=' '{gsub(/^[[:space:]]*|[[:space:]]*$$/, "", $$2); print substr($$2, 2, length($$2)-2)}')
export SCYLLA_PASSWORD := $(shell grep -E '^SCYLLA_PASSWORD=' .env | awk -F '=' '{gsub(/^[[:space:]]*|[[:space:]]*$$/, "", $$2); print substr($$2, 2, length($$2)-2)}')
# Load .env file
ifneq (,$(wildcard ./.env))
include .env
export
endif

.PHONY: print-env
print-env: ## Prints the loaded environment variables from the .env file.
@echo "SCYLLA_NODES=$(SCYLLA_NODES)"
@echo "SCYLLA_KEYSPACE=$(SCYLLA_KEYSPACE)"
@echo "SCYLLA_USERNAME=$(SCYLLA_USERNAME)"
@echo "SCYLLA_PASSWORD=$(SCYLLA_PASSWORD)"
$(foreach v, $(.VARIABLES), $(info $(v)=$($(v))))

.PHONY: migrate
migrate: ## Runs database migrations
@migrate --host=$(SCYLLA_NODES) --keyspace=$(SCYLLA_KEYSPACE) $(if $(SCYLLA_USERNAME), --user=$(SCYLLA_USERNAME),) $(if $(SCYLLA_PASSWORD),--password=$(SCYLLA_PASSWORD),)
@migrate --host=$(SCYLLA_NODES) --keyspace=$(SCYLLA_KEYSPACE) $(if $(SCYLLA_USERNAME),--user=$(SCYLLA_USERNAME)) $(if $(SCYLLA_PASSWORD),--password=$(SCYLLA_PASSWORD))

.PHONY: keyspace
keyspace: ## Configures the keyspace in the ScyllaDB
@toolkit keyspace --host=$(SCYLLA_NODES) --keyspace=$(SCYLLA_KEYSPACE) --replication-factor="1" $(if $(SCYLLA_USERNAME), --user=$(SCYLLA_USERNAME),) $(if $(SCYLLA_PASSWORD),--password=$(SCYLLA_PASSWORD),)
@toolkit keyspace --host=$(SCYLLA_NODES) --keyspace=$(SCYLLA_KEYSPACE) --replication-factor="1" $(if $(SCYLLA_USERNAME),--user=$(SCYLLA_USERNAME)) $(if $(SCYLLA_PASSWORD),--password=$(SCYLLA_PASSWORD))

.PHONY: watch
watch: ## Watches for changes in the source files and runs the project on each change.
Expand Down
Empty file removed current_schema.json
Empty file.
23 changes: 23 additions & 0 deletions docker-compose.prod.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
services:
tbp-server:
build:
context: .
dockerfile: .docker/Dockerfile.prod
image: tbp-consumer-api:${APP_VERSION}
hostname: prod
restart: on-failure
ports:
- "3001-3003:3000"
deploy:
replicas: 3
resources:
limits:
cpus: '0.3'
memory: '300MB'
networks:
- tbp-consumer-api
stop_signal: SIGTERM
networks:
tbp-consumer-api:
name: tbp-consumer-api
driver: bridge
6 changes: 3 additions & 3 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
services:
tbp-consumer-api:
tbp-server:
build:
context: .
dockerfile: .docker/Dockerfile.dev
tty: true
stdin_open: true
image: tbp-consumer-api:dev
container_name: tbp-consumer-api
container_name: tbp-server
hostname: dev
ports:
- "8001:8001"
- "3000:3000"
env_file:
- .env.docker
volumes:
Expand Down
3 changes: 0 additions & 3 deletions src/config/app.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use crate::config::Config;
use dotenvy::dotenv;
use scylla::{CachingSession, Session, SessionBuilder};
use std::sync::Arc;
use std::time::Duration;
Expand All @@ -12,8 +11,6 @@ pub struct AppState {

impl AppState {
pub async fn new() -> Self {
dotenv().expect(".env file not found");

let config = Config::new();
let session: Session = SessionBuilder::new()
.known_nodes(config.database.nodes)
Expand Down
3 changes: 2 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::io::BufReader;
use actix_cors::Cors;
use actix_web::web::Data;
use actix_web::{App, HttpServer};
use dotenvy::dotenv;
use log::debug;

use self::http::v1;
Expand All @@ -16,7 +17,7 @@ mod models;

#[actix_web::main]
async fn main() -> std::io::Result<()> {
dotenvy::dotenv().expect(".env file not found");
dotenv().ok();
colog::init();
let app_data = AppState::new().await;

Expand Down

0 comments on commit ba90085

Please sign in to comment.