There are some ways to automatically reload Go apps while developing, to not have to manually stop your app, build it, run it. Recently I ran into this article about a nice tool called Fresh.
I wanted to start using live reload (or hot reload) for a project of mine, but it had a particularity which gave me troubles when I tried Fresh. My case was:
- I had a multiple apps Git repository
- The apps were sharing some packages
- If I edited app1 and the packages it used, I didn’t want both app1 and app2 to be restarted, only app1 (similar for app2)
The repository’s structure:
- /apps
- app1
- app2
- /packages
- chronos
- random
So I made an update for Fresh to support directory watch for other directories than the app’s. And I’ve sent a pull request to the original repository. But I wanted to go with this faster, and searched for other solutions. And I’ve found fswatch.
I wanted to have everything in Docker containers. This is my Dockerfile:
FROM golang:1.10-alpine3.7 RUN apk add --update --no-cache git && \ mkdir -p $GOPATH/bin && \ go get github.com/codeskyblue/fswatch ARG APP WORKDIR /go/src/github.com/andreiavrammsd/go-live-reload/apps/${APP} COPY ./.fsw.yml /.fsw.yml RUN sed -i "s/<app>/${APP}/g" /.fsw.yml CMD fswatch -config /.fsw.yml
The config file “.fsw.yml for fswatch had some important properties:
- cmd: the command to execute after files changes
- watch_paths: the paths to watch for changes
desc: <app> triggers: - name: "" pattens: - '**/*.*' env: DEBUG: "1" cmd: cd /go/src/github.com/andreiavrammsd/go-live-reload/apps/<app> && go get -t && go vet -composites=false && go build -o /bin/<app> && /bin/<app> shell: true delay: 100ms stop_timeout: 500ms signal: KILL kill_signal: "" watch_paths: - /go/src/github.com/andreiavrammsd/go-live-reload/apps/<app> - /go/src/github.com/andreiavrammsd/go-live-reload/packages watch_depth: 1
You can see the <app> placeholder which is replaced with the app’s directory name in the Dockerfile. The app’s directory is sent as build argument in the docker compose file.
version: '3' services: app1: build: context: . args: APP: app1 volumes: - ../:/go/src/github.com/andreiavrammsd/go-live-reload restart: unless-stopped app2: build: context: . args: APP: app2 volumes: - ../:/go/src/github.com/andreiavrammsd/go-live-reload restart: unless-stopped
I just started the apps:
docker-compose up -d
And then I watched the apps logs to see how each app was restarted after its code had changed:
docker-compose logs -f
Get the full Go live reload source code on GitHub.