DevChalk

GoravelEpisode 1 of 19

Installation & Project Architecture

A running Goravel skeleton, providers wired, Docker up

19:36

This is the first episode of the Goravel series. Over the next episodes we build TaskFlow, a multi-user task management API, and use it to learn Goravel by building something real. This one is setup: the database design, a new project, Postgres and Redis in Docker, and a running server.

The database design

Watch this part

Before any code, here is the shape of the system. Three tables carry the whole app.

users holds everyone who can log in. Besides the basics it has a role, which is either manager or member. That one column drives the authorization rules later: a manager can create, edit and delete tasks, a member can only update the status of tasks assigned to them.

columntypenotes
idbigintprimary key
namestring
emailstringunique
passwordstringhashed, never plain
roleenummanager or member, default member

tasks is the main thing. A task has a title, a description and a status that is one of pending, in-progress or done. It points at the users table twice: created_by is the manager who made it, assigned_to is the person responsible for finishing it. Keeping those two separate is where the role logic lives.

columntypenotes
idbigintprimary key
created_bybigintreferences users.id
assigned_tobigintreferences users.id, nullable
titlestring
descriptiontext
statusenumpending, in-progress, done, default pending

notifications records what changed and for whom. Whenever a task changes, the affected user gets a row here. read_at is nullable, and null means the user has not seen it yet.

columntypenotes
idbigintprimary key
user_idbigintreferences users.id
task_idbigintreferences tasks.id
messagestring
read_attimestampnullable, null means unread

So a user has many tasks they created, many tasks assigned to them, and many notifications. That is the whole model.

Check Go and install the Goravel CLI

Watch this part

Goravel v1.17 needs Go 1.24 or newer. The video says 1.23; the framework’s own go.mod says 1.24, so go with 1.24.

go version

If Go is missing or older, install the current release from go.dev. It takes a couple of minutes.

Goravel ships an installer, the same idea as the Laravel installer.

go install github.com/goravel/installer/goravel@latest
goravel

If you see a help screen, it worked. If you see command not found, the Go binary directory is not on your PATH. Add this to your shell config, then restart the terminal:

export PATH=$PATH:$(go env GOPATH)/bin

Create the project

Watch this part

goravel new

The installer walks you through a few questions.

  1. Project name: taskflow.
  2. Version: pick Goravel Lite. Since v1.17 there is a slimmer skeleton where you choose only the facades you need. The full version installs everything.
  3. Module name: taskflow. This is the module line in go.mod; it usually matches the repository name.

It clones the skeleton and downloads dependencies. Because we chose Lite, it then asks which facades to install. Lite always includes the essentials (App, Artisan, Config, Session, Validation, View and a few more); these are the ones we add for TaskFlow:

  • Route, to define API routes
  • Auth, for login
  • Cache, for caching support
  • DB and ORM, for database access and queries
  • Gate, for authorization rules
  • Hash, for hashing passwords
  • HTTP, for requests and responses
  • Log, for application logging
  • Queue, for background jobs
  • Schema, for migrations

Then the drivers:

  • Cache: Redis. The memory driver keeps data inside the process and loses it on every restart.
  • Session: Redis, since it is already there. File works too.
  • Route: Gin. Fiber is also supported and the Goravel code barely changes between them.
  • Database: Postgres. Reliable, common, and fine in production. MySQL, SQL Server and SQLite are also supported.
  • Queue: Redis. Sync runs jobs inline, database stores them in a table, Redis is the usual choice for real queues.

The project structure

Watch this part

If you know Laravel this will look familiar.

  • app/ is the application: controllers, models, jobs, services. It also holds the facades, installed locally, so you can rename them or add your own. Most of the work happens here.
  • bootstrap/app.go is startup: service providers, route registration, migrations.
  • config/ has a file per installed facade. You rarely edit these directly; they read from .env.
  • routes/ holds the route files. It starts with web.go; we add more in later episodes.
  • main.go is the entry point. It boots the app using bootstrap.Boot() and starts the server.

Postgres and Redis with Docker Compose

Watch this part

We chose Postgres and Redis, so we need both running. The app itself runs directly with Go, not inside Docker. That keeps the feedback loop fast and avoids port fights. Docker only runs the two services.

The skeleton ships a docker-compose.yml. Replace its contents with the two services:

version: '3'

services:
  postgres:
    image: postgres:15-alpine
    restart: always
    environment:
      POSTGRES_DB: taskflow
      POSTGRES_USER: goravel
      POSTGRES_PASSWORD: secret
    ports:
      - "5433:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data

  redis:
    image: redis:alpine
    restart: always
    ports:
      - "6380:6379"
    volumes:
      - redis_data:/data

volumes:
  postgres_data:
  redis_data:

Two things worth knowing. The port mapping is host:container. I already have Postgres on 5432 and Redis on 6379 locally, so I map 5433 and 6380 on the host to the standard ports inside the containers. If you have nothing running on those ports, 5432:5432 and 6379:6379 are simpler. And the named volumes keep the data on disk, so stopping or recreating a container does not wipe the database.

Start them in the background:

docker compose up -d
docker ps

You should see two containers, each on the host port you mapped.

Environment configuration

Watch this part

Whatever you put in docker-compose.yml goes into .env:

DB_HOST=127.0.0.1
DB_PORT=5433
DB_DATABASE=taskflow
DB_USERNAME=goravel
DB_PASSWORD=secret

REDIS_HOST=127.0.0.1
REDIS_PASSWORD=
REDIS_PORT=6380

Run it

Watch this part

go run .

It picks up main.go, connects to Redis, and serves on port 3000. Open http://localhost:3000 and you get the Goravel welcome page. Stop it with Ctrl+C.

One more thing before we leave. Goravel has an Artisan command system, like Laravel’s:

go run . artisan

That lists everything: db commands, make commands for generating code, migrate commands, and more. We lean on these constantly in the episodes ahead.

Next episode: routing, responses, and a hot-reloading server so we stop restarting by hand.