فهرست منبع

Revert build and distribution files to upstream

- Dockerfiles
- Scripts in docker/
- Makefile
Achilleas Koutsou 6 سال پیش
والد
کامیت
388d1f0ad4

+ 41 - 20
Dockerfile

@@ -1,32 +1,53 @@
-FROM ubuntu:16.04
-
-ENV DEBIAN_FRONTEND noninteractive
-
-RUN apt-get update &&                                   \
-    apt-get install -y --no-install-recommends          \
-                       gcc g++ libc6-dev make golang    \
-                       git git-annex openssh-server     \
-                       python-pip python-setuptools     \
-                       socat tzdata patch    \
-                       libpam0g-dev \
-    && rm -rf /var/lib/apt/lists/*
+FROM golang:alpine AS binarybuilder
+# Install build deps
+RUN apk --no-cache --no-progress add --virtual build-deps build-base git linux-pam-dev python py-pip
+WORKDIR /go/src/github.com/G-Node/gogs
+COPY . .
+RUN make build TAGS="sqlite cert pam"
+
+FROM alpine:latest
+# Install system utils & Gogs runtime dependencies
+ADD https://github.com/tianon/gosu/releases/download/1.10/gosu-amd64 /usr/sbin/gosu
+RUN chmod +x /usr/sbin/gosu \
+  && echo http://dl-2.alpinelinux.org/alpine/edge/community/ >> /etc/apk/repositories \
+  && apk --no-cache --no-progress add \
+    bash \
+    ca-certificates \
+    curl \
+    git \
+    linux-pam \
+    openssh \
+    s6 \
+    shadow \
+    socat \
+    tzdata \
+    python \
+    py-pip
 
 RUN pip install supervisor pyyaml
-
+RUN mkdir /git-annex
+ENV PATH="${PATH}:/git-annex/git-annex.linux"
+RUN apk add --no-cache git openssh curl
+RUN curl -Lo /git-annex/git-annex-standalone-amd64.tar.gz https://downloads.kitenet.net/git-annex/linux/current/git-annex-standalone-amd64.tar.gz
+RUN cd /git-annex && tar -xzf git-annex-standalone-amd64.tar.gz && rm git-annex-standalone-amd64.tar.gz
+RUN apk del --no-cache curl
+RUN ln -s /git-annex/git-annex.linux/git-annex-shell /bin/git-annex-shell
 
 ENV GOGS_CUSTOM /data/gogs
 
-COPY . /app/gogs/build
-WORKDIR /app/gogs/build
-
-RUN ./docker/build-go.sh
-RUN ./docker/build.sh
-RUN ./docker/finalize.sh
-
 # Configure LibC Name Service
 COPY docker/nsswitch.conf /etc/nsswitch.conf
 
+WORKDIR /app/gogs
+COPY docker ./docker
+COPY templates ./templates
+COPY public ./public
+COPY --from=binarybuilder /go/src/github.com/G-Node/gogs/gogs .
+
+RUN ./docker/finalize.sh
+
 # Configure Docker Container
 VOLUME ["/data"]
 EXPOSE 22 3000
 ENTRYPOINT ["/app/gogs/docker/start.sh"]
+CMD ["/bin/s6-svscan", "/app/gogs/docker/s6/"]

+ 19 - 5
Dockerfile.aarch64

@@ -3,20 +3,34 @@ FROM aarch64/alpine:3.5
 # Install system utils & Gogs runtime dependencies
 ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-arm64 /usr/sbin/gosu
 RUN chmod +x /usr/sbin/gosu \
- && apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat tzdata
+  && echo http://dl-2.alpinelinux.org/alpine/edge/community/ >> /etc/apk/repositories \
+  && apk --no-cache --no-progress add \
+    bash \
+    ca-certificates \
+    curl \
+    git \
+    linux-pam \
+    openssh \
+    s6 \
+    shadow \
+    socat \
+    tzdata
 
 ENV GOGS_CUSTOM /data/gogs
 
-COPY . /app/gogs/build
+# Configure LibC Name Service
+COPY docker/nsswitch.conf /etc/nsswitch.conf
+COPY docker /app/gogs/docker
+COPY templates /app/gogs/templates
+COPY public /app/gogs/public
+
 WORKDIR /app/gogs/build
+COPY . .
 
 RUN    ./docker/build-go.sh \
     && ./docker/build.sh \
     && ./docker/finalize.sh
 
-# Configure LibC Name Service
-COPY docker/nsswitch.conf /etc/nsswitch.conf
-
 # Configure Docker Container
 VOLUME ["/data"]
 EXPOSE 22 3000

+ 25 - 12
Dockerfile.rpi

@@ -1,24 +1,37 @@
-FROM armhf/alpine:3.5
+FROM resin/rpi-raspbian:stretch
 
-# Install system utils & Gogs runtime dependencies
-ADD https://github.com/tianon/gosu/releases/download/1.9/gosu-armhf /usr/sbin/gosu
-RUN chmod +x /usr/sbin/gosu \
- && apk --no-cache --no-progress add ca-certificates bash git linux-pam s6 curl openssh socat tzdata
+ENV DEBIAN_FRONTEND noninteractive
+ENV INITSYSTEM on
+
+RUN apt-get update &&                                   \
+    apt-get install -y --no-install-recommends          \
+                       gcc g++ libc6-dev make golang    \
+                       git git-annex openssh-server     \
+                       python-pip python-setuptools     \
+                       socat tzdata patch    \
+
+    && rm -rf /var/lib/apt/lists/*
+
+RUN pip install supervisor pyyaml
 
 ENV GOGS_CUSTOM /data/gogs
 
-COPY . /app/gogs/build
+# Configure LibC Name Service
+COPY docker/nsswitch.conf /etc/nsswitch.conf
+COPY docker /app/gogs/docker
+COPY templates /app/gogs/templates
+COPY public /app/gogs/public
+
 WORKDIR /app/gogs/build
+COPY . .
 
-RUN    ./docker/build-go.sh \
-    && ./docker/build.sh \
-    && ./docker/finalize.sh
+RUN ./docker/build-go.sh
+RUN ./docker/build.sh
+RUN ./docker/finalize.sh
 
-# Configure LibC Name Service
 COPY docker/nsswitch.conf /etc/nsswitch.conf
 
-# Configure Docker Container
 VOLUME ["/data"]
 EXPOSE 22 3000
 ENTRYPOINT ["/app/gogs/docker/start.sh"]
-CMD ["/bin/s6-svscan", "/app/gogs/docker/s6/"]
+

+ 4 - 4
Makefile

@@ -30,7 +30,7 @@ web: build
 
 govet:
 	$(GOVET) gogs.go
-	$(GOVET) models pkg routers
+	$(GOVET) models pkg routes
 
 build: $(GENERATED)
 	go install $(BUILD_FLAGS) -ldflags '$(LDFLAGS)' -tags '$(TAGS)'
@@ -56,12 +56,12 @@ release: build pack
 bindata: pkg/bindata/bindata.go
 
 pkg/bindata/bindata.go: $(DATA_FILES)
-	go-bindata -o=$@ -ignore="\\.DS_Store|README.md|TRANSLATORS" -pkg=bindata conf/...
+	go-bindata -o=$@ -ignore="\\.DS_Store|README.md|TRANSLATORS|auth.d" -pkg=bindata conf/...
 
 less: public/css/gogs.css
 
 public/css/gogs.css: $(LESS_FILES)
-	lessc $< $@
+	@type lessc >/dev/null 2>&1 && lessc $< >$@ || echo "lessc command not found, skipped."
 
 clean:
 	go clean -i ./...
@@ -80,4 +80,4 @@ todo:
 
 # Legacy code should be remove by the time of release
 legacy:
-	grep -rnw "LEGACY" cmd routers models pkg
+	grep -rnw "LEGACY" cmd routes models pkg

+ 7 - 3
docker/README.md

@@ -1,6 +1,6 @@
 # Docker for Gogs
 
-Visit [Docker Hub](https://hub.docker.com/r/gogs/) / [Docker Store](https://store.docker.com/community/images/gogs/gogs) see all available images and tags.
+Visit [Docker Cloud](https://cloud.docker.com/swarm/gogs/repository/docker/gogs/gogs) / [Docker Store](https://store.docker.com/community/images/gogs/gogs) see all available images and tags.
 
 ## Usage
 
@@ -36,6 +36,10 @@ Directory `/var/gogs` keeps Git repositories and Gogs data:
         |-- data
         |-- log
 
+#### Custom Directory
+
+The "custom" directory may not be obvious in Docker environment. The `/var/gogs/gogs` (in the host) and `/data/gogs` (in the container) is already the "custom" directory and you do not need to create another layer but directly edit corresponding files under this directory.
+
 ### Volume With Data Container
 
 If you're more comfortable with mounting data to a data container, the commands you execute at the first time will look like as follows:
@@ -104,11 +108,11 @@ Steps to upgrade Gogs with Docker:
 - `docker pull gogs/gogs`
 - `docker stop gogs`
 - `docker rm gogs`
-- Finally, create container as the first time and don't forget to do same volume and port mapping.
+- Finally, create a container for the first time and don't forget to do the same for the volume and port mapping.
 
 ## Known Issues
 
-- The docker container can not currently be build on Raspberry 1 (armv6l) as our base image `alpine` does not have a `go` package available for this platform.
+- The docker container cannot currently be built on Raspberry 1 (armv6l) as our base image `alpine` does not have a `go` package available for this platform.
 
 ## Useful Links
 

+ 3 - 0
docker/aarch64/build.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+go build -ldflags "-w -s" resin-xbuild.go

BIN
docker/aarch64/qemu-aarch64-static


BIN
docker/aarch64/resin-xbuild


+ 66 - 0
docker/aarch64/resin-xbuild.go

@@ -0,0 +1,66 @@
+package main
+
+import (
+	"log"
+	"os"
+	"os/exec"
+	"syscall"
+)
+
+func crossBuildStart() {
+	err := os.Remove("/bin/sh")
+	if err != nil {
+		log.Fatal(err)
+	}
+	err = os.Link("/usr/bin/resin-xbuild", "/bin/sh")
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func crossBuildEnd() {
+	err := os.Remove("/bin/sh")
+	if err != nil {
+		log.Fatal(err)
+	}
+	err = os.Link("/bin/sh.real", "/bin/sh")
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func runShell() error {
+	cmd := exec.Command("/usr/bin/qemu-aarch64-static", append([]string{"-0", "/bin/sh", "/bin/sh"}, os.Args[1:]...)...)
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	return cmd.Run()
+}
+
+func main() {
+	switch os.Args[0] {
+	case "cross-build-start":
+		crossBuildStart()
+	case "cross-build-end":
+		crossBuildEnd()
+	case "/bin/sh":
+		code := 0
+		crossBuildEnd()
+
+		if err := runShell(); err != nil {
+			code = 1
+			if exiterr, ok := err.(*exec.ExitError); ok {
+				if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
+					code = status.ExitStatus()
+				}
+			}
+		}
+
+		crossBuildStart()
+
+		// Hack to bypass apk issues with triggering
+		code = 0
+
+		os.Exit(code)
+	}
+}

+ 3 - 0
docker/armhf/build.sh

@@ -0,0 +1,3 @@
+#!/bin/bash
+
+go build -ldflags "-w -s" resin-xbuild.go

BIN
docker/armhf/qemu-arm-static


BIN
docker/armhf/resin-xbuild


+ 66 - 0
docker/armhf/resin-xbuild.go

@@ -0,0 +1,66 @@
+package main
+
+import (
+	"log"
+	"os"
+	"os/exec"
+	"syscall"
+)
+
+func crossBuildStart() {
+	err := os.Remove("/bin/sh")
+	if err != nil {
+		log.Fatal(err)
+	}
+	err = os.Link("/usr/bin/resin-xbuild", "/bin/sh")
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func crossBuildEnd() {
+	err := os.Remove("/bin/sh")
+	if err != nil {
+		log.Fatal(err)
+	}
+	err = os.Link("/bin/sh.real", "/bin/sh")
+	if err != nil {
+		log.Fatal(err)
+	}
+}
+
+func runShell() error {
+	cmd := exec.Command("/usr/bin/qemu-arm-static", append([]string{"-0", "/bin/sh", "/bin/sh"}, os.Args[1:]...)...)
+	cmd.Stdin = os.Stdin
+	cmd.Stdout = os.Stdout
+	cmd.Stderr = os.Stderr
+	return cmd.Run()
+}
+
+func main() {
+	switch os.Args[0] {
+	case "cross-build-start":
+		crossBuildStart()
+	case "cross-build-end":
+		crossBuildEnd()
+	case "/bin/sh":
+		code := 0
+		crossBuildEnd()
+
+		if err := runShell(); err != nil {
+			code = 1
+			if exiterr, ok := err.(*exec.ExitError); ok {
+				if status, ok := exiterr.Sys().(syscall.WaitStatus); ok {
+					code = status.ExitStatus()
+				}
+			}
+		}
+
+		crossBuildStart()
+
+		// Hack to bypass apk issues with triggering
+		code = 0
+
+		os.Exit(code)
+	}
+}

+ 2 - 0
docker/build-go.sh

@@ -11,6 +11,7 @@ export GOLANG_SRC_SHA256="406865f587b44be7092f206d73fc1de252600b79b3cacc587b74b5
 
 
 # Install build tools
+apk add --no-cache --no-progress --virtual build-deps-go gcc musl-dev openssl go
 
 export GOROOT_BOOTSTRAP="$(go env GOROOT)"
 
@@ -28,3 +29,4 @@ patch -p2 -i /app/gogs/build/docker/no-pic.patch
 
 # Clean
 rm /app/gogs/build/docker/*.patch
+apk del build-deps-go

+ 12 - 14
docker/build.sh

@@ -5,18 +5,14 @@ set -e
 # Set temp environment vars
 export GOPATH=/tmp/go
 export PATH=/usr/local/go/bin:${PATH}:${GOPATH}/bin
-export GO15VENDOREXPERIMENT=1
 
-#
-go get golang.org/x/crypto/bcrypt
-go get github.com/jteeuwen/go-bindata
-cd ${GOPATH}/src/github.com/jteeuwen/go-bindata/go-bindata
-go install
+# Install build deps
+apk --no-cache --no-progress add --virtual build-deps build-base linux-pam-dev
 
 # Build Gogs
-mkdir -p ${GOPATH}/src/github.com/G-Node/
-ln -s /app/gogs/build ${GOPATH}/src/github.com/G-Node/gogs
-cd ${GOPATH}/src/github.com/G-Node/gogs
+mkdir -p ${GOPATH}/src/github.com/gogs/
+ln -s /app/gogs/build ${GOPATH}/src/github.com/gogs/gogs
+cd ${GOPATH}/src/github.com/gogs/gogs
 # Needed since git 2.9.3 or 2.9.4
 git config --global http.https://gopkg.in.followRedirects true
 make build TAGS="sqlite cert pam"
@@ -24,10 +20,12 @@ make build TAGS="sqlite cert pam"
 # Cleanup GOPATH
 rm -r $GOPATH
 
+# Remove build deps
+apk --no-progress del build-deps
 
-# Create git user for Gogs
+# Move to final place
+mv /app/gogs/build/gogs /app/gogs/
 
-addgroup  git
-adduser --home /data/git --shell /bin/sh --ingroup git --disabled-password git
-passwd -d git
-echo "export GOGS_CUSTOM=${GOGS_CUSTOM}" >> /etc/profile
+# Cleanup go
+rm -rf /tmp/go
+rm -rf /usr/local/go

+ 4 - 8
docker/finalize.sh

@@ -4,11 +4,10 @@
 set -x
 set -e
 
-# Move to final place
-mv /app/gogs/build/gogs /app/gogs/
-mv /app/gogs/build/templates /app/gogs/
-mv /app/gogs/build/public /app/gogs/
-mv /app/gogs/build/docker /app/gogs/
+# Create git user for Gogs
+addgroup -S git
+adduser -G git -H -D -g 'Gogs Git User' git -h /data/git -s /bin/bash && usermod -p '*' git && passwd -u git
+echo "export GOGS_CUSTOM=${GOGS_CUSTOM}" >> /etc/profile
 
 # Final cleaning
 rm -rf /app/gogs/build
@@ -17,6 +16,3 @@ rm /app/gogs/docker/build-go.sh
 rm /app/gogs/docker/finalize.sh
 rm /app/gogs/docker/nsswitch.conf
 rm /app/gogs/docker/README.md
-
-rm -rf /tmp/go
-rm -rf /usr/local/go

+ 1 - 1
docker/no-pic.patch

@@ -13,4 +13,4 @@ index 14f4fa9..5599307 100644
 +
  	if l.Debugvlog != 0 {
  		l.Logf("%5.2f host link:", obj.Cputime())
- 		for _, v := range argv {
+ 		for _, v := range argv {

+ 7 - 4
docker/s6/gogs/setup

@@ -13,11 +13,14 @@ fi
 cd /app/gogs
 
 # Link volumed data with app data
-ln -sf /data/gogs/log  ./log
-ln -sf /data/gogs/data ./data
+ln -sfn /data/gogs/log  ./log
+ln -sfn /data/gogs/data ./data
 
 # Backward Compatibility with Gogs Container v0.6.15
-ln -sf /data/git /home/git
+ln -sfn /data/git /home/git
 
-chown -R git:git /data /app/gogs ~git/
+# Only chown for the first time, '/data/gogs/conf/app.ini' must exist inside Docker after installation
+if ! test -d /data/gogs/conf/app.ini; then
+	chown -R git:git /data /app/gogs ~git/
+fi
 chmod 0755 /data /data/gogs ~git/

+ 0 - 1
docker/sshd_config

@@ -11,6 +11,5 @@ HostKey /data/ssh/ssh_host_ed25519_key
 PermitRootLogin no
 AuthorizedKeysFile	.ssh/authorized_keys
 PasswordAuthentication no
-UsePrivilegeSeparation no
 PermitUserEnvironment yes
 AllowUsers git

+ 61 - 63
docker/start.sh

@@ -1,75 +1,73 @@
 #!/bin/sh
 
-# directory setup
-mkdir -p /data/ssh
-mkdir -p /data/gogs/log
-mkdir -p /data/gogs/data
+create_socat_links() {
+    # Bind linked docker container to localhost socket using socat
+    USED_PORT="3000:22"
+    while read NAME ADDR PORT; do
+        if test -z "$NAME$ADDR$PORT"; then
+            continue
+        elif echo $USED_PORT | grep -E "(^|:)$PORT($|:)" > /dev/null; then
+            echo "init:socat  | Can't bind linked container ${NAME} to localhost, port ${PORT} already in use" 1>&2
+        else
+            SERV_FOLDER=/app/gogs/docker/s6/SOCAT_${NAME}_${PORT}
+            mkdir -p ${SERV_FOLDER}
+            CMD="socat -ls TCP4-LISTEN:${PORT},fork,reuseaddr TCP4:${ADDR}:${PORT}"
+            echo -e "#!/bin/sh\nexec $CMD" > ${SERV_FOLDER}/run
+            chmod +x ${SERV_FOLDER}/run
+            USED_PORT="${USED_PORT}:${PORT}"
+            echo "init:socat  | Linked container ${NAME} will be binded to localhost on port ${PORT}" 1>&2
+        fi
+    done << EOT
+    $(env | sed -En 's|(.*)_PORT_([0-9]+)_TCP=tcp://(.*):([0-9]+)|\1 \3 \4|p')
+EOT
+}
 
-#SSH setup
-# Check if host keys are present, else create them
-if ! test -f /data/ssh/ssh_host_rsa_key; then
-    ssh-keygen -q -f /data/ssh/ssh_host_rsa_key -N '' -t rsa
-fi
-
-if ! test -f /data/ssh/ssh_host_dsa_key; then
-    ssh-keygen -q -f /data/ssh/ssh_host_dsa_key -N '' -t dsa
-fi
-
-if ! test -f /data/ssh/ssh_host_ecdsa_key; then
-    ssh-keygen -q -f /data/ssh/ssh_host_ecdsa_key -N '' -t ecdsa
-fi
-
-if ! test -f /data/ssh/ssh_host_ed25519_key; then
-    ssh-keygen -q -f /data/ssh/ssh_host_ed25519_key -N '' -t ed25519
-fi
+cleanup() {
+    # Cleanup SOCAT services and s6 event folder
+    # On start and on shutdown in case container has been killed
+    rm -rf $(find /app/gogs/docker/s6/ -name 'event')
+    rm -rf /app/gogs/docker/s6/SOCAT_*
+}
 
-if ! test -d ~git/.ssh; then
-    mkdir -p ~git/.ssh
-    chmod 700 ~git/.ssh
-fi
+create_volume_subfolder() {
+    # Create VOLUME subfolder
+    for f in /data/gogs/data /data/gogs/conf /data/gogs/log /data/git /data/ssh; do
+        if ! test -d $f; then
+            mkdir -p $f
+        fi
+    done
+}
 
-#Gogs setup
-if ! test -f ~git/.ssh/environment; then
-    echo "GOGS_CUSTOM=${GOGS_CUSTOM}" > ~git/.ssh/environment
-    chmod 600 ~git/.ssh/environment
-fi
+setids() {
+    PUID=${PUID:-1000}
+    PGID=${PGID:-1000}
+    groupmod -o -g "$PGID" git
+    usermod -o -u "$PUID" git
+}
 
-cd /app/gogs
+setids
+cleanup
+create_volume_subfolder
 
-# check authorized keys
-if ! test -f /data/git/.ssh/authorized_keys; then
-    echo "" > /data/git/.ssh/authorized_keys
-fi
-# check authorized keys
-if ! test -d /data/.ssh; then
-    mkdir -p /data/.ssh
+LINK=$(echo "$SOCAT_LINK" | tr '[:upper:]' '[:lower:]')
+if [ "$LINK" = "false" -o "$LINK" = "0" ]; then
+    echo "init:socat  | Will not try to create socat links as requested" 1>&2
+else
+    create_socat_links
 fi
 
-# Link volumed data with app data
-ln -sf /data/gogs/log  ./log
-ln -sf /data/gogs/data ./data
-ln -s /data/git/.ssh/authorized_keys /data/.ssh/authorized_keys
-
-# Backward Compatibility with Gogs Container v0.6.15
-ln -sf /data/git /home/git
-
-# check whether we nedd to reset userid
-if [ ! -z "$GITUID" ]; then
-    echo "change git user id to $GITUID"
-    usermod -u "$GITUID" git
+CROND=$(echo "$RUN_CROND" | tr '[:upper:]' '[:lower:]')
+if [ "$CROND" = "true" -o "$CROND" = "1" ]; then
+    echo "init:crond  | Cron Daemon (crond) will be run as requested by s6" 1>&2
+    rm -f /app/gogs/docker/s6/crond/down
+else
+    # Tell s6 not to run the crond service
+    touch /app/gogs/docker/s6/crond/down
 fi
-if [ ! -z "$GITGID" ]; then
-    echo "change git group id to $GITGID"
-    groupmod -g "$GITGID" git
-fi
-
-chown -R git:git /data /app/gogs ~git/
-chmod 0755 /data /data/gogs ~git/
 
-# Set correct right to ssh keys
-chown -R root:root /data/ssh/*
-chmod 0700 /data/ssh
-chmod 0600 /data/ssh/*
 # Exec CMD or S6 by default if nothing present
-supervisord -c /app/gogs/docker/supervisord.conf
-
+if [ $# -gt 0 ];then
+    exec "$@"
+else
+    exec /bin/s6-svscan /app/gogs/docker/s6/
+fi

+ 1 - 0
docker/supervisord.conf

@@ -16,3 +16,4 @@ stdout_logfile=/dev/stdout
 stdout_logfile_maxbytes=0
 stderr_logfile=/dev/stderr
 stderr_logfile_maxbytes=0
+autorestart = true