├── .devcontainer ├── .dockerignore ├── Dockerfile ├── README.md ├── devcontainer.json └── docker-compose.yml ├── .dockerignore ├── .github ├── CODEOWNERS ├── CONTRIBUTING.md ├── FUNDING.yml ├── labels.yml └── workflows │ ├── build.yml │ ├── buildx-latest.yml │ ├── buildx-release.yml │ ├── dockerhub-description.yml │ └── labels.yml ├── .golangci.yml ├── Dockerfile ├── LICENSE ├── README.md ├── docker-compose.yml ├── go.mod ├── go.sum ├── main.go └── title.png /.devcontainer/.dockerignore: -------------------------------------------------------------------------------- 1 | .dockerignore 2 | devcontainer.json 3 | docker-compose.yml 4 | Dockerfile 5 | README.md 6 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM qmcgaw/godevcontainer 2 | -------------------------------------------------------------------------------- /.devcontainer/README.md: -------------------------------------------------------------------------------- 1 | # Development container 2 | 3 | Development container that can be used with VSCode. 4 | 5 | It works on Linux, Windows and OSX. 6 | 7 | ## Requirements 8 | 9 | - [VS code](https://code.visualstudio.com/download) installed 10 | - [VS code remote containers extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) installed 11 | - [Docker](https://www.docker.com/products/docker-desktop) installed and running 12 | - [Docker Compose](https://docs.docker.com/compose/install/) installed 13 | 14 | ## Setup 15 | 16 | 1. Create the following files on your host if you don't have them: 17 | 18 | ```sh 19 | touch ~/.gitconfig ~/.zsh_history 20 | ``` 21 | 22 | Note that the development container will create the empty directories `~/.docker`, `~/.ssh` and `~/.kube` if you don't have them. 23 | 24 | 1. **For Docker on OSX or Windows without WSL**: ensure your home directory `~` is accessible by Docker. 25 | 1. **For Docker on Windows without WSL:** if you want to use SSH keys, bind mount your host `~/.ssh` to `/tmp/.ssh` instead of `~/.ssh` by changing the `volumes` section in the [docker-compose.yml](docker-compose.yml). 26 | 1. Open the command palette in Visual Studio Code (CTRL+SHIFT+P). 27 | 1. Select `Remote-Containers: Open Folder in Container...` and choose the project directory. 28 | 29 | ## Customization 30 | 31 | ### Customize the image 32 | 33 | You can make changes to the [Dockerfile](Dockerfile) and then rebuild the image. For example, your Dockerfile could be: 34 | 35 | ```Dockerfile 36 | FROM qmcgaw/godevcontainer 37 | RUN apk add curl 38 | ``` 39 | 40 | To rebuild the image, either: 41 | 42 | - With VSCode through the command palette, select `Remote-Containers: Rebuild and reopen in container` 43 | - With a terminal, go to this directory and `docker-compose build` 44 | 45 | ### Customize VS code settings 46 | 47 | You can customize **settings** and **extensions** in the [devcontainer.json](devcontainer.json) definition file. 48 | 49 | ### Entrypoint script 50 | 51 | You can bind mount a shell script to `/home/vscode/.welcome.sh` to replace the [current welcome script](shell/.welcome.sh). 52 | 53 | ### Publish a port 54 | 55 | To access a port from your host to your development container, publish a port in [docker-compose.yml](docker-compose.yml). You can also now do it directly with VSCode without restarting the container. 56 | 57 | ### Run other services 58 | 59 | 1. Modify [docker-compose.yml](docker-compose.yml) to launch other services at the same time as this development container, such as a test database: 60 | 61 | ```yml 62 | database: 63 | image: postgres 64 | restart: always 65 | environment: 66 | POSTGRES_PASSWORD: password 67 | ``` 68 | 69 | 1. In [devcontainer.json](devcontainer.json), change the line `"runServices": ["vscode"],` to `"runServices": ["vscode", "database"],`. 70 | 1. In the VS code command palette, rebuild the container. 71 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "stackedit-dev", 3 | "dockerComposeFile": [ 4 | "docker-compose.yml" 5 | ], 6 | "service": "vscode", 7 | "runServices": [ 8 | "vscode" 9 | ], 10 | "shutdownAction": "stopCompose", 11 | "postCreateCommand": "source ~/.windows.sh && go mod download && go mod tidy", 12 | "workspaceFolder": "/workspace", 13 | // "overrideCommand": "", 14 | "extensions": [ 15 | "golang.go", 16 | "eamodio.gitlens", // IDE Git information 17 | "davidanson.vscode-markdownlint", 18 | "ms-azuretools.vscode-docker", // Docker integration and linting 19 | "shardulm94.trailing-spaces", // Show trailing spaces 20 | "Gruntfuggly.todo-tree", // Highlights TODO comments 21 | "bierner.emojisense", // Emoji sense for markdown 22 | "stkb.rewrap", // rewrap comments after n characters on one line 23 | "vscode-icons-team.vscode-icons", // Better file extension icons 24 | "github.vscode-pull-request-github", // Github interaction 25 | "redhat.vscode-yaml", // Kubernetes, Drone syntax highlighting 26 | "bajdzis.vscode-database", // Supports connections to mysql or postgres, over SSL, socked 27 | "IBM.output-colorizer", // Colorize your output/test logs 28 | // "mohsen1.prettify-json", // Prettify JSON data 29 | // "zxh404.vscode-proto3", // Supports Proto syntax 30 | // "jrebocho.vscode-random", // Generates random values 31 | // "alefragnani.Bookmarks", // Manage bookmarks 32 | // "quicktype.quicktype", // Paste JSON as code 33 | // "spikespaz.vscode-smoothtype", // smooth cursor animation 34 | ], 35 | "settings": { 36 | "files.eol": "\n", 37 | "remote.extensionKind": { 38 | "ms-azuretools.vscode-docker": "workspace" 39 | }, 40 | "editor.codeActionsOnSaveTimeout": 3000, 41 | "go.useLanguageServer": true, 42 | "[go]": { 43 | "editor.formatOnSave": true, 44 | "editor.codeActionsOnSave": { 45 | "source.organizeImports": true, 46 | }, 47 | // Optional: Disable snippets, as they conflict with completion ranking. 48 | "editor.snippetSuggestions": "none" 49 | }, 50 | "[go.mod]": { 51 | "editor.formatOnSave": true, 52 | "editor.codeActionsOnSave": { 53 | "source.organizeImports": true, 54 | }, 55 | }, 56 | "gopls": { 57 | "usePlaceholders": false, 58 | "staticcheck": true 59 | }, 60 | "go.autocompleteUnimportedPackages": true, 61 | "go.gotoSymbol.includeImports": true, 62 | "go.gotoSymbol.includeGoroot": true, 63 | "go.lintTool": "golangci-lint", 64 | "go.buildOnSave": "workspace", 65 | "go.lintOnSave": "workspace", 66 | "go.vetOnSave": "workspace", 67 | "editor.formatOnSave": true, 68 | "go.toolsEnvVars": { 69 | "GOFLAGS": "-tags=", 70 | "CGO_ENABLED": 1 // for the race detector 71 | }, 72 | "gopls.env": { 73 | "GOFLAGS": "-tags=" 74 | }, 75 | "go.testEnvVars": { 76 | "": "", 77 | }, 78 | "go.testFlags": [ 79 | "-v", 80 | "-race" 81 | ], 82 | "go.testTimeout": "10s", 83 | "go.coverOnSingleTest": true, 84 | "go.coverOnSingleTestFile": true, 85 | "go.coverOnTestPackage": true 86 | } 87 | } -------------------------------------------------------------------------------- /.devcontainer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | 3 | services: 4 | vscode: 5 | build: . 6 | image: godevcontainer 7 | volumes: 8 | - ../:/workspace 9 | # Docker 10 | - ~/.docker:/root/.docker:z 11 | # Docker socket to access Docker server 12 | - /var/run/docker.sock:/var/run/docker.sock 13 | # SSH directory for Linux, OSX and WSL 14 | - ~/.ssh:/root/.ssh:z 15 | # For Windows without WSL, a copy will be made 16 | # from /tmp/.ssh to ~/.ssh to fix permissions 17 | # - ~/.ssh:/tmp/.ssh:ro 18 | # Shell history persistence 19 | - ~/.zsh_history:/root/.zsh_history:z 20 | # Git config 21 | - ~/.gitconfig:/root/.gitconfig:z 22 | # Kubernetes 23 | - ~/.kube:/root/.kube:z 24 | environment: 25 | - TZ= 26 | cap_add: 27 | # For debugging with dlv 28 | - SYS_PTRACE 29 | security_opt: 30 | # For debugging with dlv 31 | - seccomp:unconfined 32 | entrypoint: zsh -c "while sleep 1000; do :; done" 33 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | readme/ 3 | docker-compose.yml 4 | README.md -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | @qdm12 -------------------------------------------------------------------------------- /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing 2 | 3 | Contributions are [released](https://help.github.com/articles/github-terms-of-service/#6-contributions-under-repository-license) to the public under the [open source license of this project](../LICENSE). 4 | 5 | ## Submitting a pull request 6 | 7 | 1. [Fork](https://github.com/qdm12/stackedit-docker/fork) and clone the repository 8 | 1. Create a new branch `git checkout -b my-branch-name` 9 | 1. Modify the code 10 | 1. Ensure the docker build succeeds `docker build .` 11 | 1. Commit your modifications 12 | 1. Push to your fork and [submit a pull request](https://github.com/qdm12/stackedit-docker/compare) 13 | 14 | ## Resources 15 | 16 | - [Using Pull Requests](https://help.github.com/articles/about-pull-requests/) 17 | - [How to Contribute to Open Source](https://opensource.guide/how-to-contribute/) 18 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [qdm12] 2 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | - name: ":robot: bot" 2 | color: "69cde9" 3 | description: "" 4 | - name: ":bug: bug" 5 | color: "b60205" 6 | description: "" 7 | - name: ":game_die: dependencies" 8 | color: "0366d6" 9 | description: "" 10 | - name: ":memo: documentation" 11 | color: "c5def5" 12 | description: "" 13 | - name: ":busts_in_silhouette: duplicate" 14 | color: "cccccc" 15 | description: "" 16 | - name: ":sparkles: enhancement" 17 | color: "0054ca" 18 | description: "" 19 | - name: ":bulb: feature request" 20 | color: "0e8a16" 21 | description: "" 22 | - name: ":mega: feedback" 23 | color: "03a9f4" 24 | description: "" 25 | - name: ":rocket: future maybe" 26 | color: "fef2c0" 27 | description: "" 28 | - name: ":hatching_chick: good first issue" 29 | color: "7057ff" 30 | description: "" 31 | - name: ":pray: help wanted" 32 | color: "4caf50" 33 | description: "" 34 | - name: ":hand: hold" 35 | color: "24292f" 36 | description: "" 37 | - name: ":no_entry_sign: invalid" 38 | color: "e6e6e6" 39 | description: "" 40 | - name: ":interrobang: maybe bug" 41 | color: "ff5722" 42 | description: "" 43 | - name: ":thinking: needs more info" 44 | color: "795548" 45 | description: "" 46 | - name: ":question: question" 47 | color: "3f51b5" 48 | description: "" 49 | - name: ":coffin: wontfix" 50 | color: "ffffff" 51 | description: "" 52 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: Docker build 2 | on: 3 | pull_request: 4 | branches: [master] 5 | paths-ignore: 6 | - .github/workflows/buildx-latest.yml 7 | - .github/workflows/buildx-release.yml 8 | - .github/workflows/dockerhub-description.yml 9 | - .dockerignore 10 | - .gitignore 11 | - docker-compose.yml 12 | - LICENSE 13 | - readme.md 14 | - title.png 15 | jobs: 16 | build: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout 20 | uses: actions/checkout@v2 21 | - name: Build image 22 | run: docker build . 23 | -------------------------------------------------------------------------------- /.github/workflows/buildx-latest.yml: -------------------------------------------------------------------------------- 1 | name: Buildx latest 2 | on: 3 | push: 4 | branches: [master] 5 | paths-ignore: 6 | - .github/workflows/build.yml 7 | - .github/workflows/buildx-release.yml 8 | - .github/workflows/dockerhub-description.yml 9 | - .dockerignore 10 | - .gitignore 11 | - docker-compose.yml 12 | - LICENSE 13 | - readme.md 14 | - title.png 15 | jobs: 16 | buildx: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Buildx setup 21 | uses: crazy-max/ghaction-docker-buildx@v1 22 | - name: Dockerhub login 23 | run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u qmcgaw --password-stdin 2>&1 24 | - name: Run Buildx 25 | run: | 26 | docker buildx build \ 27 | --progress plain \ 28 | --platform=linux/amd64,linux/386,linux/arm64,linux/arm/v7,linux/arm/v6 \ 29 | --build-arg CREATED=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ 30 | --build-arg COMMIT=`git rev-parse --short HEAD` \ 31 | --build-arg VERSION=latest \ 32 | -t qmcgaw/stackedit:latest \ 33 | --push \ 34 | . 35 | -------------------------------------------------------------------------------- /.github/workflows/buildx-release.yml: -------------------------------------------------------------------------------- 1 | name: Buildx release 2 | on: 3 | release: 4 | types: [published] 5 | paths-ignore: 6 | - .github/workflows/build.yml 7 | - .github/workflows/buildx-latest.yml 8 | - .github/workflows/dockerhub-description.yml 9 | - .dockerignore 10 | - .gitignore 11 | - docker-compose.yml 12 | - LICENSE 13 | - readme.md 14 | - title.png 15 | jobs: 16 | buildx: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - uses: actions/checkout@v2 20 | - name: Buildx setup 21 | uses: crazy-max/ghaction-docker-buildx@v1 22 | - name: Dockerhub login 23 | run: echo ${{ secrets.DOCKERHUB_PASSWORD }} | docker login -u qmcgaw --password-stdin 2>&1 24 | - name: Run Buildx 25 | run: | 26 | docker buildx build \ 27 | --progress plain \ 28 | --platform=linux/amd64,linux/386,linux/arm64,linux/arm/v7,linux/arm/v6 \ 29 | --build-arg CREATED=`date -u +"%Y-%m-%dT%H:%M:%SZ"` \ 30 | --build-arg COMMIT=`git rev-parse --short HEAD` \ 31 | --build-arg VERSION=${GITHUB_REF##*/} \ 32 | -t qmcgaw/stackedit:${GITHUB_REF##*/} \ 33 | --push \ 34 | . 35 | -------------------------------------------------------------------------------- /.github/workflows/dockerhub-description.yml: -------------------------------------------------------------------------------- 1 | name: Docker Hub description 2 | on: 3 | push: 4 | branches: [master] 5 | paths: 6 | - README.md 7 | - .github/workflows/dockerhub-description.yml 8 | jobs: 9 | dockerHubDescription: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v2 14 | - name: Docker Hub Description 15 | uses: peter-evans/dockerhub-description@v2.1.0 16 | env: 17 | DOCKERHUB_USERNAME: qmcgaw 18 | DOCKERHUB_PASSWORD: ${{ secrets.DOCKERHUB_PASSWORD }} 19 | DOCKERHUB_REPOSITORY: qmcgaw/stackedit 20 | -------------------------------------------------------------------------------- /.github/workflows/labels.yml: -------------------------------------------------------------------------------- 1 | name: labels 2 | on: 3 | push: 4 | branches: ["master"] 5 | paths: 6 | - '.github/labels.yml' 7 | - '.github/workflows/labels.yml' 8 | jobs: 9 | labeler: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v2 14 | - name: Labeler 15 | if: success() 16 | uses: crazy-max/ghaction-github-labeler@v1 17 | env: 18 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 19 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | linters-settings: 2 | maligned: 3 | suggest-new: true 4 | misspell: 5 | locale: US 6 | 7 | linters: 8 | disable-all: true 9 | enable: 10 | - bodyclose 11 | - deadcode 12 | - dogsled 13 | - dupl 14 | - errcheck 15 | - gochecknoglobals 16 | - gochecknoinits 17 | - gocognit 18 | - goconst 19 | - gocritic 20 | - gocyclo 21 | - goimports 22 | - golint 23 | - gosec 24 | - gosimple 25 | - govet 26 | - ineffassign 27 | - interfacer 28 | - maligned 29 | - misspell 30 | - nakedret 31 | - prealloc 32 | - rowserrcheck 33 | - scopelint 34 | - staticcheck 35 | - structcheck 36 | - typecheck 37 | - unconvert 38 | - unparam 39 | - unused 40 | - varcheck 41 | - whitespace 42 | 43 | run: 44 | skip-dirs: 45 | - .devcontainer 46 | - .github 47 | - postgres 48 | 49 | service: 50 | golangci-lint-version: 1.27.x # use the fixed version to not introduce new linters unexpectedly -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # Sets linux/amd64 in case it's not injected by older Docker versions 2 | ARG BUILDPLATFORM=linux/amd64 3 | 4 | ARG ALPINE_VERSION=3.14 5 | ARG STACKEDIT_VERSION=v5.14.10 6 | ARG GO_VERSION=1.17 7 | ARG XCPUTRANSLATE_VERSION=v0.6.0 8 | ARG GOLANGCI_LINT_VERSION=v1.42.1 9 | 10 | FROM --platform=${BUILDPLATFORM} qmcgaw/xcputranslate:${XCPUTRANSLATE_VERSION} AS xcputranslate 11 | FROM --platform=${BUILDPLATFORM} qmcgaw/binpot:golangci-lint-${GOLANGCI_LINT_VERSION} AS golangci-lint 12 | 13 | FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION}-alpine${ALPINE_VERSION} AS base 14 | ENV CGO_ENABLED=0 15 | WORKDIR /tmp/gobuild 16 | RUN apk --update add git g++ 17 | COPY --from=xcputranslate /xcputranslate /usr/local/bin/xcputranslate 18 | COPY --from=golangci-lint /bin /go/bin/golangci-lint 19 | COPY go.mod go.sum ./ 20 | RUN go mod download 21 | COPY main.go . 22 | 23 | FROM base AS lint 24 | COPY .golangci.yml ./ 25 | RUN golangci-lint run --timeout=10m 26 | 27 | FROM base AS server 28 | ARG TARGETPLATFORM 29 | ARG VERSION=unknown 30 | ARG CREATED="an unknown date" 31 | ARG COMMIT=unknown 32 | RUN GOARCH="$(xcputranslate translate -targetplatform=${TARGETPLATFORM} -field arch)" \ 33 | GOARM="$(xcputranslate translate -targetplatform=${TARGETPLATFORM} -field arm)" \ 34 | go build -trimpath -ldflags="-s -w \ 35 | -X 'main.version=$VERSION' \ 36 | -X 'main.buildDate=$CREATED' \ 37 | -X 'main.commit=$COMMIT' \ 38 | " -o app main.go 39 | 40 | FROM --platform=amd64 alpine:${ALPINE_VERSION} AS stackedit 41 | ARG STACKEDIT_VERSION 42 | WORKDIR /stackedit 43 | RUN apk add -q --progress --update --no-cache git npm python3 make g++ 44 | RUN git clone --branch ${STACKEDIT_VERSION} --single-branch --depth 1 https://github.com/benweet/stackedit.git . &> /dev/null 45 | RUN npm install 46 | ENV NODE_ENV=production 47 | RUN sed -i "s/assetsPublicPath: '\/',/assetsPublicPath: '.\/',/g" config/index.js 48 | RUN npm run build 49 | 50 | FROM scratch AS final 51 | ARG CREATED 52 | ARG COMMIT 53 | ARG STACKEDIT_VERSION 54 | LABEL \ 55 | org.opencontainers.image.authors="quentin.mcgaw@gmail.com" \ 56 | org.opencontainers.image.created=$CREATED \ 57 | org.opencontainers.image.version=$STACKEDIT_VERSION \ 58 | org.opencontainers.image.revision=$COMMIT \ 59 | org.opencontainers.image.url="https://github.com/qdm12/stackedit-docker" \ 60 | org.opencontainers.image.documentation="https://github.com/qdm12/stackedit-docker/blob/master/README.md" \ 61 | org.opencontainers.image.source="https://github.com/qdm12/stackedit-docker" \ 62 | org.opencontainers.image.title="stackedit-docker" \ 63 | org.opencontainers.image.description="StackEdit server in a lightweight Docker container" 64 | EXPOSE 8000 65 | HEALTHCHECK --start-period=1s --interval=100s --timeout=2s --retries=1 CMD ["/server","healthcheck"] 66 | USER 1000 67 | ENTRYPOINT ["/server"] 68 | ENV \ 69 | LISTENING_PORT=8000 \ 70 | ROOT_URL=/ \ 71 | NODE_ENV=production \ 72 | PANDOC_PATH=pandoc \ 73 | WKHTMLTOPDF_PATH=wkhtmltopdf \ 74 | USER_BUCKET_NAME=stackedit-users \ 75 | PAYPAL_RECEIVER_EMAIL= \ 76 | DROPBOX_APP_KEY= \ 77 | DROPBOX_APP_KEY_FULL= \ 78 | GITHUB_CLIENT_ID= \ 79 | GITHUB_CLIENT_SECRET= \ 80 | GOOGLE_CLIENT_ID= \ 81 | GOOGLE_API_KEY= \ 82 | WORDPRESS_CLIENT_ID= 83 | COPY --from=stackedit --chown=1000 /stackedit/dist /html/dist 84 | COPY --from=stackedit --chown=1000 /stackedit/static /html/static 85 | COPY --from=server --chown=1000 /tmp/gobuild/app /server 86 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Quentin McGaw 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # StackEdit Docker server 2 | 3 | *StackEdit v5.14.5 (January 2020) with a Golang HTTP server on Scratch* 4 | 5 | [![Docker StackEdit](https://github.com/qdm12/stackedit-docker/raw/master/title.png)](https://hub.docker.com/r/qmcgaw/stackedit/) 6 | 7 | [![Build status](https://github.com/qdm12/stackedit-docker/workflows/Buildx%20latest/badge.svg)](https://github.com/qdm12/stackedit-docker/actions?query=workflow%3A%22Buildx+latest%22) 8 | [![Docker Pulls](https://img.shields.io/docker/pulls/qmcgaw/stackedit.svg)](https://hub.docker.com/r/qmcgaw/stackedit) 9 | [![Docker Stars](https://img.shields.io/docker/stars/qmcgaw/stackedit.svg)](https://hub.docker.com/r/qmcgaw/stackedit) 10 | 11 | [![GitHub last commit](https://img.shields.io/github/last-commit/qdm12/stackedit-docker.svg)](https://github.com/qdm12/stackedit-docker/commits) 12 | [![GitHub commit activity](https://img.shields.io/github/commit-activity/y/qdm12/stackedit-docker.svg)](https://github.com/qdm12/stackedit-docker/commits) 13 | [![GitHub issues](https://img.shields.io/github/issues/qdm12/stackedit-docker.svg)](https://github.com/qdm12/stackedit-docker/issues) 14 | [![Donate PayPal](https://img.shields.io/badge/Donate-PayPal-green.svg)](https://paypal.me/qmcgaw) 15 | 16 | ## Features 17 | 18 | - [Stackedit features](https://github.com/benweet/stackedit/blob/master/README.md#stackedit-can) 19 | - Lightweight image based on: 20 | - [Stackedit 5.14.5](https://github.com/benweet/stackedit) 21 | - [Scratch](https://hub.docker.com/_/scratch) 22 | - Golang simple HTTP static server 23 | - Running without root 24 | - Cross cpu architecture compatible: amd64, 386, arm64v8, arm32v7 and arm32v6 (ask for more) 25 | - Small 36.8MB image size (amd64, uncompressed) 26 | - Built-in Docker healthcheck 27 | - Nice emojis in the logs... 28 | 29 | ## Setup 30 | 31 | 1. Use the following command: 32 | 33 | ```sh 34 | docker run -d -p 8000:8000/tcp qmcgaw/stackedit 35 | ``` 36 | 37 | You can also use [docker-compose.yml](https://github.com/qdm12/stackedit-docker/blob/master/docker-compose.yml) with: 38 | 39 | ```sh 40 | docker-compose up -d 41 | ``` 42 | 43 | 1. Access at [http://localhost:8000](http://localhost:8000) 44 | 45 | ## Environment variables 46 | 47 | | Environment variable | Default | Description | 48 | | --- | --- | --- | 49 | | `LISTENING_PORT` | `8000` | Internal server listening port | 50 | | `ROOT_URL` | `/` | Root URL to use, useful when used with a reverse proxy | 51 | | `NODE_ENV` | `production` | Sets production behavior for stackedit | 52 | | `PANDOC_PATH` | `pandoc` | *Non functional yet* | 53 | | `WKHTMLTOPDF_PATH` | `wkhtmltopdf` | *Non functional yet* | 54 | | `USER_BUCKET_NAME` | `stackedit-users` | ? | 55 | | `PAYPAL_RECEIVER_EMAIL` | | Receive Paypal donation email address | 56 | | `DROPBOX_APP_KEY` | | | 57 | | `DROPBOX_APP_KEY_FULL` | | | 58 | | `GITHUB_CLIENT_ID` | | | 59 | | `GITHUB_CLIENT_SECRET` | | | 60 | | `GOOGLE_CLIENT_ID` | | | 61 | | `GOOGLE_API_KEY` | | | 62 | | `WORDPRESS_CLIENT_ID` | | | 63 | 64 | ## Acknowledgements 65 | 66 | Credits to the [developers](https://github.com/benweet/stackedit/graphs/contributors) of [StackEdit](https://stackedit.io/) 67 | 68 | ## TODOs 69 | 70 | - [ ] Add static binary programs 71 | - [ ] pandoc 72 | - [ ] wkhtmltopdf 73 | - [ ] Travis CI build cross CPU arch 74 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3.7" 2 | services: 3 | stackedit: 4 | image: qmcgaw/stackedit 5 | container_name: stackedit 6 | environment: 7 | - LISTENING_PORT=8000 8 | - ROOT_URL=/ 9 | - USER_BUCKET_NAME=stackedit-users 10 | - PAYPAL_RECEIVER_EMAIL= 11 | - DROPBOX_APP_KEY= 12 | - DROPBOX_APP_KEY_FULL= 13 | - GITHUB_CLIENT_ID= 14 | - GITHUB_CLIENT_SECRET= 15 | - GOOGLE_CLIENT_ID= 16 | - GOOGLE_API_KEY= 17 | - WORDPRESS_CLIENT_ID= 18 | ports: 19 | - 8000:8000/tcp 20 | network_mode: bridge 21 | restart: always 22 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/qdm12/stackedit-docker 2 | 3 | require ( 4 | github.com/kyokomi/emoji v2.2.4+incompatible 5 | github.com/qdm12/golibs v0.0.0-20200528010515-765b7cd4f0db 6 | ) 7 | 8 | go 1.14 9 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= 2 | github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= 3 | github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= 4 | github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= 5 | github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= 6 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 7 | github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= 8 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 9 | github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= 10 | github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s= 11 | github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= 12 | github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= 13 | github.com/go-openapi/analysis v0.0.0-20180825180245-b006789cd277/go.mod h1:k70tL6pCuVxPJOHXQ+wIac1FUrvNkHolPie/cLEU6hI= 14 | github.com/go-openapi/analysis v0.17.0/go.mod h1:IowGgpVeD0vNm45So8nr+IcQ3pxVtpRoBWb8PVZO0ik= 15 | github.com/go-openapi/errors v0.17.0/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= 16 | github.com/go-openapi/errors v0.17.2/go.mod h1:LcZQpmvG4wyF5j4IhA73wkLFQg+QJXOQHVjmcZxhka0= 17 | github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= 18 | github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I= 19 | github.com/go-openapi/loads v0.17.0/go.mod h1:72tmFy5wsWx89uEVddd0RjRWPZm92WRLhf7AC+0+OOU= 20 | github.com/go-openapi/runtime v0.0.0-20180920151709-4f900dc2ade9/go.mod h1:6v9a6LTXWQCdL8k1AO3cvqx5OtZY/Y9wKTgaoP6YRfA= 21 | github.com/go-openapi/runtime v0.17.2/go.mod h1:QO936ZXeisByFmZEO1IS1Dqhtf4QV1sYYFtIq6Ld86Q= 22 | github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= 23 | github.com/go-openapi/strfmt v0.17.0/go.mod h1:P82hnJI0CXkErkXi8IKjPbNBM6lV6+5pLP5l494TcyU= 24 | github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg= 25 | github.com/go-openapi/validate v0.17.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+MYsct2VUrAJ4= 26 | github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= 27 | github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= 28 | github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= 29 | github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= 30 | github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 31 | github.com/gotify/go-api-client/v2 v2.0.4/go.mod h1:VKiah/UK20bXsr0JObE1eBVLW44zbBouzjuri9iwjFU= 32 | github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= 33 | github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= 34 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 35 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 36 | github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= 37 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 38 | github.com/kyokomi/emoji v2.2.4+incompatible h1:np0woGKwx9LiHAQmwZx79Oc0rHpNw3o+3evou4BEPv4= 39 | github.com/kyokomi/emoji v2.2.4+incompatible/go.mod h1:mZ6aGCD7yk8j6QY6KICwnZ2pxoszVseX1DNoGtU2tBA= 40 | github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= 41 | github.com/mattn/go-colorable v0.1.4 h1:snbPLB8fVfU9iwbbo30TPtbLRzwWu6aJS6Xh4eaaviA= 42 | github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= 43 | github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= 44 | github.com/mattn/go-isatty v0.0.11 h1:FxPOTFNqGkuDUGi3H/qkUbQO4ZiBa2brKq5r0l8TGeM= 45 | github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= 46 | github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= 47 | github.com/mr-tron/base58 v1.1.3 h1:v+sk57XuaCKGXpWtVBX8YJzO7hMGx4Aajh4TQbdEFdc= 48 | github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= 49 | github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= 50 | github.com/phayes/permbits v0.0.0-20190612203442-39d7c581d2ee/go.mod h1:3uODdxMgOaPYeWU7RzZLxVtJHZ/x1f/iHkBZuKJDzuY= 51 | github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= 52 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 53 | github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= 54 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 55 | github.com/qdm12/golibs v0.0.0-20200528010515-765b7cd4f0db h1:omObof3k8JjHri+K4ZwKvDCPV12pmLsZOQy4EPYnZMQ= 56 | github.com/qdm12/golibs v0.0.0-20200528010515-765b7cd4f0db/go.mod h1:pikkTN7g7zRuuAnERwqW1yAFq6pYmxrxpjiwGvb0Ysc= 57 | github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 58 | github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= 59 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 60 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 61 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 62 | github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= 63 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 64 | go.uber.org/atomic v1.5.0 h1:OI5t8sDa1Or+q8AeE+yKeB/SDYioSHAgcVljj9JIETY= 65 | go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= 66 | go.uber.org/multierr v1.3.0 h1:sFPn2GLc3poCkfrpIXGhBD2X0CMIo4Q/zSULXrj/+uc= 67 | go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= 68 | go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= 69 | go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= 70 | go.uber.org/zap v1.13.0 h1:nR6NoDBgAf67s68NhaXbsojM+2gxp3S1hWkHDl27pVU= 71 | go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= 72 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 73 | golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= 74 | golang.org/x/crypto v0.0.0-20200117160349-530e935923ad/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 75 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs= 76 | golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= 77 | golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= 78 | golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 79 | golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 80 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 81 | golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 82 | golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 83 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 84 | golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 85 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 86 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037 h1:YyJpGZS1sBuBCzLAR1VEpK193GlqGZbnPFnPV/5Rsb4= 87 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 88 | golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 89 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 90 | golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 91 | golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= 92 | golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= 93 | golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 94 | golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs= 95 | golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= 96 | golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 97 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 98 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= 99 | gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 100 | gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= 101 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 102 | gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= 103 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 104 | honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM= 105 | honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= 106 | rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= 107 | rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= 108 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "encoding/json" 6 | "fmt" 7 | "net/http" 8 | "os" 9 | "os/signal" 10 | "strings" 11 | "syscall" 12 | 13 | "github.com/kyokomi/emoji" 14 | "github.com/qdm12/golibs/healthcheck" 15 | "github.com/qdm12/golibs/logging" 16 | "github.com/qdm12/golibs/params" 17 | "github.com/qdm12/golibs/server" 18 | ) 19 | 20 | func main() { 21 | ctx := context.Background() 22 | os.Exit(_main(ctx, os.Args)) 23 | } 24 | 25 | func _main(ctx context.Context, args []string) int { 26 | ctx, cancel := context.WithCancel(ctx) 27 | defer cancel() 28 | 29 | if healthcheck.Mode(args) { 30 | if err := healthcheck.Query(); err != nil { 31 | fmt.Println(err) 32 | return 1 33 | } 34 | return 0 35 | } 36 | 37 | fmt.Println("#####################################") 38 | fmt.Println("########## StackEdit Server #########") 39 | fmt.Println("########## by Quentin McGaw #########") 40 | fmt.Println("########## Give some " + emoji.Sprint(":heart:") + " at ##########") 41 | fmt.Println("# github.com/qdm12/stackedit-docker #") 42 | fmt.Print("#####################################\n\n") 43 | envParams := params.NewEnvParams() 44 | logger, err := logging.NewLogger(logging.ConsoleEncoding, logging.InfoLevel, -1) 45 | if err != nil { 46 | fmt.Println(err) 47 | return 1 48 | } 49 | 50 | listeningPort, warning, err := envParams.GetListeningPort(params.Default("8000")) 51 | if len(warning) > 0 { 52 | logger.Warn(warning) 53 | } 54 | if err != nil { 55 | logger.Error(err) 56 | return 1 57 | } 58 | logger.Info("Using internal listening port %s", listeningPort) 59 | 60 | rootURL, err := envParams.GetRootURL(params.Default("/")) 61 | if err != nil { 62 | logger.Error(err) 63 | return 1 64 | } 65 | logger.Info("Using root URL %q", rootURL) 66 | 67 | productionRouter := http.NewServeMux() 68 | productionRouter.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 69 | urlStackeditPath := strings.TrimPrefix(r.URL.Path, rootURL) 70 | filepath := "/dist/" + urlStackeditPath 71 | switch urlStackeditPath { 72 | case "/conf", "/app/conf": 73 | bytes := getAllStackeditEnv() 74 | if _, err := w.Write(bytes); err != nil { 75 | logger.Error(err) 76 | } 77 | return 78 | case "/": 79 | filepath = "/static/landing/" 80 | case "/sitemap.xml": 81 | filepath = "/static/sitemap.xml" 82 | case "/oauth2/callback": 83 | filepath = "/static/oauth2/callback.html" 84 | case "/app", "/app/": 85 | filepath = "/dist/index.html" 86 | default: 87 | switch { 88 | case strings.HasPrefix(urlStackeditPath, "/static/css/static/fonts/"): 89 | filepath = "/dist/" + strings.TrimPrefix(urlStackeditPath, "/static/css/") 90 | case strings.HasPrefix(urlStackeditPath, "/app/static/css/static/fonts/"): 91 | filepath = "/dist/" + strings.TrimPrefix(urlStackeditPath, "/app/static/css/") 92 | case strings.HasPrefix(urlStackeditPath, "/app/"): 93 | filepath = "/dist/" + strings.TrimPrefix(urlStackeditPath, "/app/") 94 | } 95 | } 96 | http.ServeFile(w, r, "/html"+filepath) 97 | }) 98 | healthcheckHandlerFunc := healthcheck.GetHandler(func() error { return nil }) 99 | serverErrors := make(chan []error) 100 | go func() { 101 | serverErrors <- server.RunServers(ctx, 102 | server.Settings{Name: "production", Addr: "0.0.0.0:" + listeningPort, Handler: productionRouter}, 103 | server.Settings{Name: "healthcheck", Addr: "127.0.0.1:9999", Handler: healthcheckHandlerFunc}, 104 | ) 105 | }() 106 | 107 | osSignals := make(chan os.Signal, 1) 108 | signal.Notify(osSignals, 109 | syscall.SIGINT, 110 | syscall.SIGTERM, 111 | os.Interrupt, 112 | ) 113 | select { 114 | case errors := <-serverErrors: 115 | for _, err := range errors { 116 | logger.Error(err) 117 | } 118 | return 1 119 | case signal := <-osSignals: 120 | message := fmt.Sprintf("Stopping program: caught OS signal %q", signal) 121 | logger.Warn(message) 122 | return 2 123 | case <-ctx.Done(): 124 | message := fmt.Sprintf("Stopping program: %s", ctx.Err()) 125 | logger.Warn(message) 126 | return 1 127 | } 128 | } 129 | 130 | // Returns all stackedit env values as JSON 131 | func getAllStackeditEnv() []byte { 132 | env := struct { 133 | DropboxAppKey string `json:"dropboxAppKey"` 134 | DropboxAppKeyFull string `json:"dropboxAppKeyFull"` 135 | GithubClientID string `json:"githubClientId"` 136 | GithubClientSecret string `json:"githubClientSecret"` 137 | GoogleClientID string `json:"googleClientId"` 138 | GoogleAPIKey string `json:"googleApiKey"` 139 | WordpressClientID string `json:"wordpressClientId"` 140 | PaypalReceiverEmail string `json:"paypalReceiverEmail"` 141 | AllowSponsorship bool `json:"allowSponsorship"` 142 | }{} 143 | envParams := params.NewEnvParams() 144 | env.DropboxAppKey, _ = envParams.GetEnv("DROPBOX_APP_KEY") 145 | env.DropboxAppKeyFull, _ = envParams.GetEnv("DROPBOX_APP_KEY_FULL") 146 | env.GithubClientID, _ = envParams.GetEnv("GITHUB_CLIENT_ID") 147 | env.GithubClientSecret, _ = envParams.GetEnv("GITHUB_CLIENT_SECRET") 148 | env.GoogleClientID, _ = envParams.GetEnv("GOOGLE_CLIENT_ID") 149 | env.GoogleAPIKey, _ = envParams.GetEnv("GOOGLE_API_KEY") 150 | env.WordpressClientID, _ = envParams.GetEnv("WORDPRESS_CLIENT_ID") 151 | env.PaypalReceiverEmail, _ = envParams.GetEnv("PAYPAL_RECEIVER_EMAIL") 152 | if len(env.PaypalReceiverEmail) > 0 { 153 | env.AllowSponsorship = true 154 | } 155 | b, _ := json.Marshal(env) 156 | return b 157 | } 158 | -------------------------------------------------------------------------------- /title.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/qdm12/stackedit-docker/1c88c9cfb57ea69c2f6c57071c37c1ed57d1e71c/title.png --------------------------------------------------------------------------------