1

I've been trying to run a go script with cron under Ubuntu 16.04 Docker image. Here are the files that I've

Dockerfile

FROM couchbase

RUN apt-get update
RUN apt-get install gcc make -y
RUN apt-get install golang-1.10 git -y

ADD src/crontab.txt /crontab.txt
ADD src/backup.sh /backup.sh
ADD src/backup.go /backup.go
ADD src/file.txt /file.txt
COPY entry.sh /entry.sh

RUN chmod 755 /backup.sh /entry.sh
RUN /usr/bin/crontab /crontab.txt

RUN apt-get install vim -y

CMD ["/entry.sh"]

entry.sh

#!/bin/sh
/usr/sbin/cron -f -l 8

src/crontab.txt

* * * * * /backup.sh >> /var/log/backup.log

src/backup.sh

#!/bin/sh
chmod 666 /var/log/backup.log
/usr/lib/go-1.10/bin/go run backup.go

backup.go

package main

import (
    "log"
    "os"
    "strings"
)

func init() {
    file, err := os.OpenFile("/var/log/backup.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666)
    if err != nil {
        log.Fatal(err)
    }
    log.SetOutput(file)
}

func main() {
    log.Println("Writing log")
}

I checked and the cron task is running each minute. The go installation is there in the folder and when I exec into the container it works, but the backup.go script is not logging anything. When I trigger the script manually it works though. The container that I'm using has Ubuntu 16.04 and I want it cause I don't have to do a couchbase installation.

Lexx
  • 705
  • 2
  • 9
  • 19
  • 1
    Go doesn't have "scripts"; did you mean to compile the program in your Dockerfile? – David Maze Apr 09 '21 at 13:51
  • 4
    @mahendra Go will automatically [execute `init()` functions when a package is initialized](https://golang.org/ref/spec#Package_initialization). (But as a matter of style I'd avoid them whenever possible: this program will nearly silently fail to start up, in any context, including tests, if `/var/log` isn't writeable by the current user.) – David Maze Apr 09 '21 at 13:53
  • @DavidMaze I want to be able to execute it as I can do it locally with go run. What approach would you recommend to avoid silent fails and have some proper logging? – Lexx Apr 09 '21 at 14:06
  • compile the backup.go as a binary and try again. go build . – Eddwin Paz Apr 09 '21 at 18:50
  • @EddwinPaz tried doing go build backup.go and then ./backup, but still no result. – Lexx Apr 09 '21 at 18:55
  • the /var/log/backup.log file has no permissions try giving it permissions to write. – Eddwin Paz Apr 09 '21 at 19:24

1 Answers1

2

You can do this simpler by using a multi stage build. First use a Go image to compile a standalone executable from your src/backup.go. Then switch to a coughbase image and copy the executable from the previous step.

Dockerfile:

# use a first-stage image to build the go code
# we'll change it later
FROM golang:1.10 AS build

# for now we only need the go code
COPY src/backup.go backup.go

# build a standalone executable
RUN go build -o /backup backup.go

# switch to a second-stage production image
FROM couchbase

# setup cronjob
COPY src/crontab.txt /crontab.txt
RUN /usr/bin/crontab /crontab.txt

# copy the executable from the first stage
# into the production image
COPY --from=build /backup /backup

CMD ["/usr/sbin/cron", "-f", "-l", "8"]

src/crontab.txt:

* * * * * /backup >> /var/log/backup.log

Build and run like this:

docker build . -t backup

# start in backgroud
docker run --name backup -d test

# check if it works
docker exec backup tail -f /var/log/backup.log

On the next minute :

2021/04/09 19:05:01 Writing log
Arthur Chaloin
  • 610
  • 1
  • 5
  • 12