Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: Tests

on:
pull_request:
branches:
- "*"
push:
branches:
- main

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# This is a workaround for overriding containers. As by default the
# environment is development and the containers read the .env file,
# here we keep the default but for CI we use the test env.
- name: Replace defaulf environment variables
run: |
cp lib/templates/.env.test.template .env.development.local
- name: Build and run containers
run: docker-compose build app
- name: Prepare database and run migrations
run: docker-compose run app rails db:create db:migrate
- name: Running suite of tests
env:
CI: true
run: docker-compose run app bundle exec rails spec
- name: Stop containers
run: docker-compose down
3 changes: 2 additions & 1 deletion .tool-versions
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
ruby 3.2.0
nodejs 19.6.0
nodejs 19.9.0
postgres 15.1
redis 7.0.8
golang 1.20.2
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ RUN echo 'gem: --no-rdoc --no-ri' >> $HOME/.gemrc

RUN curl -sL https://deb.nodesource.com/setup_19.x | bash -
RUN apt-get install -y nodejs
RUN npm install npm@9.4.0 -g
RUN npm install npm@9.6.6 -g
RUN npm install yarn@1.22.19 -g

RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
Expand Down
2 changes: 1 addition & 1 deletion Procfile.dev → Procfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@ mail: maildev --hide-extensions STARTTLS
web: bundle exec puma -C config/puma.rb
js: yarn build --watch
css: yarn build:css --watch
minio: minio server ~/minio_storage
minio: minio server ~/buckets/management
background: bundle exec sidekiq -C config/sidekiq.yml
264 changes: 108 additions & 156 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,224 +1,176 @@
# README
<p align="center">
<img src="https://cdn-icons-png.flaticon.com/512/3286/3286792.png" width="200" alt="Management">
</p>

