commit 99e2cd23f3175639cdc7b544528515f2bfed62b3 Author: Simon Rieger Date: Thu Jan 11 22:23:10 2024 +0100 First Commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..ea85cb6 --- /dev/null +++ b/README.md @@ -0,0 +1,63 @@ +# Picture Uploader + +This project is a simple web application written in Go for uploading and viewing images. + +## Getting Started + +To run this application, follow the steps below: + +### Prerequisites + +- [Docker](https://www.docker.com/) +- [docker-compose](https://docs.docker.com/compose/) + +### Instructions + +1. Clone the repository: + + ```bash + git clone + ``` + +2. Navigate to the project directory: + + ```bash + cd + ``` + +3. Create a folder named `uploads`: + + ```bash + mkdir uploads + ``` + +4. Set permissions for the `uploads` folder: + + ```bash + chmod 777 uploads + ``` + +5. Run the application using Docker Compose: + + ```bash + docker-compose up -d + ``` + +The application should be accessible at [http://localhost:8080](http://localhost:8080). + +## Configuration + +Modify the `docker-compose.yml` file to adjust environment variables, ports, or any other configurations as needed. + +## Additional Information + +- This project uses NGINX as a reverse proxy. Ensure that the required networks (`nginx-proxy` and `edge`) are set up externally or adjust the `docker-compose.yml` accordingly. +- If you encounter issues with image uploads, verify the permissions on the `uploads` folder. + +### Support and Issues + +For support or to report issues, please [open an issue](/issues). + +### License + +This project is licensed under the [MIT License](LICENSE). diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100755 index 0000000..006363c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,41 @@ +version: "3.9" + +services: + +# Go application service + go-app: + build: + context: go/. + args: + - GO111MODULE=on + #ports: + # - "8080:8080" + environment: + - VIRTUAL_HOST=pick.brothertec.eu + - VIRTUAL_PORT=8080 + - LETSENCRYPT_HOST=pick.brothertec.eu + - LETSENCRYPT_EMAIL=admin@brothertec.eu + + volumes: + - ./uploads:/uploads + + restart: always + + labels: + - flame.type=application + - flame.name=Picture Upload + - flame.url=https://pick.brothertec.eu + - flame.icon=image + + networks: + default: + proxy: + edge-tier: + +networks: + proxy: + name: nginx-proxy + external: true + edge-tier: + name: edge + external: true diff --git a/go/Dockerfile b/go/Dockerfile new file mode 100755 index 0000000..612122a --- /dev/null +++ b/go/Dockerfile @@ -0,0 +1,30 @@ +# syntax=docker/dockerfile:1 + +# Build the application from source +FROM golang:1.21.4 AS build-stage + +WORKDIR /app + +COPY go.mod ./ +RUN go mod download + +COPY *.go ./ + +RUN CGO_ENABLED=0 GOOS=linux go build -o /picture-uploader + +# Run the tests in the container +FROM build-stage AS run-test-stage +RUN go test -v ./... + +# Deploy the application binary into a lean image +FROM gcr.io/distroless/base-debian11 AS build-release-stage + +WORKDIR / + +COPY --from=build-stage /picture-uploader /picture-uploader + +EXPOSE 8080 + +USER nonroot:nonroot + +ENTRYPOINT ["/picture-uploader"] diff --git a/go/Dockerfile.old b/go/Dockerfile.old new file mode 100755 index 0000000..2c572c4 --- /dev/null +++ b/go/Dockerfile.old @@ -0,0 +1,22 @@ +# Use an official Golang runtime as a parent image +FROM golang:1.21.4 + +# Set the working directory in the container +WORKDIR /go/src/app + +# Copy the local package files to the container's workspace +COPY . . + +# Download and install any required third-party dependencies into the container. +#RUN go get -u github.com/gorilla/mux +RUN go get -u github.com/go-sql-driver/mysql +RUN go get -u github.com/sirupsen/logrus + +# Build the Go application +RUN go build -o main . + +# Expose port 8080 to the outside world +EXPOSE 8080 + +# Command to run the application with environment variables +CMD ["./main"] diff --git a/go/go.mod b/go/go.mod new file mode 100644 index 0000000..9c6c86c --- /dev/null +++ b/go/go.mod @@ -0,0 +1,3 @@ +module picture-uploader + +go 1.20 diff --git a/go/main.go b/go/main.go new file mode 100755 index 0000000..c2bc278 --- /dev/null +++ b/go/main.go @@ -0,0 +1,91 @@ +package main + +import ( + "fmt" + _ "html/template" + "io" + "log" + "net/http" + "os" +) + +func main() { + http.HandleFunc("/", homeHandler) + http.HandleFunc("/upload", uploadHandler) + http.HandleFunc("/view/", viewHandler) + + fmt.Println("Server listening on :8080") + http.ListenAndServe(":8080", nil) +} + +func homeHandler(w http.ResponseWriter, r *http.Request) { + // Hier können Sie eine HTML-Templatedatei für die Homepage erstellen + // und sie mit template.Execute laden. + fmt.Fprint(w, "Willkommen! Besuchen Sie /upload, um Bilder hochzuladen.") +} + +func uploadHandler(w http.ResponseWriter, r *http.Request) { + if r.Method == http.MethodPost { + file, handler, err := r.FormFile("image") + if err != nil { + http.Error(w, "Fehler beim Lesen der Datei", http.StatusInternalServerError) + log.Printf("Fehler beim Lesen der Datei: %v", err) + return + } + defer file.Close() + + // Hier können Sie den Dateinamen manipulieren oder einen anderen Speicherort wählen + uploadPath := "./uploads/" + handler.Filename + f, err := os.Create(uploadPath) + if err != nil { + http.Error(w, "Fehler beim Erstellen der Datei", http.StatusInternalServerError) + log.Printf("Fehler beim Erstellen der Datei: %v", err) + return + } + defer f.Close() + + _, copyErr := io.Copy(f, file) + if copyErr != nil { + http.Error(w, "Fehler beim Kopieren der Datei", http.StatusInternalServerError) + log.Printf("Fehler beim Kopieren der Datei: %v", copyErr) + return + } + + // Erfolgsmeldung mit dem Link ausgeben + link := fmt.Sprintf("Bild erfolgreich hochgeladen. Sie können es hier anzeigen: Anzeigen", handler.Filename) + + // Schreiben Sie den Link als HTML in die Antwort + w.Header().Set("Content-Type", "text/html; charset=utf-8") + fmt.Fprint(w, link) + } else { + // HTML-Formular für Bild-Upload hier anzeigen + form := ` +
+ + +
+ ` + fmt.Fprint(w, form) + } +} + +func viewHandler(w http.ResponseWriter, r *http.Request) { + filePath := r.URL.Path[len("/view/"):] + imagePath := "./uploads/" + filePath + + // Öffnen und Lesen der Bilddatei + imageFile, err := os.Open(imagePath) + if err != nil { + http.Error(w, "Bild nicht gefunden", http.StatusNotFound) + log.Printf("Fehler beim Öffnen des Bildes: %v", err) + return + } + defer imageFile.Close() + + // Kopieren des Bildes in die HTTP-Antwort + _, copyErr := io.Copy(w, imageFile) + if copyErr != nil { + log.Printf("Fehler beim Senden des Bildes: %v", copyErr) + return + } +}