├── .editorconfig ├── .github ├── CODEOWNERS ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug.yml │ ├── config.yml │ └── feature.yml ├── SUPPORT.md ├── dependabot.yml ├── labels.yml └── workflows │ ├── build.yml │ ├── labels.yml │ └── test.yml ├── .gitignore ├── CHANGELOG.md ├── Dockerfile ├── LICENSE ├── README.md ├── docker-bake.hcl └── test ├── dist.Dockerfile ├── legacy-pureftpd ├── Dockerfile ├── logcheck.txt ├── patchs │ └── minimal.patch └── rootfs │ └── etc │ ├── cont-init.d │ ├── 01-config.sh │ ├── 02-service.sh │ └── 03-uploadscript.sh │ └── socklog.rules │ └── pure-ftpd └── legacy-rrdtool ├── Dockerfile ├── logcheck.txt └── rootfs └── etc ├── cont-init.d ├── 00-fix-logs.sh ├── 01-fix-uidgid.sh ├── 02-fix-perms.sh └── 04-svc-main.sh └── socklog.rules └── rrdcached /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = false 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false 14 | insert_final_newline = true 15 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @crazy-max 2 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: crazy-max 2 | custom: https://www.paypal.me/crazyws 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema 2 | name: Bug Report 3 | description: Report a bug 4 | labels: 5 | - kind/bug 6 | - status/triage 7 | 8 | body: 9 | - type: checkboxes 10 | attributes: 11 | label: Support guidelines 12 | description: Please read the support guidelines before proceeding. 13 | options: 14 | - label: I've read the [support guidelines](https://github.com/crazy-max/docker-alpine-s6/blob/master/.github/SUPPORT.md) 15 | required: true 16 | 17 | - type: checkboxes 18 | attributes: 19 | label: I've found a bug and checked that ... 20 | description: | 21 | Make sure that your request fulfills all of the following requirements. If one requirement cannot be satisfied, explain in detail why. 22 | options: 23 | - label: ... the documentation does not mention anything about my problem 24 | - label: ... there are no open or closed issues that are related to my problem 25 | 26 | - type: textarea 27 | attributes: 28 | label: Description 29 | description: | 30 | Please provide a brief description of the bug in 1-2 sentences. 31 | validations: 32 | required: true 33 | 34 | - type: textarea 35 | attributes: 36 | label: Expected behaviour 37 | description: | 38 | Please describe precisely what you'd expect to happen. 39 | validations: 40 | required: true 41 | 42 | - type: textarea 43 | attributes: 44 | label: Actual behaviour 45 | description: | 46 | Please describe precisely what is actually happening. 47 | validations: 48 | required: true 49 | 50 | - type: textarea 51 | attributes: 52 | label: Steps to reproduce 53 | description: | 54 | Please describe the steps to reproduce the bug. 55 | placeholder: | 56 | 1. ... 57 | 2. ... 58 | 3. ... 59 | validations: 60 | required: true 61 | 62 | - type: textarea 63 | attributes: 64 | label: Docker info 65 | description: | 66 | Output of `docker info` command. 67 | render: text 68 | validations: 69 | required: true 70 | 71 | - type: textarea 72 | attributes: 73 | label: Docker Compose config 74 | description: | 75 | Output of `docker compose config` command. 76 | render: yaml 77 | 78 | - type: textarea 79 | attributes: 80 | label: Logs 81 | description: | 82 | Please provide the container logs (set `LOG_LEVEL=debug` if applicable). 83 | render: text 84 | validations: 85 | required: true 86 | 87 | - type: textarea 88 | attributes: 89 | label: Additional info 90 | description: | 91 | Please provide any additional information that seem useful. 92 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/configuring-issue-templates-for-your-repository#configuring-the-template-chooser 2 | blank_issues_enabled: true 3 | contact_links: 4 | - name: Questions and Discussions 5 | url: https://github.com/crazy-max/docker-alpine-s6/discussions/new 6 | about: Use Github Discussions to ask questions and/or open discussion topics. 7 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature.yml: -------------------------------------------------------------------------------- 1 | # https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/syntax-for-githubs-form-schema 2 | name: Feature request 3 | description: Missing functionality? Come tell us about it! 4 | labels: 5 | - kind/enhancement 6 | - status/triage 7 | 8 | body: 9 | - type: textarea 10 | id: description 11 | attributes: 12 | label: Description 13 | description: What is the feature you want to see? 14 | validations: 15 | required: true 16 | -------------------------------------------------------------------------------- /.github/SUPPORT.md: -------------------------------------------------------------------------------- 1 | # Support [![](https://isitmaintained.com/badge/resolution/crazy-max/docker-alpine-s6.svg)](https://isitmaintained.com/project/crazy-max/docker-alpine-s6) 2 | 3 | ## Reporting an issue 4 | 5 | Please do a search in [open issues](https://github.com/crazy-max/docker-alpine-s6/issues?utf8=%E2%9C%93&q=) to see if the issue or feature request has already been filed. 6 | 7 | If you find your issue already exists, make relevant comments and add your [reaction](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments). Use a reaction in place of a "+1" comment. 8 | 9 | :+1: - upvote 10 | 11 | :-1: - downvote 12 | 13 | If you cannot find an existing issue that describes your bug or feature, submit an issue using the guidelines below. 14 | 15 | ## Writing good bug reports and feature requests 16 | 17 | File a single issue per problem and feature request. 18 | 19 | * Do not enumerate multiple bugs or feature requests in the same issue. 20 | * Do not add your issue as a comment to an existing issue unless it's for the identical input. Many issues look similar, but have different causes. 21 | 22 | The more information you can provide, the more likely someone will be successful reproducing the issue and finding a fix. 23 | 24 | You are now ready to [create a new issue](https://github.com/crazy-max/docker-alpine-s6/issues/new/choose)! 25 | 26 | ## Closure policy 27 | 28 | * Issues that don't have the information requested above (when applicable) will be closed immediately and the poster directed to the support guidelines. 29 | * Issues that go a week without a response from original poster are subject to closure at my discretion. 30 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" 7 | time: "08:00" 8 | timezone: "Europe/Paris" 9 | labels: 10 | - "kind/dependencies" 11 | - "bot" 12 | -------------------------------------------------------------------------------- /.github/labels.yml: -------------------------------------------------------------------------------- 1 | ## more info https://github.com/crazy-max/ghaction-github-labeler 2 | - 3 | name: "bot" 4 | color: "69cde9" 5 | description: "" 6 | - 7 | name: "good first issue" 8 | color: "7057ff" 9 | description: "" 10 | - 11 | name: "help wanted" 12 | color: "4caf50" 13 | description: "" 14 | - 15 | name: "area/ci" 16 | color: "ed9ca9" 17 | description: "" 18 | - 19 | name: "area/dockerfile" 20 | color: "03a9f4" 21 | description: "" 22 | - 23 | name: "kind/bug" 24 | color: "b60205" 25 | description: "" 26 | - 27 | name: "kind/dependencies" 28 | color: "0366d6" 29 | description: "" 30 | - 31 | name: "kind/docs" 32 | color: "c5def5" 33 | description: "" 34 | - 35 | name: "kind/duplicate" 36 | color: "cccccc" 37 | description: "" 38 | - 39 | name: "kind/enhancement" 40 | color: "0054ca" 41 | description: "" 42 | - 43 | name: "kind/invalid" 44 | color: "e6e6e6" 45 | description: "" 46 | - 47 | name: "kind/upstream" 48 | color: "fbca04" 49 | description: "" 50 | - 51 | name: "kind/wontfix" 52 | color: "ffffff" 53 | description: "" 54 | - 55 | name: "status/automerge" 56 | color: "8f4fbc" 57 | description: "" 58 | - 59 | name: "status/needs-investigation" 60 | color: "e6625b" 61 | description: "" 62 | - 63 | name: "status/needs-more-info" 64 | color: "795548" 65 | description: "" 66 | - 67 | name: "status/stale" 68 | color: "237da0" 69 | description: "" 70 | - 71 | name: "status/triage" 72 | color: "dde4b7" 73 | description: "" 74 | -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions 8 | permissions: 9 | contents: read 10 | 11 | on: 12 | push: 13 | branches: 14 | - 'master' 15 | - 'releases/*' 16 | tags: 17 | - '*' 18 | paths-ignore: 19 | - '**.md' 20 | pull_request: 21 | branches: 22 | - 'master' 23 | - 'releases/*' 24 | paths-ignore: 25 | - '**.md' 26 | 27 | env: 28 | DOCKERHUB_SLUG: crazymax/alpine-s6 29 | GHCR_SLUG: ghcr.io/crazy-max/alpine-s6 30 | DOCKERHUB_DIST_SLUG: crazymax/alpine-s6-dist 31 | GHCR_DIST_SLUG: ghcr.io/crazy-max/alpine-s6-dist 32 | ALPINE_LATEST: '3.21' 33 | 34 | jobs: 35 | build: 36 | runs-on: ubuntu-22.04 37 | permissions: 38 | # required to create GitHub release 39 | contents: write 40 | # required to push to GHCR 41 | packages: write 42 | strategy: 43 | fail-fast: false 44 | matrix: 45 | alpine_version: 46 | - '3.16' 47 | - '3.17' 48 | - '3.18' 49 | - '3.19' 50 | - '3.20' 51 | - '3.21' 52 | - 'edge' 53 | steps: 54 | - 55 | name: Prepare 56 | run: | 57 | NL=$'\n' 58 | ALPINE_VERSION=${{ matrix.alpine_version }} 59 | VERSION=edge 60 | if [[ $GITHUB_REF == refs/tags/* ]]; then 61 | TAG=${GITHUB_REF#refs/tags/} 62 | VERSION=${TAG%-r*} 63 | fi 64 | IMAGE_TAGS="" 65 | if [[ $ALPINE_VERSION =~ ^[0-9]{1,3}\.[0-9]{1,3} ]]; then 66 | IMAGE_TAGS="${IMAGE_TAGS}${ALPINE_VERSION}-${VERSION}${NL}" 67 | if [ "$ALPINE_VERSION" = "${{ env.ALPINE_LATEST }}" ]; then 68 | IMAGE_TAGS="${IMAGE_TAGS}latest-${VERSION}${NL}" 69 | fi 70 | else 71 | if [[ $VERSION =~ ^[0-9]{1,3}\.[0-9]{1,3} ]]; then 72 | IMAGE_TAGS="${IMAGE_TAGS}${ALPINE_VERSION}-${VERSION}${NL}" 73 | else 74 | IMAGE_TAGS="${IMAGE_TAGS}${VERSION}${NL}" 75 | fi 76 | fi 77 | if [ "$VERSION" != "edge" ]; then 78 | IMAGE_TAGS="${IMAGE_TAGS}${ALPINE_VERSION}${NL}" 79 | if [ "$ALPINE_VERSION" = "${{ env.ALPINE_LATEST }}" ]; then 80 | IMAGE_TAGS="${IMAGE_TAGS}latest${NL}" 81 | fi 82 | fi 83 | echo "IMAGE_TAGS<> $GITHUB_ENV 84 | echo -e "$IMAGE_TAGS" >> $GITHUB_ENV 85 | echo "EOF" >> $GITHUB_ENV 86 | - 87 | name: Docker meta 88 | id: meta 89 | uses: docker/metadata-action@v5 90 | with: 91 | images: | 92 | ${{ env.DOCKERHUB_SLUG }} 93 | ${{ env.GHCR_SLUG }} 94 | tags: ${{ env.IMAGE_TAGS }} 95 | labels: | 96 | org.opencontainers.image.title=alpine-s6 97 | org.opencontainers.image.description=Alpine Linux with s6 overlay 98 | org.opencontainers.image.vendor=CrazyMax 99 | - 100 | name: Docker meta dist 101 | id: meta_dist 102 | uses: docker/metadata-action@v5 103 | with: 104 | images: | 105 | ${{ env.DOCKERHUB_DIST_SLUG }} 106 | ${{ env.GHCR_DIST_SLUG }} 107 | tags: ${{ env.IMAGE_TAGS }} 108 | labels: | 109 | org.opencontainers.image.title=alpine-s6-dist 110 | org.opencontainers.image.description=s6 overlay 111 | org.opencontainers.image.vendor=CrazyMax 112 | - 113 | name: Set up QEMU 114 | uses: docker/setup-qemu-action@v3 115 | - 116 | name: Set up Docker Buildx 117 | uses: docker/setup-buildx-action@v3 118 | with: 119 | buildkitd-config-inline: | 120 | [worker.oci] 121 | max-parallelism = 4 122 | - 123 | name: Login to DockerHub 124 | if: github.event_name != 'pull_request' 125 | uses: docker/login-action@v3 126 | with: 127 | username: ${{ secrets.DOCKER_USERNAME }} 128 | password: ${{ secrets.DOCKER_PASSWORD }} 129 | - 130 | name: Login to GitHub Container Registry 131 | if: github.event_name != 'pull_request' 132 | uses: docker/login-action@v3 133 | with: 134 | registry: ghcr.io 135 | username: ${{ github.repository_owner }} 136 | password: ${{ secrets.GITHUB_TOKEN }} 137 | - 138 | name: Build artifacts 139 | uses: docker/bake-action@v6 140 | with: 141 | targets: artifact-all 142 | pull: true 143 | provenance: false 144 | env: 145 | ALPINE_VERSION: ${{ matrix.alpine_version }} 146 | - 147 | name: Move artifacts 148 | if: matrix.alpine_version == env.ALPINE_LATEST 149 | run: | 150 | mv ./dist/**/* ./dist/ 151 | - 152 | name: Upload artifacts 153 | if: matrix.alpine_version == env.ALPINE_LATEST 154 | uses: actions/upload-artifact@v4 155 | with: 156 | name: s6-overlay 157 | path: ./dist/* 158 | if-no-files-found: error 159 | - 160 | name: Build image 161 | uses: docker/bake-action@v6 162 | with: 163 | files: | 164 | ./docker-bake.hcl 165 | cwd://${{ steps.meta.outputs.bake-file }} 166 | targets: image-all 167 | push: ${{ github.event_name != 'pull_request' }} 168 | env: 169 | ALPINE_VERSION: ${{ matrix.alpine_version }} 170 | - 171 | name: Build dist 172 | uses: docker/bake-action@v6 173 | with: 174 | files: | 175 | ./docker-bake.hcl 176 | cwd://${{ steps.meta_dist.outputs.bake-file }} 177 | targets: image-dist-all 178 | pull: true 179 | push: ${{ github.event_name != 'pull_request' }} 180 | env: 181 | ALPINE_VERSION: ${{ matrix.alpine_version }} 182 | - 183 | name: GitHub Release 184 | uses: softprops/action-gh-release@v2 185 | if: matrix.alpine_version == env.ALPINE_LATEST && startsWith(github.ref, 'refs/tags/') 186 | with: 187 | draft: true 188 | files: | 189 | dist/*.tar.gz 190 | dist/*.zip 191 | env: 192 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 193 | - 194 | name: Check manifest 195 | if: github.event_name != 'pull_request' 196 | run: | 197 | docker buildx imagetools inspect ${{ env.DOCKERHUB_SLUG }}:${{ steps.meta.outputs.version }} 198 | docker buildx imagetools inspect ${{ env.GHCR_SLUG }}:${{ steps.meta.outputs.version }} 199 | - 200 | name: Check pull 201 | if: github.event_name != 'pull_request' 202 | run: | 203 | docker pull ${{ env.DOCKERHUB_SLUG }}:${{ steps.meta.outputs.version }} 204 | docker image inspect ${{ env.DOCKERHUB_SLUG }}:${{ steps.meta.outputs.version }} 205 | docker pull ${{ env.GHCR_SLUG }}:${{ steps.meta.outputs.version }} 206 | docker image inspect ${{ env.GHCR_SLUG }}:${{ steps.meta.outputs.version }} 207 | -------------------------------------------------------------------------------- /.github/workflows/labels.yml: -------------------------------------------------------------------------------- 1 | name: labels 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions 8 | permissions: 9 | contents: read 10 | 11 | on: 12 | push: 13 | branches: 14 | - 'master' 15 | paths: 16 | - '.github/labels.yml' 17 | - '.github/workflows/labels.yml' 18 | pull_request: 19 | paths: 20 | - '.github/labels.yml' 21 | - '.github/workflows/labels.yml' 22 | 23 | jobs: 24 | labeler: 25 | runs-on: ubuntu-latest 26 | permissions: 27 | # same as global permissions 28 | contents: read 29 | # required to update labels 30 | issues: write 31 | steps: 32 | - 33 | name: Checkout 34 | uses: actions/checkout@v4 35 | - 36 | name: Run Labeler 37 | uses: crazy-max/ghaction-github-labeler@v5 38 | with: 39 | dry-run: ${{ github.event_name == 'pull_request' }} 40 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: test 2 | 3 | concurrency: 4 | group: ${{ github.workflow }}-${{ github.ref }} 5 | cancel-in-progress: true 6 | 7 | # https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#permissions 8 | permissions: 9 | contents: read 10 | 11 | on: 12 | push: 13 | branches: 14 | - 'master' 15 | - 'releases/*' 16 | paths-ignore: 17 | - '**.md' 18 | pull_request: 19 | branches: 20 | - 'master' 21 | - 'releases/*' 22 | paths-ignore: 23 | - '**.md' 24 | 25 | env: 26 | BUILD_TAG: test 27 | BASE_IMAGE: test-alpine-s6 28 | 29 | jobs: 30 | test: 31 | strategy: 32 | fail-fast: false 33 | matrix: 34 | target: 35 | - legacy-pureftpd 36 | - legacy-rrdtool 37 | alpine_version: 38 | - '3.16' 39 | - '3.17' 40 | - '3.18' 41 | - '3.19' 42 | - '3.20' 43 | - '3.21' 44 | - 'edge' 45 | runs-on: ubuntu-latest 46 | steps: 47 | - 48 | name: Checkout 49 | uses: actions/checkout@v4 50 | - 51 | name: Prepare 52 | run: | 53 | echo "CONTAINER_NAME=${{ matrix.target }}" >> $GITHUB_ENV 54 | echo "LOG_CHECK=$(cat ./test/${{ matrix.target }}/logcheck.txt)" >> $GITHUB_ENV 55 | - 56 | name: Set up Docker Buildx 57 | uses: docker/setup-buildx-action@v3 58 | with: 59 | driver: docker 60 | - 61 | name: Build image 62 | uses: docker/build-push-action@v6 63 | with: 64 | context: . 65 | file: ./Dockerfile 66 | load: true 67 | pull: true 68 | tags: ${{ env.BASE_IMAGE }} 69 | build-args: | 70 | ALPINE_VERSION=${{ matrix.alpine_version }} 71 | - 72 | name: Build ${{ matrix.target }} 73 | uses: docker/build-push-action@v6 74 | with: 75 | context: ./test/${{ matrix.target }} 76 | build-args: | 77 | BASE_IMAGE=${{ env.BASE_IMAGE }} 78 | load: true 79 | tags: ${{ env.BUILD_TAG }} 80 | - 81 | name: Start ${{ matrix.target }} 82 | run: | 83 | docker rm -f ${{ env.CONTAINER_NAME }} > /dev/null 2>&1 || true 84 | docker run -d --name ${{ env.CONTAINER_NAME }} ${{ env.BUILD_TAG }} 85 | - 86 | name: Check container logs 87 | uses: crazy-max/.github/.github/actions/container-logs-check@main 88 | with: 89 | container_name: ${{ env.CONTAINER_NAME }} 90 | log_check: ${{ env.LOG_CHECK }} 91 | timeout: 120 92 | - 93 | name: Build dist 94 | uses: docker/build-push-action@v6 95 | with: 96 | context: . 97 | file: ./Dockerfile 98 | load: true 99 | pull: true 100 | tags: ${{ env.BASE_IMAGE }}-dist 101 | build-args: | 102 | ALPINE_VERSION=${{ matrix.alpine_version }} 103 | - 104 | name: Check dist content 105 | uses: docker/build-push-action@v6 106 | with: 107 | context: ./test 108 | file: ./test/dist.Dockerfile 109 | build-args: | 110 | DIST_IMAGE=${{ env.BASE_IMAGE }}-dist 111 | - 112 | name: Container logs 113 | if: always() 114 | run: | 115 | docker logs ${{ env.CONTAINER_NAME }} 116 | docker rm -f ${{ env.CONTAINER_NAME }} > /dev/null 2>&1 || true 117 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /dist 2 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ## 3.2.0.2-r1 (2025/01/13) 4 | 5 | * Upstream Alpine update 6 | 7 | ## 2.2.0.3-r27 (2025/01/13) 8 | 9 | * Upstream Alpine update 10 | 11 | ## 3.2.0.2-r0 (2024/12/24) 12 | 13 | * s6-overlay 3.2.0.2 (#96) 14 | * Alpine Linux 3.21 (#94) 15 | 16 | ## 2.2.0.3-r26 (2024/12/24) 17 | 18 | * Alpine Linux 3.21 (#95) 19 | 20 | ## 3.2.0.0-r0 (2024/10/05) 21 | 22 | * s6-overlay 3.2.0.0 (#92) 23 | 24 | ## 2.2.0.3-r25 (2024/10/05) 25 | 26 | * Upstream Alpine update 27 | * Workaround for gcc 14 incompatible pointer types (#91) 28 | 29 | ## 3.1.5.0-r2 (2024/05/26) 30 | 31 | * Alpine Linux 3.20 (#81) 32 | 33 | ## 2.2.0.3-r24 (2024/05/26) 34 | 35 | * Alpine Linux 3.20 (#82) 36 | 37 | ## 3.1.5.0-r1 (2023/12/09) 38 | 39 | * Alpine Linux 3.19 (#74) 40 | 41 | ## 2.2.0.3-r23 (2023/12/09) 42 | 43 | * Alpine Linux 3.19 (#75) 44 | 45 | ## 3.1.5.0-r0 (2023/08/13) 46 | 47 | * s6-overlay 3.1.5.0 (#68) 48 | 49 | ## 3.1.4.2-r2 (2023/08/13) 50 | 51 | * Upstream Alpine update 52 | 53 | ## 2.2.0.3-r22 (2023/08/13) 54 | 55 | * Upstream Alpine update 56 | 57 | ## 3.1.4.2-r1 (2023/06/07) 58 | 59 | * Alpine Linux 3.18 (#65) 60 | 61 | ## 2.2.0.3-r21 (2023/06/07) 62 | 63 | * Alpine Linux 3.18 (#67) 64 | 65 | ## 3.1.4.2-r0 (2023/05/02) 66 | 67 | * s6-overlay 3.1.4.2 (#61) 68 | 69 | ## 3.1.1.2-r3 (2023/03/27) 70 | 71 | * Upstream Alpine update 72 | 73 | ## 2.2.0.3-r20 (2023/03/27) 74 | 75 | * Upstream Alpine update 76 | 77 | ## 3.1.1.2-r2 (2022/12/28) 78 | 79 | * Alpine Linux 3.17 (#54) 80 | 81 | ## 3.1.1.2-r1 (2022/07/24) 82 | 83 | * Upstream Alpine update 84 | 85 | ## 2.2.0.3-r18 (2022/07/24) 86 | 87 | * Upstream Alpine update 88 | 89 | ## 3.1.1.2-r0 (2022/07/11) 90 | 91 | * s6-overlay 3.1.1.2 (#53) 92 | 93 | ## 3.1.1.0-r0 (2022/06/19) 94 | 95 | * s6-overlay 3.1.1.0 (#52) 96 | 97 | ## 3.1.0.1-r2 (2022/05/31) 98 | 99 | * Alpine Linux 3.16 (#51) 100 | 101 | ## 2.2.0.3-r17 (2022/05/28) 102 | 103 | * Alpine Linux 3.16 (#50) 104 | 105 | ## 3.1.0.1-r1 (2022/05/15) 106 | 107 | * Upstream Alpine update 108 | 109 | ## 2.2.0.3-r16 (2022/05/15) 110 | 111 | * Upstream Alpine update 112 | 113 | ## 3.1.0.1-r0 (2022/03/26) 114 | 115 | * s6-overlay 3.1.0.1 (#42) 116 | 117 | ## 3.0.0.2-r0 (2022/01/30) 118 | 119 | * s6-overlay 3.0.0.2 (#39) 120 | 121 | ## 2.2.0.3-r15 (2021/12/03) 122 | 123 | * Alpine Linux 3.15 124 | 125 | ## 2.2.0.3-r14 (2021/11/14) 126 | 127 | * Upstream Alpine update 128 | 129 | ## 2.2.0.3-r13 (2021/08/29) 130 | 131 | * Upstream Alpine update 132 | * Update socklog and s6 libs (#32) 133 | 134 | ## 2.2.0.3-r12 (2021/07/03) 135 | 136 | * Alpine Linux 3.14 137 | * Drop Alpine Linux 3.11 support 138 | * Drop s6 2.1 support 139 | 140 | ## 2.2.0.3-r11 / 2.1.0.2-r15 (2021/06/26) 141 | 142 | * Upstream Alpine update 143 | * Move to `docker/metadata-action` 144 | 145 | ## 2.2.0.3-r10 / 2.1.0.2-r14 (2021/04/14) 146 | 147 | * Upstream Alpine update 148 | 149 | ## 2.2.0.3-r9 / 2.1.0.2-r13 (2021/04/01) 150 | 151 | * Upstream Alpine update 152 | 153 | ## 2.2.0.3-r8 / 2.1.0.2-r12 (2021/03/18) 154 | 155 | * Fix s6 tooling compil 156 | * Enhance Dockerfile 157 | * Wrong Alpine release used 158 | 159 | ## 2.2.0.3-r7 / 2.1.0.2-r11 (2021/03/03) 160 | 161 | * Create dist image (#19) 162 | * Add cache on ci (#20) 163 | 164 | ## 2.2.0.3-r6 / 2.1.0.2-r10 (2021/03/02) 165 | 166 | * No need gosu (see https://github.com/crazy-max/gosu#from-dockerfile) 167 | 168 | ## 2.2.0.3-r5 / 2.1.0.2-r9 (2021/03/02) 169 | 170 | * Add gosu 171 | 172 | ## 2.2.0.3-r4 / 2.1.0.2-r8 (2021/02/26) 173 | 174 | * Upstream Alpine update 175 | 176 | ## 2.2.0.3-r3 / 2.1.0.2-r7 (2021/02/24) 177 | 178 | * Upstream Alpine update 179 | 180 | ## 2.1.0.2-r6 (2021/02/20) 181 | 182 | * s6-overlay 2.1 on a dedicated branch 183 | 184 | ## 2.2.0.3-r2 (2021/02/20) 185 | 186 | * s6-overlay-preinit 1.0.5 187 | 188 | ## 2.2.0.3-r1 (2021/02/17) 189 | 190 | * Upstream Alpine update 191 | 192 | ## 2.2.0.3-r0 (2021/02/16) 193 | 194 | * s6-overlay 2.2.0.3 (#17) 195 | 196 | ## 2.2.0.1-r0 (2021/01/22) 197 | 198 | * s6-overlay 2.2.0.1 199 | * Alpine Linux 3.13 200 | * Build skalibs from sources (2.10.0.1) 201 | * Build execline from sources (2.7.0.1) 202 | * Build s6 from sources (2.10.0.1) 203 | * Build s6-dns from sources (2.3.5.0) 204 | * Build s6-linux-utils from sources (2.5.1.4) 205 | * Build s6-networking from sources (2.4.0.0) 206 | * Build s6-portable-utils from sources (2.2.3.1) 207 | * Build s6-rc from sources (0.5.2.1) 208 | * Add justc-installer 1.0.1-2 209 | * justc-envdir 1.0.1-1 210 | * socklog 2.2.2 211 | * socklog-overlay 3.1.1-1 212 | * s6-overlay-preinit 1.0.4 213 | * Switch to buildx bake 214 | 215 | ## 2.1.0.2-RC5 (2021/01/06) 216 | 217 | * Handle alpine edge 218 | 219 | ## 2.1.0.2-RC4 (2020/12/17) 220 | 221 | * Upstream Alpine update 222 | 223 | ## 2.1.0.2-RC3 (2020/12/11) 224 | 225 | * Upstream Alpine update 226 | 227 | ## 2.1.0.2-RC2 (2020/11/25) 228 | 229 | * Upstream Alpine update 230 | 231 | ## 2.1.0.2-RC1 (2020/10/24) 232 | 233 | * s6-overlay 2.1.0.2 234 | 235 | ## 2.1.0.0-RC2 (2020/09/14) 236 | 237 | * Add missing s6-overlay-preinit binary 238 | 239 | ## 2.1.0.0-RC1 (2020/09/13) 240 | 241 | * s6-overlay 2.1.0.0 242 | 243 | ## 2.0.0.1-RC5 (2020/09/04) 244 | 245 | * Add entrypoint (#8) 246 | 247 | ## 2.0.0.1-RC4 (2020/08/10) 248 | 249 | * Keep socklog rules 250 | * Review build stages 251 | 252 | ## 2.0.0.1-RC3 (2020/08/09) 253 | 254 | * Add [socklog-overlay](https://github.com/just-containers/socklog-overlay) 255 | 256 | ## 2.0.0.1-RC2 (2020/08/09) 257 | 258 | * Build `justc-envdir` from sources 259 | 260 | ## 2.0.0.1-RC1 (2020/08/07) 261 | 262 | * Initial version based on [s6-overlay](https://github.com/just-containers/s6-overlay) 2.0.0.1 263 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | # syntax=docker/dockerfile:1 2 | 3 | ARG ALPINE_VERSION="latest" 4 | ARG XX_VERSION="1.6.1" 5 | 6 | ARG S6_OVERLAY_VERSION="3.2.0.2" 7 | ARG S6_OVERLAY_REF="45f4b2122ff1426a943a57a47ed6e796a6609339" 8 | 9 | # https://bearssl.org/gitweb/?p=BearSSL;a=commit;h=3c040368f6791553610e362401db1efff4b4c5b8 10 | ARG BEARSSL_VERSION="0.6" 11 | ARG BEARSSL_REF="3c040368f6791553610e362401db1efff4b4c5b8" 12 | 13 | ARG SKALIBS_VERSION="2.14.3.0" 14 | ARG EXECLINE_VERSION="2.9.6.1" 15 | 16 | ARG S6_VERSION="2.13.1.0" 17 | ARG S6_RC_VERSION="0.5.5.0" 18 | ARG S6_LINUX_INIT_VERSION="1.1.2.1" 19 | ARG S6_PORTABLE_UTILS_VERSION="2.3.0.4" 20 | ARG S6_LINUX_UTILS_VERSION="2.6.2.1" 21 | ARG S6_DNS_VERSION="2.4.0.0" 22 | ARG S6_NETWORKING_VERSION="2.7.0.4" 23 | ARG S6_OVERLAY_HELPERS_VERSION="0.1.1.0" 24 | 25 | FROM --platform=$BUILDPLATFORM tonistiigi/xx:${XX_VERSION} AS xx 26 | FROM --platform=$BUILDPLATFORM alpine:${ALPINE_VERSION} AS alpine 27 | 28 | FROM alpine AS src 29 | RUN apk --update --no-cache add curl git patch tar 30 | WORKDIR /src 31 | 32 | FROM src AS src-s6overlay 33 | ARG S6_OVERLAY_VERSION 34 | ARG S6_OVERLAY_REF 35 | RUN < 2 | Build Status 3 | Docker Stars 4 | Docker Pulls 5 |
Become a sponsor 6 | Donate Paypal 7 |

