init
This commit is contained in:
44
Dockerfile
Normal file
44
Dockerfile
Normal file
@ -0,0 +1,44 @@
|
||||
# Use Alpine as the base image
|
||||
FROM alpine:3.20.2
|
||||
|
||||
# Install necessary packages & Go
|
||||
RUN apk add --no-cache \
|
||||
alpine-base \
|
||||
logrotate \
|
||||
dcron \
|
||||
go \
|
||||
s6-overlay
|
||||
|
||||
# Set up the s6-overlay configuration
|
||||
COPY etc /etc
|
||||
|
||||
# Set up Go environment
|
||||
ENV GOPATH /go
|
||||
ENV PATH $GOPATH/bin:/usr/local/go/bin:$PATH
|
||||
|
||||
# Copy the Go application
|
||||
COPY main.go /app/main.go
|
||||
|
||||
# Build the Go application
|
||||
RUN go build -o /usr/local/bin/myapp /app/main.go
|
||||
|
||||
# Set up syslog
|
||||
#COPY syslog.conf /etc/syslog.conf
|
||||
#RUN mkdir -p /var/log/syslog
|
||||
|
||||
# Set up logrotate
|
||||
#COPY logrotate.conf /etc/logrotate.conf
|
||||
|
||||
# Set up watchdog
|
||||
#COPY watchdog.conf /etc/watchdog.conf
|
||||
|
||||
# Copy your application
|
||||
# COPY myapp /usr/local/bin/myapp
|
||||
|
||||
# Set up s6 service for your app
|
||||
#COPY run /etc/services.d/myapp/run
|
||||
|
||||
ENV LOG_LEVEL=WARNING
|
||||
|
||||
# Use s6-overlay as the entrypoint
|
||||
ENTRYPOINT ["/init"]
|
||||
17
README.md
Normal file
17
README.md
Normal file
@ -0,0 +1,17 @@
|
||||
# Alpine with S6-Overlay
|
||||
|
||||
I want a docker image that behaves more like a VM:
|
||||
|
||||
1. I can start / stop many processes, also the main process (usually PID 1)
|
||||
Why? To test things out. Changing environment variables, debugging with the coredump file or recompiling the app without crashing the container follows much more my development process
|
||||
2. Logging to a seperate file with logrotation
|
||||
Why? Docker logs (and Kibana) are a pain in the ass!
|
||||
3. Watchdog: k8s restarts containers when they are crashing. That should be done by the s6-overlay.
|
||||
|
||||
## Tested
|
||||
|
||||
- [x] Starting & Stopping services with `s6-rc start myapp` and `s6-rc stop myapp`
|
||||
- [x] `docker exec` into the container and run myapp manually, it uses the env vars of the shell
|
||||
- [x] Logging: `/var/log/myapp/current` is filled
|
||||
- [ ] Logrotation
|
||||
- [ ] Cron
|
||||
1
etc/s6-overlay/s6-rc.d/myapp-log-prepare/type
Normal file
1
etc/s6-overlay/s6-rc.d/myapp-log-prepare/type
Normal file
@ -0,0 +1 @@
|
||||
oneshot
|
||||
3
etc/s6-overlay/s6-rc.d/myapp-log-prepare/up
Executable file
3
etc/s6-overlay/s6-rc.d/myapp-log-prepare/up
Executable file
@ -0,0 +1,3 @@
|
||||
if { mkdir -p /var/log/myapp }
|
||||
if { chown nobody:nogroup /var/log/myapp }
|
||||
chmod 02755 /var/log/myapp
|
||||
1
etc/s6-overlay/s6-rc.d/myapp-log/consumer-for
Normal file
1
etc/s6-overlay/s6-rc.d/myapp-log/consumer-for
Normal file
@ -0,0 +1 @@
|
||||
myapp
|
||||
1
etc/s6-overlay/s6-rc.d/myapp-log/pipeline-name
Normal file
1
etc/s6-overlay/s6-rc.d/myapp-log/pipeline-name
Normal file
@ -0,0 +1 @@
|
||||
myapp-pipeline
|
||||
2
etc/s6-overlay/s6-rc.d/myapp-log/run
Executable file
2
etc/s6-overlay/s6-rc.d/myapp-log/run
Executable file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
exec logutil-service /var/log/myapp
|
||||
1
etc/s6-overlay/s6-rc.d/myapp-log/type
Normal file
1
etc/s6-overlay/s6-rc.d/myapp-log/type
Normal file
@ -0,0 +1 @@
|
||||
longrun
|
||||
0
etc/s6-overlay/s6-rc.d/myapp/dependencies.d/base
Normal file
0
etc/s6-overlay/s6-rc.d/myapp/dependencies.d/base
Normal file
9
etc/s6-overlay/s6-rc.d/myapp/finish
Executable file
9
etc/s6-overlay/s6-rc.d/myapp/finish
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
|
||||
if test "$1" -eq 256 ; then
|
||||
e=$((128 + $2))
|
||||
else
|
||||
e="$1"
|
||||
fi
|
||||
|
||||
echo "$e" > /run/s6-linux-init-container-results/exitcode
|
||||
1
etc/s6-overlay/s6-rc.d/myapp/producer-for
Normal file
1
etc/s6-overlay/s6-rc.d/myapp/producer-for
Normal file
@ -0,0 +1 @@
|
||||
myapp-log
|
||||
3
etc/s6-overlay/s6-rc.d/myapp/run
Executable file
3
etc/s6-overlay/s6-rc.d/myapp/run
Executable file
@ -0,0 +1,3 @@
|
||||
#!/command/with-contenv sh
|
||||
exec 2>&1
|
||||
exec s6-setuidgid daemon /usr/local/bin/myapp
|
||||
1
etc/s6-overlay/s6-rc.d/myapp/type
Normal file
1
etc/s6-overlay/s6-rc.d/myapp/type
Normal file
@ -0,0 +1 @@
|
||||
longrun
|
||||
0
etc/s6-overlay/s6-rc.d/user/contents.d/myapp
Normal file
0
etc/s6-overlay/s6-rc.d/user/contents.d/myapp
Normal file
26
main.go
Normal file
26
main.go
Normal file
@ -0,0 +1,26 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Configure logging to include timestamp
|
||||
log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds)
|
||||
|
||||
// Read LOG_LEVEL from environment variable
|
||||
logLevel := os.Getenv("LOG_LEVEL")
|
||||
if logLevel == "" {
|
||||
logLevel = "INFO" // Default log level
|
||||
}
|
||||
|
||||
log.Printf("Starting application with LOG_LEVEL: %s", logLevel)
|
||||
|
||||
// Infinite loop to log every 2 seconds
|
||||
for {
|
||||
log.Printf("Current LOG_LEVEL: %s", logLevel)
|
||||
time.Sleep(2 * time.Second)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user