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.