This documentation focuses on the post-formatted setup environment for windows with the following settings:
[![CI](https://github.com/ricardopacheco/Fullstack-Developer/actions/workflows/ci.yml/badge.svg)](https://github.com/ricardopacheco/Fullstack-Developer/actions/workflows/ci.yml) [![Current Version](https://img.shields.io/badge/demo-online-green.svg)](https://github/com/ricardopacheco/Fullstack-Developer)

- Ubuntu WSL2 22.04 LTS
A small app for user management.

## Getting started
---

Clone the project from github:
## Table of Contents

```
user@host:~$ git clone git@github.com:ricardopacheco/Fullstack-Developer.git management
user@host:~$ cd management
user@host:~$ cp .env.development.template .env.development.local
user@host:~$ cp .env.test.template .env.test.local
```
- [Introduction](#introduction)
- [Getting started](#getting-started)
- [Setup with Host](#setup-with-host)
- [Setup with Docker](#setup-with-docker)
- [Useful commands](#useful-commands)
- [Troubleshouting](#troubleshouting)

> You will configure environment variables according to your development and test environment.
---

> Use the initial credentials email `admin@email.com` and password `password` to first login in system.
## Introduction

## Setup in development environment in host mode [ASDF]
This is sample code following best practices for a monolithic application. The code of this application has educational purposes and can be used freely. To run this project locally, you can choose "host" mode, where I use asdf to manage versions and Procfile to start processes correctly, or you can choose using Docker and compose. Both ways are well documented in this README.

> Read the asdf documentation [here](https://asdf-vm.com/#/core-manage-asdf). It contains the asdf setup process for your OS. Once asdf has been installed and is working, navigate to the folder where you cloned the project and perform the following steps:
---

## OS dependencies
## Getting started

#### Nokogiri gem
Clone the project from github and prepare environment variables for dev/test.

```
user@host:~$ sudo apt install zlib1g-dev liblzma-dev patch pkg-config libxml2-dev libxslt-dev
```shell
git clone git@github.com:ricardopacheco/Fullstack-Developer.git management
cd management
cp lib/templates/.env.development.template .env.development.local
cp lib/templates/.env.test.template .env.test.local
```

#### Shrinerb gem
---

```
user@host:~$ sudo apt install imagemagick
```
## Setup with Host

## Database (PostgreSQL)
> Read the asdf documentation [here](https://asdf-vm.com/#/core-manage-asdf). It contains the asdf setup process for your OS. Next steps considerind Once asdf has been installed and is working.

### Postgres
> [IMPORTANT] By default, environment variables are set to initial values for docker. You need to change the values to that of your host.

```
user@host:~$ sudo apt install build-essential libssl-dev libreadline-dev zlib1g-dev libcurl4-openssl-dev uuid-dev
user@host:~$ asdf plugin add postgres
user@host:~$ asdf install postgres 15.1
user@host:~$ rm -rf ~/.asdf/installs/postgres/15.1/data
user@host:~$ initdb -D ~/.asdf/installs/postgres/15.1/data -U postgres
```

#### Ruby
Run the command below, it will setup ruby and support services using asdf plugins, as well as installing necessary operating system packages.

```
user@host:~$ sudo apt install autoconf bison build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm6 libgdbm-dev libdb-dev
user@host:~$ asdf plugin add ruby
user@host:~$ asdf install ruby 3.2.0
user@host:~$ gem install pg -v 1.4.5 --verbose -- --with-pg-config=$HOME/.asdf/installs/postgres/15.1/bin/pg_config # Fix pg_config
user@host:~$ bundle install
```shell
devops/development/setup
```

### NodeJS
Now, let's create a bucket for development with minio service:

```
user@host:~$ asdf plugin add nodejs
user@host:~$ asdf install nodejs 19.6.0
user@host:~$ npm install -g yarn@1.22.19
user@host:~$ npm install -g maildev@latest
```shell
overmind s -l minio -D
mc alias set minio-dev http://127.0.0.1:9000 minioadmin minioadmin
mc mb ~/buckets/management/development --region="br-east-1"
mc anonymous set public minio-dev/development
overmind quit
```

> You will be able to view emails fired through the maildev UI by accessing [http://localhost:1080](http://localhost:1080)
> after starting the services (whether using docker or with procfile).
> [Careful] We set this policy option for practical reasons of agility in the workflow. In production, this is strictly prohibited and the policy must be set up focused exclusively on performance and security.

### Redis
After that, let's start the database service and create database for application:

```
user@host:~$ sudo apt install build-essential
user@host:~$ asdf plugin add redis
user@host:~$ asdf install redis 7.0.8
```shell
overmind s -l database -D
bundle exec rails db:create db:setup
overmind quit
```

#### Procfile manager (Optional, but recommended)
You can start application with `overmind start`. The application will be available at the address `http://localhost:3000`

```
user@host:~$ curl -O https://storage.googleapis.com/golang/go1.19.4.linux-amd64.tar.gz
user@host:~$ tar -xvf go1.19.4.linux-amd64.tar.gz
user@host:~$ sudo mv go /usr/local
user@host:~$ mkdir $HOME/go
```
## Setup with Docker

Add this config to shell config file (~/.bashrc, ~/.zshrc)
You will need to have `docker` and `docker-compose` installed to run the project correctly. Install according to your OS's official documentation:

```
export GOROOT=/usr/local/go
export GOPATH=$HOME/go
export PATH=$GOPATH/bin:$GOROOT/bin:$PATH
```
- [`docker`](https://docs.docker.com/engine/install/)
- [`docker-compose`](https://docs.docker.com/compose/install/)

And run the commands above:

```
user@host:~$ source ~/.zshrc # set to your shell config file
user@host:~$ GO111MODULE=on go install github.com/DarthSim/overmind@v2
```
> Consider running docker without using sudo in linux (with your default user) via this documentation. [documentation](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)

### Install minio server
To verify that docker is working correctly, run the `docker --version` and `docker compose --version` commands. If the output of the command is the same like `Docker version 20.10.23, build 7155243` and `Docker Compose version v2.15.1` your installation should be ok.

> In this install, go lang is required if installed by source code. If not, you can read minio's official documentation to install the server and client according to your OS.
| WARNING: **After that, edit `.env.development.local` and `.env.test.local` files with docker values if needed.** |
| ---------------------------------------------------------------------------------------------------------------- |

```
user@host:~$ mkdir $HOME/minio_storage
user@host:~$ GO111MODULE=on go install github.com/minio/minio@latest
user@host:~$ GO111MODULE=on go install github.com/minio/mc@latest
user@host:~$ minio server ~/minio_storage
```
Now let's configure a bucket for the application using minio:

Now, open the new tab in current directory, run the command below creating an alias for the client that will authenticate and connect to the minio deployment:
```shell
docker compose up minio -d
docker run -it --name mc --net management_default --env-file "./.env" --entrypoint=/bin/sh minio/mc
mc alias set minio-dev http://minio:9000 minioadmin minioadmin
mc mb minio-dev/management --region="br-east-1"
mc anonymous set public minio-dev/management
exit

docker compose stop
docker rm -f $(docker ps -a -q)
```
user@host:~$ mc alias set minio-dev http://127.0.0.1:9000 minioadmin minioadmin
```

> Check that everything is working using the command `mc admin info minio-dev`.

After that, create a bucket for development purposes:
> If error "mc: <ERROR> Unable to make bucket `minio-dev/management/development`. Your previous request to create > the named bucket succeeded and you already own it." occours when `mc mb minio-dev/management/development --region="br-east-1"` **just ignored it**.

```
user@host:~$ mc mb ~/minio_storage/development --region="br-east-1"
user@host:~$ mc anonymous set public minio-dev/development
```

> We set this policy option for practical reasons of agility in the development workflow. In production, this is strictly prohibited and the policy must be set up focused exclusively on performance and security.
With the bucket created, we can follow the normal setup of a rails application with docker:

#### Create a development database

```
user@host:~$ OVERMIND_PROCFILE=Procfile.dev overmind s -l database
user@host:~$ bundle exec rails db:create db:migrate db:seed
```shell
# This command may take a while depending on your internet speed.
# This will create an intermediate container that will open a bash for us
docker compose run --rm app bin/setup
dockero compose down
```

> Give ctrl+c here to stop the database service, we will start it below along with the other dependent services.
Now just start your full stack using `docker compose up`. You should be able to see the application running [locally](http://localhost:3000)

#### Install git hooks

```
user@host:~$ overcommit --install
user@host:~$ overcommit --sign
user@host:~$ overcommit --sign pre-commit
user@host:~$ overcommit --sign post-commit
```

> We use git hooks to do code checking to avoid bad commits.

#### Start application
> To run the test suite, run the commands below:

```
user@host:~$ overmind s -f Procfile.dev
docker compose run --rm $(awk '!/^#/ && NF > 0 {print "-e", $1}' .env.test.local) app bundle exec rails db:create
docker compose run --rm $(awk '!/^#/ && NF > 0 {print "-e", $1}' .env.test.local) app bundle exec rails spec
```

## Setup in development environment in container mode [Docker]

> Installation of docker and compose may vary by operating system and are updated quite frequently. With that, I suggest you see the installation documentation in the official documentation, follow the links (I'll put ubuntu because we're using it as a base, but change according to your OS).

- [Docker](https://docs.docker.com/engine/install/ubuntu/)
- [Docker compose](https://docs.docker.com/compose/install/)
## Useful commands

> Consider running docker without using sudo (with your default user) via this documentation. [documentation](https://docs.docker.com/engine/install/linux-postinstall/#manage-docker-as-a-non-root-user)

| WARNING: **After that, edit `.env.development.local` and `.env.test.local` files with docker values if needed.** |
| ---------------------------------------------------------------------------------------------------------------- |
This is actually a cheat-sheet we find useful! Nothing too specific to our apps.

With that, we created an intermediate application container in order to make the first configurations. First, let's start a file upload server:
```shell
# Debugging container with pry: connect to the `app` process to be able to input commands:
docker attach $(docker-compose ps -q app)
# Then disconnect by hitting [Ctrl+C].

```
user@host:~$ docker compose up minio
```
# Restart a container without restarting all the other ones:
docker compose restart app

Now in another tab, let's set up a bucket for the file upload server:
# Stop all containers with compose
docker compose stop

```
user@host:~$ docker run -it --name mc --net management_default --env-file "./.env.development.local" --entrypoint=/bin/sh minio/mc
sh-4.4# mc alias set minio-dev http://minio:9000 minioadmin minioadmin
sh-4.4# mc mb minio-dev/development --region="br-east-1"
sh-4.4# mc anonymous set public minio-dev/development
sh-4.4# exit
```
# Remove all containers with compose
docker compose rm

> If error "mc: <ERROR> Unable to make bucket `minio-dev/development`. Your previous request to create > the named bucket succeeded and you already own it." occours when `mc mb minio-dev/development --region="br-east-1"` **just ignored it**.
# Stop and remove all containers with compose
docker compose down

Now, Run the following commands below to add gems in cache volume, create a development/test database and kill containers to start all containers correctly:
# Stop all containers (with or without compose). This is useful in case some
# unexpected container is running and disturbing the workflow.
docker stop -f $(docker ps -a -q)

```
user@host:~$ docker compose build app
user@host:~$ docker compose run app bash
root@container-id:~$ bundle install
root@container-id:~$ bundle exec rails db:create db:migrate db:seed
root@container-id:~$ exit
user@host:~$ docker rm -f $(docker ps -a -q)
```
# Remove all containers (with or without compose). This is useful in case some
# unexpected container is running and disturbing the workflow.
docker rm -f $(docker ps -a -q)

> Remove ~/.docker if happen this error "docker endpoint for "default" not found" and try again build app image (`docker compose build app`)
# Install ping tool (for debug network issues)
apt install iputils-ping

#### Start application
# Install ifconfig tool (for debug network issues)
apt install net-tools

```
user@host:~$ docker compose up
# Running specified scripts. Using --rm option just remove app container.
# Linked dependencies (db,redis,etc) will continue to run. To stop them,
# use `docker compose down`
docker compose run --rm service_name [command]
```

### Run suite of tests

```
user@host:~$ docker compose --env-file=".env.test.local" run --rm app bundle exec rake spec
```
---

## Troubleshouting

- "gem_name" is not yet checked out. Run `bundle install`
- "gem_name" is not yet checked out.

> Run a intermediate container and run bundle install (add gems in app cache volume).
> Run a intermediate container and run bundle install (add gems in app cache volume) with `docker compose run --rm app bundle install`

```
user@host:~$ docker compose run app bash
root@container-id:~$ bundle install
```
- "docker endpoint for "default" not found"

> Remove ~/.docker if happen this error and try again build app image (`docker compose build app`)
2 changes: 1 addition & 1 deletion config/environments/development.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
config.active_record.verbose_query_logs = true

# Suppress logger output for asset requests.
config.assets.quiet = true
# config.assets.quiet = true

# Raises error for missing translations.
# config.i18n.raise_on_missing_translations = true
Expand Down
Loading