8 | 9 | ## About 10 | 11 | Alpine Linux with [s6 overlay](https://github.com/just-containers/s6-overlay/). 12 | 13 | > [!TIP] 14 | > Want to be notified of new releases? Check out 🔔 [Diun (Docker Image Update Notifier)](https://github.com/crazy-max/diun) 15 | > project! 16 | 17 | ___ 18 | 19 | * [Features](#features) 20 | * [Usage](#usage) 21 | * [Alpine image](#alpine-image) 22 | * [Dist image](#dist-image) 23 | * [Supported tags](#supported-tags) 24 | * [Build](#build) 25 | * [Contributing](#contributing) 26 | * [License](#license) 27 | 28 | ## Features 29 | 30 | * Multi-platform [alpine based](#alpine-image) and [distribution](#dist-image) images 31 | * Artifacts provided on [releases page](https://github.com/crazy-max/docker-alpine-s6/releases) 32 | 33 | ## Usage 34 | 35 | This repository provides two images. The first one is built on top of alpine 36 | so, you can use it as a base image for your own images: 37 | 38 | ```dockerfile 39 | FROM crazymax/alpine-s6 40 | RUN apk add --no-cache nginx 41 | RUN echo "daemon off;" >> /etc/nginx/nginx.conf 42 | CMD ["/usr/sbin/nginx"] 43 | ``` 44 | 45 | > [!NOTE] 46 | > `ENTRYPOINT ["/init"]` is already defined in the base image so no need to add 47 | > this command. 48 | 49 | The second one is a [distribution image](#dist-image). This is a 50 | multi-platform scratch image that only contains all the scripts and binaries 51 | needed to run s6-overlay. This way you can use any base image and use the 52 | `COPY --from` command to copy the assets inside your image: 53 | 54 | ```dockerfile 55 | FROM ubuntu 56 | COPY --from=crazymax/alpine-s6-dist / / 57 | RUN apt-get update && apt-get install -y nginx 58 | RUN echo "daemon off;" >> /etc/nginx/nginx.conf 59 | CMD ["/usr/sbin/nginx"] 60 | ENTRYPOINT ["/init"] 61 | ``` 62 | 63 | ## Alpine image 64 | 65 | | Registry | Image | 66 | |------------------------------------------------------------------------------------------------------|-------------------------------| 67 | | [Docker Hub](https://hub.docker.com/r/crazymax/alpine-s6/) | `crazymax/alpine-s6` | 68 | | [GitHub Container Registry](https://github.com/users/crazy-max/packages/container/package/alpine-s6) | `ghcr.io/crazy-max/alpine-s6` | 69 | 70 | ``` 71 | $ docker buildx imagetools inspect crazymax/alpine-s6 --format "{{json .Manifest}}" | \ 72 | jq -r '.manifests[] | select(.platform.os != null and .platform.os != "unknown") | .platform | "\(.os)/\(.architecture)\(if .variant then "/" + .variant else "" end)"' 73 | 74 | linux/386 75 | linux/amd64 76 | linux/arm/v6 77 | linux/arm/v7 78 | linux/arm64 79 | linux/ppc64le 80 | linux/riscv64 81 | linux/s390x 82 | ``` 83 | 84 | ## Dist image 85 | 86 | | Registry | Image | 87 | |-----------------------------------------------------------------------------------------------------------|------------------------------------| 88 | | [Docker Hub](https://hub.docker.com/r/crazymax/alpine-s6-dist/) | `crazymax/alpine-s6-dist` | 89 | | [GitHub Container Registry](https://github.com/users/crazy-max/packages/container/package/alpine-s6-dist) | `ghcr.io/crazy-max/alpine-s6-dist` | 90 | 91 | ``` 92 | $ docker buildx imagetools inspect crazymax/alpine-s6-dist --format "{{json .Manifest}}" | \ 93 | jq -r '.manifests[] | select(.platform.os != null and .platform.os != "unknown") | .platform | "\(.os)/\(.architecture)\(if .variant then "/" + .variant else "" end)"' 94 | 95 | linux/386 96 | linux/amd64 97 | linux/arm/v6 98 | linux/arm/v7 99 | linux/arm64 100 | linux/ppc64le 101 | linux/riscv64 102 | linux/s390x 103 | ``` 104 | 105 | ## Supported tags 106 | 107 | * `edge`, `edge-x.x.x.x` 108 | * `latest-edge`, `3.21-edge` 109 | * `latest`, `latest-x.x.x.x`, `3.21`, `3.21-x.x.x.x` 110 | * `3.20-edge` 111 | * `3.20`, `3.20-x.x.x.x` 112 | * `3.19-edge` 113 | * `3.19`, `3.19-x.x.x.x` 114 | * `3.18-edge` 115 | * `3.18`, `3.18-x.x.x.x` 116 | * `3.17-edge` 117 | * `3.17`, `3.17-x.x.x.x` 118 | * `3.16-edge` 119 | * `3.16`, `3.16-x.x.x.x` 120 | 121 | > `x.x.x.x` has to be replaced with one of the s6-overlay releases available (e.g. `3.1.0.1`). 122 | 123 | ## Build 124 | 125 | ```shell 126 | git clone https://github.com/crazy-max/docker-alpine-s6.git 127 | cd docker-alpine-s6 128 | 129 | # Build image and output to docker (default) 130 | docker buildx bake 131 | 132 | # Build tarballs to ./dist 133 | docker buildx bake artifact-all 134 | 135 | # Build multi-platform image 136 | docker buildx bake image-all 137 | 138 | # Build multi-platform dist image 139 | docker buildx bake image-dist-all 140 | ``` 141 | 142 | ## Contributing 143 | 144 | Want to contribute? Awesome! The most basic way to show your support is to star 145 | the project, or to raise issues. You can also support this project by [**becoming a sponsor on GitHub**](https://github.com/sponsors/crazy-max) 146 | or by making a [PayPal donation](https://www.paypal.me/crazyws) to ensure this 147 | journey continues indefinitely! 148 | 149 | Thanks again for your support, it is much appreciated! :pray: 150 | 151 | ## License 152 | 153 | MIT. See `LICENSE` for more details. 154 | -------------------------------------------------------------------------------- /docker-bake.hcl: -------------------------------------------------------------------------------- 1 | // Alpine version 2 | variable "ALPINE_VERSION" { 3 | default = "latest" 4 | } 5 | 6 | target "args" { 7 | args = { 8 | ALPINE_VERSION = ALPINE_VERSION 9 | } 10 | } 11 | 12 | target "platforms" { 13 | platforms = ALPINE_VERSION == "3.21" || ALPINE_VERSION == "3.20" || ALPINE_VERSION == "latest" || ALPINE_VERSION == "edge" ? [ 14 | "linux/386", 15 | "linux/amd64", 16 | "linux/arm64", 17 | "linux/arm/v6", 18 | "linux/arm/v7", 19 | "linux/ppc64le", 20 | "linux/riscv64", 21 | "linux/s390x" 22 | ] : [ 23 | "linux/386", 24 | "linux/amd64", 25 | "linux/arm64", 26 | "linux/arm/v6", 27 | "linux/arm/v7", 28 | "linux/ppc64le", 29 | "linux/s390x" 30 | ] 31 | } 32 | 33 | // Special target: https://github.com/docker/metadata-action#bake-definition 34 | target "docker-metadata-action" { 35 | tags = ["alpine-s6:local"] 36 | } 37 | 38 | group "default" { 39 | targets = ["image-local"] 40 | } 41 | 42 | target "artifact" { 43 | inherits = ["args"] 44 | target = "artifact" 45 | output = ["./dist"] 46 | } 47 | 48 | target "artifact-all" { 49 | inherits = ["platforms", "artifact"] 50 | } 51 | 52 | target "image" { 53 | inherits = ["args", "docker-metadata-action"] 54 | } 55 | 56 | target "image-local" { 57 | inherits = ["image"] 58 | output = ["type=docker"] 59 | } 60 | 61 | target "image-all" { 62 | inherits = ["platforms", "image"] 63 | } 64 | 65 | target "image-dist" { 66 | inherits = ["image"] 67 | target = "dist" 68 | } 69 | 70 | target "image-dist-local" { 71 | inherits = ["image-dist"] 72 | output = ["type=docker"] 73 | } 74 | 75 | target "image-dist-all" { 76 | inherits = ["platforms", "image-dist"] 77 | } 78 | -------------------------------------------------------------------------------- /test/dist.Dockerfile: -------------------------------------------------------------------------------- 1 | ARG DIST_IMAGE 2 | 3 | FROM ${DIST_IMAGE:-test-alpine-s6-dist} AS s6-dist 4 | FROM alpine 5 | RUN apk add tree 6 | COPY --from=s6-dist / /dist 7 | RUN tree /dist 8 | -------------------------------------------------------------------------------- /test/legacy-pureftpd/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG BASE_IMAGE 2 | ARG PUREFTPD_VERSION=1.0.47 3 | 4 | FROM ${BASE_IMAGE:-test-alpine-s6} AS builder 5 | ARG PUREFTPD_VERSION 6 | 7 | RUN apk --update --no-cache add curl patch tar 8 | WORKDIR /dist/pureftpd 9 | COPY patchs /dist 10 | RUN curl -sSL "https://download.pureftpd.org/pub/pure-ftpd/releases/obsolete/pure-ftpd-${PUREFTPD_VERSION}.tar.gz" | tar xz --strip 1 \ 11 | && patch -p1 < ../minimal.patch 12 | 13 | RUN apk --update --no-cache add \ 14 | autoconf \ 15 | automake \ 16 | binutils \ 17 | build-base \ 18 | gnu-libiconv-dev \ 19 | libsodium-dev \ 20 | mariadb-connector-c-dev \ 21 | openldap-dev \ 22 | postgresql-dev \ 23 | openssl-dev \ 24 | tree 25 | 26 | RUN ./configure \ 27 | --prefix=/pure-ftpd \ 28 | --without-humor \ 29 | --without-inetd \ 30 | --without-pam \ 31 | --with-altlog \ 32 | --with-cookie \ 33 | --with-ftpwho \ 34 | --with-ldap \ 35 | --with-mysql \ 36 | --with-pgsql \ 37 | --with-puredb \ 38 | --with-quotas \ 39 | --with-ratios \ 40 | --with-rfc2640 \ 41 | --with-throttling \ 42 | --with-tls \ 43 | --with-uploadscript \ 44 | --with-brokenrealpath \ 45 | --with-certfile=/data/pureftpd.pem \ 46 | && make install-strip \ 47 | && tree /pure-ftpd 48 | 49 | FROM ${BASE_IMAGE:-test-alpine-s6} 50 | 51 | ENV S6_BEHAVIOUR_IF_STAGE2_FAILS="2" \ 52 | SOCKLOG_TIMESTAMP_FORMAT="" \ 53 | PURE_PASSWDFILE="/data/pureftpd.passwd" \ 54 | PURE_DBFILE="/data/pureftpd.pdb" \ 55 | TZ="UTC" 56 | 57 | RUN apk --update --no-cache add \ 58 | bind-tools \ 59 | gnu-libiconv \ 60 | libldap \ 61 | libpq \ 62 | libsodium \ 63 | mariadb-connector-c \ 64 | mysql-client \ 65 | openldap-clients \ 66 | openssl \ 67 | postgresql-client \ 68 | tzdata \ 69 | zlib \ 70 | && rm -f /etc/socklog.rules/* 71 | 72 | COPY --from=builder /pure-ftpd / 73 | COPY rootfs / 74 | 75 | RUN mkdir -p /data && pure-ftpwho --help 76 | 77 | EXPOSE 2100 30000-30009 78 | WORKDIR /data 79 | VOLUME [ "/data" ] 80 | -------------------------------------------------------------------------------- /test/legacy-pureftpd/logcheck.txt: -------------------------------------------------------------------------------- 1 | service legacy-services successfully started -------------------------------------------------------------------------------- /test/legacy-pureftpd/patchs/minimal.patch: -------------------------------------------------------------------------------- 1 | diff --git a/src/ftpd.c b/src/ftpd.c 2 | index 60b95b6..6aee9bc 100644 3 | --- a/src/ftpd.c 4 | +++ b/src/ftpd.c 5 | @@ -1080,8 +1080,6 @@ void dobanner(const int type) 6 | 7 | #endif 8 | 9 | -#ifndef MINIMAL 10 | - 11 | int modernformat(const char *file, char *target, size_t target_size, 12 | const char * const prefix) 13 | { 14 | @@ -1228,8 +1226,6 @@ void doallo(const off_t size) 15 | } 16 | } 17 | 18 | -#endif 19 | - 20 | void dositetime(void) 21 | { 22 | char tmp[64]; 23 | -------------------------------------------------------------------------------- /test/legacy-pureftpd/rootfs/etc/cont-init.d/01-config.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv sh 2 | # shellcheck shell=sh 3 | 4 | TZ=${TZ:-UTC} 5 | AUTH_METHOD=${AUTH_METHOD:-puredb} 6 | SECURE_MODE=${SECURE_MODE:-true} 7 | PASSIVE_IP=${PASSIVE_IP:-$(dig +short myip.opendns.com @resolver1.opendns.com)} 8 | PASSIVE_PORT_RANGE=${PASSIVE_PORT_RANGE:-30000:30009} 9 | DB_TIMEOUT=${DB_TIMEOUT:-45} 10 | 11 | extractFromConf() { 12 | awk -F' ' "/^${1}/ { print \$2 }" < "$2" 13 | } 14 | 15 | PFTPD_FLAGS="/data/pureftpd.flags" 16 | PFTPD_PUREDB="/data/pureftpd.pdb" 17 | PFTPD_PASSWD="/data/pureftpd.passwd" 18 | PFTPD_MYSQL_CONF="/data/pureftpd-mysql.conf" 19 | PFTPD_PGSQL_CONF="/data/pureftpd-pgsql.conf" 20 | PFTPD_LDAP_CONF="/data/pureftpd-ldap.conf" 21 | PFTPD_PEM="/data/pureftpd.pem" 22 | PFTPD_DHPARAMS="/data/pureftpd-dhparams.pem" 23 | 24 | ADD_FLAGS="" 25 | if [ -f "${PFTPD_FLAGS}" ]; then 26 | while read FLAG; do 27 | test -z "$FLAG" && continue 28 | ADD_FLAGS="$ADD_FLAGS $FLAG" 29 | done < ${PFTPD_FLAGS} 30 | FLAGS="$FLAGS$ADD_FLAGS" 31 | fi 32 | 33 | FLAGS="$FLAGS --bind 0.0.0.0,2100" 34 | FLAGS="$FLAGS --ipv4only" 35 | FLAGS="$FLAGS --passiveportrange ${PASSIVE_PORT_RANGE}" 36 | FLAGS="$FLAGS --noanonymous" 37 | FLAGS="$FLAGS --createhomedir" 38 | FLAGS="$FLAGS --nochmod" 39 | FLAGS="$FLAGS --syslogfacility ftp" 40 | 41 | if [ -n "$PASSIVE_IP" ]; then 42 | FLAGS="$FLAGS --forcepassiveip $PASSIVE_IP" 43 | fi 44 | 45 | # Secure mode 46 | SECURE_FLAGS="" 47 | if [ "$SECURE_MODE" = "true" ]; then 48 | SECURE_FLAGS="$SECURE_FLAGS --maxclientsnumber 5" 49 | SECURE_FLAGS="$SECURE_FLAGS --maxclientsperip 5" 50 | SECURE_FLAGS="$SECURE_FLAGS --antiwarez" 51 | SECURE_FLAGS="$SECURE_FLAGS --customerproof" 52 | SECURE_FLAGS="$SECURE_FLAGS --dontresolve" 53 | SECURE_FLAGS="$SECURE_FLAGS --norename" 54 | SECURE_FLAGS="$SECURE_FLAGS --prohibitdotfilesread" 55 | SECURE_FLAGS="$SECURE_FLAGS --prohibitdotfileswrite" 56 | FLAGS="$FLAGS$SECURE_FLAGS" 57 | fi 58 | 59 | # Timezone 60 | echo "Setting timezone to ${TZ}..." 61 | ln -snf /usr/share/zoneinfo/${TZ} /etc/localtime 62 | echo ${TZ} > /etc/timezone 63 | 64 | # MySQL auth 65 | if [ "$AUTH_METHOD" = "mysql" ]; then 66 | FLAGS="$FLAGS --login mysql:${PFTPD_MYSQL_CONF}" 67 | if [ ! -f "${PFTPD_MYSQL_CONF}" ]; then 68 | >&2 echo "ERROR: ${PFTPD_MYSQL_CONF} does not exist" 69 | exit 1 70 | fi 71 | echo "Use MySQL authentication method" 72 | 73 | DB_HOST=$(extractFromConf "MYSQLServer" ${PFTPD_MYSQL_CONF}) 74 | DB_PORT=$(extractFromConf "MYSQLPort" ${PFTPD_MYSQL_CONF}) 75 | DB_USER=$(extractFromConf "MYSQLUser" ${PFTPD_MYSQL_CONF}) 76 | DB_PASSWORD=$(extractFromConf "MYSQLPassword" ${PFTPD_MYSQL_CONF}) 77 | DB_CMD="mysql -h ${DB_HOST} -P ${DB_PORT} -u ${DB_USER} "-p${DB_PASSWORD}"" 78 | #echo "DB_CMD=$DB_CMD" 79 | 80 | echo "Waiting ${DB_TIMEOUT}s for MySQL database to be ready..." 81 | counter=1 82 | while ! ${DB_CMD} -e "show databases;" > /dev/null 2>&1; do 83 | sleep 1 84 | counter=$((counter + 1)) 85 | if [ ${counter} -gt "${DB_TIMEOUT}" ]; then 86 | >&2 echo "ERROR: Failed to connect to MySQL database on $DB_HOST" 87 | exit 1 88 | fi; 89 | done 90 | echo "MySQL database ready!" 91 | unset DB_USER DB_PASSWORD DB_CMD 92 | 93 | # PostgreSQL auth 94 | elif [ "$AUTH_METHOD" = "pgsql" ]; then 95 | FLAGS="$FLAGS --login pgsql:${PFTPD_PGSQL_CONF}" 96 | if [ ! -f "${PFTPD_PGSQL_CONF}" ]; then 97 | >&2 echo "ERROR: ${PFTPD_PGSQL_CONF} does not exist" 98 | exit 1 99 | fi 100 | echo "Use PostgreSQL authentication method" 101 | 102 | DB_HOST=$(extractFromConf "PGSQLServer" ${PFTPD_PGSQL_CONF}) 103 | DB_PORT=$(extractFromConf "PGSQLPort" ${PFTPD_PGSQL_CONF}) 104 | DB_USER=$(extractFromConf "PGSQLUser" ${PFTPD_PGSQL_CONF}) 105 | DB_PASSWORD=$(extractFromConf "PGSQLPassword" ${PFTPD_PGSQL_CONF}) 106 | DB_NAME=$(extractFromConf "PGSQLDatabase" ${PFTPD_PGSQL_CONF}) 107 | export PGPASSWORD=${DB_PASSWORD} 108 | DB_CMD="psql --host=${DB_HOST} --port=${DB_PORT} --username=${DB_USER} -lqt" 109 | #echo "DB_CMD=$DB_CMD" 110 | 111 | echo "Waiting ${DB_TIMEOUT}s for database to be ready..." 112 | counter=1 113 | while ${DB_CMD} | cut -d \| -f 1 | grep -qw "${DB_NAME}" > /dev/null 2>&1; [ $? -ne 0 ]; do 114 | sleep 1 115 | counter=$((counter + 1)) 116 | if [ ${counter} -gt "${DB_TIMEOUT}" ]; then 117 | >&2 echo "ERROR: Failed to connect to PostgreSQL database on $DB_HOST" 118 | exit 1 119 | fi; 120 | done 121 | echo "PostgreSQL database ready!" 122 | unset DB_USER DB_PASSWORD DB_CMD PGPASSWORD 123 | 124 | # LDAP auth 125 | elif [ "$AUTH_METHOD" = "ldap" ]; then 126 | FLAGS="$FLAGS --login ldap:${PFTPD_LDAP_CONF}" 127 | if [ ! -f "${PFTPD_LDAP_CONF}" ]; then 128 | >&2 echo "ERROR: ${PFTPD_LDAP_CONF} does not exist" 129 | exit 1 130 | fi 131 | 132 | # PureDB auth 133 | else 134 | AUTH_METHOD="puredb" 135 | FLAGS="$FLAGS --login puredb:${PFTPD_PUREDB}" 136 | touch "${PFTPD_PUREDB}" "${PFTPD_PASSWD}" 137 | pure-pw mkdb "${PFTPD_PUREDB}" -f "${PFTPD_PASSWD}" 138 | echo "Use PureDB authentication method" 139 | fi 140 | 141 | # Set uploadscript if defined 142 | if [ -f "$UPLOADSCRIPT" ]; then 143 | FLAGS="$FLAGS --uploadscript" 144 | fi 145 | 146 | # Check TLS cert 147 | if [ -f "$PFTPD_PEM" ]; then 148 | chmod 600 "$PFTPD_PEM" 149 | fi 150 | if [ -f "$PFTPD_DHPARAMS" ]; then 151 | chmod 600 "$PFTPD_DHPARAMS" 152 | ln -sf "$PFTPD_DHPARAMS" "/etc/ssl/private/pure-ftpd-dhparams.pem" 153 | fi 154 | 155 | echo "Flags" 156 | echo " Secure:$SECURE_FLAGS" 157 | echo " Additional:$ADD_FLAGS" 158 | echo " All:$FLAGS" 159 | 160 | printf "%s" "$FLAGS" > /var/run/s6/container_environment/PUREFTPD_FLAGS 161 | -------------------------------------------------------------------------------- /test/legacy-pureftpd/rootfs/etc/cont-init.d/02-service.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv sh 2 | # shellcheck shell=sh 3 | 4 | mkdir -p /etc/services.d/pure-ftpd 5 | 6 | env|sort 7 | 8 | cat >/etc/services.d/pure-ftpd/run </etc/services.d/pure-ftpd/finish <&2 "pure-ftpd exited. code=${1}" 18 | exec s6-svscanctl -t /run/service 19 | EOL 20 | chmod +x /etc/services.d/pure-ftpd/finish 21 | -------------------------------------------------------------------------------- /test/legacy-pureftpd/rootfs/etc/cont-init.d/03-uploadscript.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/with-contenv sh 2 | # shellcheck shell=sh 3 | 4 | #UPLOADSCRIPT=${UPLOADSCRIPT:-/data/uploadscript.sh} 5 | 6 | if [ -z "$UPLOADSCRIPT" ]; then 7 | exit 0 8 | fi 9 | if [ ! -f "$UPLOADSCRIPT" ]; then 10 | >&2 echo "ERROR: UPLOADSCRIPT program/script is not defined or does not exist" 11 | exit 1 12 | fi 13 | 14 | mkdir -p /etc/services.d/pure-uploadscript 15 | cat > /etc/services.d/pure-uploadscript/run < /etc/services.d/rrdcached/run <