Golang + vue.js + nginx + docker-compose + github action
.
├── 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
Two braches test and master (prod) enviroment.
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
.
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)
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;
...
....
I created three dockerfile Dockerfile{,contractTests,e2e} for frontend. Because of this I can easily builds according to the enviroment.
I used multi-stage build for my dockerfiles to reduce produced image size.
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
..
Terminated.
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 ./...
[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
$ docker-compose -f docker-compose-{test,prod}.yml up --build -d