diff --git a/Makefile b/Makefile index 8a86607..5030396 100644 --- a/Makefile +++ b/Makefile @@ -84,3 +84,32 @@ release-dry: .PHONY: release release: goreleaser --parallelism 1 --rm-dist --skip-validate + +# Build local docker images for development. +.PHONY: build-dev-docker +build-dev-docker: build ## Build docker containers for the entire suite (Front/Core/PG). + cd dev; \ + docker-compose build ; \ + +# Spin a local docker suite for local development. +.PHONY: dev-docker +dev-docker: build-dev-docker ## Build and spawns docker containers for the entire suite (Front/Core/PG). + cd dev; \ + docker-compose up + +# Run the backend in docker-dev mode. The frontend assets in dev mode are loaded from disk from frontend/dist. +.PHONY: run-backend-docker +run-backend-docker: + CGO_ENABLED=0 go run -ldflags="-s -w -X 'main.buildString=${BUILDSTR}' -X 'main.versionString=${VERSION}' -X 'main.frontendDir=frontend/dist'" cmd/*.go --config=dev/config.toml + +# Tear down the complete local development docker suite. +.PHONY: rm-dev-docker +rm-dev-docker: build ## Delete the docker containers including DB volumes. + cd dev; \ + docker-compose down -v ; \ + +# Setup the db for local dev docker suite. +.PHONY: init-dev-docker +init-dev-docker: build-dev-docker ## Delete the docker containers including DB volumes. + cd dev; \ + docker-compose run --rm backend sh -c "make dist && yes | ./listmonk --install --config dev/config.toml" diff --git a/dev/README.md b/dev/README.md new file mode 100644 index 0000000..e16e3c2 --- /dev/null +++ b/dev/README.md @@ -0,0 +1,43 @@ +# Docker suite for development + +**NOTE**: This exists only for local development. If you're interested in using Docker for a production setup, visit the [docs](https://listmonk.app/docs/installation/#docker) instead. + +### Objective + +The purpose of this docker suite for local development is to isolate all the dev dependencies in a docker environment. The containers have a host volume mounted inside for the entire app directory. This helps us to not do a full `docker build` for every single local change, only restarting the docker environment is enough. + +## Setting up a dev suite + +To spin up a local suite of + +- PostgreSQL +- Mailhog +- Node.js frontend app +- Golang backend app + +### Setup DB + +```bash +make init-dev-docker +``` + +### Start frontend and backend apps + +```bash +make dev-docker +``` + +Visit `http://localhost:8080` on your browser. + +### Tear down + +This will tear down all the data, including DB. + +```bash +make rm-dev-docker +``` + +### See local changes in action + +- Backend: Anytime you do a change to the Go app, it needs to be compiled. Just run `make dev-docker` again and that should automatically handle it for you. +- Frontend: Anytime you change the frontend code, you don't need to do anything. Since `yarn` is watching for all the changes and we have mounted the code inside the docker container, `yarn` server automatically restarts. diff --git a/dev/app.Dockerfile b/dev/app.Dockerfile new file mode 100644 index 0000000..3544705 --- /dev/null +++ b/dev/app.Dockerfile @@ -0,0 +1,11 @@ +FROM golang:1.17 AS go + +FROM node:16 AS node + +COPY --from=go /usr/local/go /usr/local/go +ENV GOPATH /go +ENV CGO_ENABLED=0 +ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH + +WORKDIR /app +ENTRYPOINT [ "" ] diff --git a/dev/docker-compose.yml b/dev/docker-compose.yml new file mode 100644 index 0000000..846cf0c --- /dev/null +++ b/dev/docker-compose.yml @@ -0,0 +1,61 @@ +version: "3" + +services: + mailhog: + image: mailhog/mailhog:v1.0.1 + ports: + - "1025:1025" # SMTP + - "8025:8025" # UI + + db: + image: postgres:13 + ports: + - "5432:5432" + networks: + - listmonk-dev + environment: + - POSTGRES_PASSWORD=listmonk-dev + - POSTGRES_USER=listmonk-dev + - POSTGRES_DB=listmonk-dev + restart: unless-stopped + volumes: + - type: volume + source: listmonk-dev-db + target: /var/lib/postgresql/data + + front: + build: + context: ../ + dockerfile: dev/app.Dockerfile + command: ["make", "run-frontend"] + ports: + - "8080:8080" + environment: + - LISTMONK_API_URL=http://backend:9000 + depends_on: + - db + volumes: + - ../:/app + networks: + - listmonk-dev + + backend: + build: + context: ../ + dockerfile: dev/app.Dockerfile + command: ["make", "run-backend-docker"] + ports: + - "9000:9000" + depends_on: + - db + volumes: + - ../:/app + - $GOPATH/pkg/mod/cache:/go/pkg/mod/cache + networks: + - listmonk-dev + +volumes: + listmonk-dev-db: + +networks: + listmonk-dev: