web-based-todo-list-application

Golang + vue.js + nginx + docker-compose + github action

Stars
5

Web Based ToDo List Application

To Do List

  • 1- User interface for ONLY adding ToDo’s
  • 2- Back-end service to store a persistent state of ToDo list
  • 3- Writing deployment files of your front-end and back-end
  • 4- Automating build, test and deployment of your application via CI/CD pipeline
  • 5- Dockerize both your front-end and back-end application to make them ready for deployment.
  • 6- Deploy your application to a Kubernetes cluster or Docker Swarm or into a VM using a cloud provider
  • 7- Write deployment configurations(i.e. Kubernetes config files, Docker Swarm files etc.) for each project.

Tech Stack

Directory Structure

.
├── Dockerfile // Dockerfile backend
├── config // Config for backend
├── controllers // Backend APIs and their tests
├── docker-compose-prod.yml 
├── docker-compose-test.yml
├── frontend
│   ├── Dockerfile // Dockerfile frontend
│   ├── Dockerfile-contractTests // Dockerfile apiblueprint dredd
│   ├── Dockerfile-e2e // Dockerfile cypress
│   ├── api-description.apib 
│   ├── cypress.json
│   ├── dredd.yml // Dredd settings
│   ├── nginx-prod.conf 
│   ├── nginx-test.conf
│   ├── src
│   ├────── App.vue // App Todo UI
│   ├────── api.js // Axios API Calls
│   └── main.js
│   ├── tests
│   ├────── e2e
│   └────── unit
├── go.mod
├── go.sum
├── main.go

Architecture Decision

  1. Two braches test and master (prod) enviroment.

  2. I could use embed directive in Golang to serve static app files (Vue). But I wanted to learn nginx+vue+go stack and implement. Because of this I did not use embed.

  3. I used two different servers for test and prod in aws cloud provider. I wanted to run ui acceptance test and api consumer driven contract test in live enviroment in different server. (Reason of the choosing AWS, just experience)

  4. I created two nginx-{test,prod} file because of the differentation of server name in nginx conf. With this distinction I could handle cors etc. easily

 listen       80;
 server_name  ec2-52-59-226-235.eu-central-1.compute.amazonaws.com;

 location /api/v1 {
   if ($request_method = 'OPTIONS') {
      add_header Access-Control-Allow-Origin '*' always;
      ...
      ....
  1. I created three dockerfile Dockerfile{,contractTests,e2e} for frontend. Because of this I can easily builds according to the enviroment.

  2. I used multi-stage build for my dockerfiles to reduce produced image size.

  3. I used testenv for backend, and test for frontend as build args. So, I could easily build docker images for different enviroment just a one Dockerfile.

backend:
   build:
     context: "."
     args:
       - ENV=testenv

nginx-frontend:
    build:
      context: ./frontend/
      args:
        - ENV=test

Backend Dockerfile, I gave $ENV variable from docker-compose for build different enviroments.

..
RUN go mod download
COPY . .

RUN CGO_ENABLED=0 go test --tags $ENV ./...
RUN CGO_ENABLED=0 GOOS=linux go build --tags $ENV -o main main.go
..

Frontend Dockerfile, I gave $ENV to run related vue build and load (nginx-test or nginx-prod) nginx file.

..
COPY . .
RUN npm run test:unit && npm run build-for-$ENV

FROM nginx:stable-alpine as production-stage
ARG ENV
RUN mkdir /app
COPY --from=build-stage /app/dist /app
COPY --from=build-stage /app/nginx-$ENV.conf /etc/nginx/nginx.conf
..

Pipeline automation

Terminated.

Development enviroment

With standole

For our backend app, you must give "tag" for go compiler.

$ go run --tags dev main.go

it runs :3000

For tests:

$ go test --tags dev ./...

APIs

[POST] api/v1/addTodo

$ curl -H "Content-type: application/json" localhost:3000/api/v1/getTodoList

[GET] api/v1/getTodolist

$ curl -H "Content-type: application/json" -X POST -d '{"task_description":"dummy"}' localhost:3000/api/v1/addTodo

[GET] api/v1/deleteAllTodos

$ curl -H "Content-type: application/json" localhost:3000/api/v1/deleteAllTodos

For the frontend development server you can run

$ npm run serve

it runs :8080

For Unit tests:

npm run test:unit

With Docker compose

$ docker-compose -f docker-compose-{test,prod}.yml up --build -d

Package Rankings
Top 8.17% on Proxy.golang.org