└── flyway-docker ├── .gitattributes ├── .gitignore ├── LICENSE ├── Makefile ├── README.md ├── dockerfiles ├── Dockerfile ├── Dockerfile-mongo ├── alpine │ ├── Dockerfile │ └── Dockerfile-mongo └── azure │ ├── Dockerfile │ └── Dockerfile-mongo ├── enterprise └── README.md ├── lastVersion.sh ├── scripts ├── build_images.py ├── download_artifacts.py ├── release.py ├── test_images.py └── utils.py └── test-sql ├── .sqlfluff └── V1__table.sql /flyway-docker/.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | 3 | *.ico binary 4 | *.png binary 5 | *.gif binary 6 | *.jar binary 7 | *.nofilter binary 8 | -------------------------------------------------------------------------------- /flyway-docker/.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | build 3 | target 4 | *.iml 5 | *.ipr 6 | *.iws 7 | *.ids 8 | .project 9 | .classpath 10 | .settings 11 | .metadata 12 | .idea 13 | .gradle 14 | *.h2.db 15 | .DS_Store 16 | -------------------------------------------------------------------------------- /flyway-docker/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /flyway-docker/Makefile: -------------------------------------------------------------------------------- 1 | get_artifacts: 2 | python ./scripts/download_artifacts.py $(EDITION) $(VERSION) 3 | 4 | build: 5 | python ./scripts/build_images.py $(EDITION) $(VERSION) 6 | 7 | test: 8 | python ./scripts/test_images.py $(EDITION) $(VERSION) $(EXTRA_ARGS) 9 | 10 | release: 11 | python ./scripts/release.py $(EDITION) $(VERSION) 12 | -------------------------------------------------------------------------------- /flyway-docker/README.md: -------------------------------------------------------------------------------- 1 | # Flyway Open Source Docker images 2 | 3 | This is the repository for [Flyway Command-line⁠](https://documentation.red-gate.com/fd/welcome-to-flyway-184127914.html) Open Source images. 4 | 5 | For the officially certified Redgate Flyway Docker images, use [Redgate/Flyway](https://hub.docker.com/r/redgate/flyway/) on Dockerhub, which works across the complete range of Flyway editions, including Community, Teams and Enterprise. 6 | 7 | [Redgate/Flyway](https://hub.docker.com/r/redgate/flyway/) also provides compatibility with [Flyway Pipelines](https://flyway.red-gate.com/pipelines). Flyway Pipelines will help you gain centralized visibility of the state of your database deployments across projects so you can see what has been deployed, when and where for easy tracking. 8 | 9 | ## Suggested Project Structure 10 | 11 | To make it easy to run Flyway the way you want to, you can use the following folders in your Flyway project 12 | 13 | Volume | Usage 14 | ------------------|------ 15 | `/flyway/conf` | Directory containing a `flyway.conf/toml` [configuration file](https://documentation.red-gate.com/fd/configuration-files-224003079.html) 16 | `/flyway/drivers` | Directory containing the [JDBC driver for your database](https://documentation.red-gate.com/fd/command-line-184127404.html#jdbc-drivers) 17 | `/flyway/sql` | The SQL files that you want Flyway to use (for [SQL-based migrations](https://documentation.red-gate.com/fd/migrations-184127470.html#sql-based-migrations)) 18 | `/flyway/jars` | The jars files that you want Flyway to use (for [Java-based migrations](https://documentation.red-gate.com/fd/migrations-184127470.html#java-based-migrations)) 19 | 20 | ## Getting started 21 | 22 | The easiest way to get started is simply to test the default image by running 23 | 24 | `docker run --rm flyway/flyway` 25 | 26 | This will give you Flyway Command-line's usage instructions. 27 | 28 | To do anything useful however, you must pass the arguments that you need to the image. For example: 29 | 30 | `docker run --rm flyway/flyway -url=jdbc:sqlite:dev.db info` 31 | 32 | Note that the syntax for **flyway/flyway:\*-azure** is slightly different in order to be compatible with Azure Pipelines 33 | agent job requirements. As it does not define an entrypoint, you need to explicitly add the `flyway` command. For example: 34 | 35 | `docker run --rm flyway/flyway:latest-azure flyway` 36 | 37 | ## Adding SQL files 38 | 39 | To add your own SQL files, place them in a directory, mount it and point flyway at it using the [`workingDirectory`](https://documentation.red-gate.com/fd/working-directory-224919763.html) parameter. 40 | 41 | ### Example 42 | 43 | Create a new `/sql` directory in your project folder and add a file named `V1__Initial.sql` with following contents: 44 | 45 | ```sql 46 | CREATE TABLE MyTable ( 47 | MyColumn VARCHAR(100) NOT NULL 48 | ); 49 | ``` 50 | 51 | Now run the image with the volume mapped: 52 | 53 | `docker run --rm -v /absolute/path/to/my/project_folder:/flyway/project flyway/flyway -url=jdbc:sqlite:dev.db -workingDirectory="project" migrate` 54 | 55 | ## Adding a config file 56 | 57 | If you prefer to store arguments in a config file you can put that in your project folder. 58 | 59 | ### Example 60 | 61 | Create a file named `flyway.toml` with the following contents: 62 | 63 | ``` 64 | [environments.development] 65 | url = "jdbc:sqlite:/flyway/project/dev.db" 66 | user= "admin" 67 | password = "password1" 68 | 69 | [flyway] 70 | environment = "development" 71 | ``` 72 | 73 | Now run the image with that volume mapped as well: 74 | 75 | `docker run --rm -v /absolute/path/to/my/project_folder:/flyway/project flyway/flyway migrate -workingDirectory="project"` 76 | 77 | ## Adding a JDBC driver 78 | 79 | If your database driver is not shipped by default (you can check the [official documentation here](https://documentation.red-gate.com/fd/supported-databases-184127454.html) to see if it is), or if you want to use a different or newer driver than the one included you can create a `drivers/` folder in your project folder. 80 | 81 | ## Adding Java-based migrations and callbacks 82 | 83 | To pass in Java-based migrations and callbacks you can use a `jars/` folder in your project directory and place them in there. 84 | 85 | ## Docker Compose 86 | 87 | To run both Flyway and the database that will be migrated in containers, you can use a `docker-compose.yml` file that 88 | starts and links both containers. 89 | 90 | ### Example 91 | 92 | ``` 93 | version: '3' 94 | services: 95 | flyway: 96 | image: flyway/flyway 97 | command: -url=jdbc:mysql://db -schemas=myschema -user=root -password=P@ssw0rd -connectRetries=60 migrate 98 | volumes: 99 | - .:/flyway/sql 100 | depends_on: 101 | - db 102 | db: 103 | image: mysql 104 | environment: 105 | - MYSQL_ROOT_PASSWORD=P@ssw0rd 106 | command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci 107 | ports: 108 | - 3306:3306 109 | ``` 110 | 111 | Run `docker-compose up`, this will start both Flyway and MySQL. Flyway will automatically wait for up to one minute for MySQL to be initialized before it begins to migrate the database. 112 | -------------------------------------------------------------------------------- /flyway-docker/dockerfiles/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bash:5 AS untar 2 | 3 | WORKDIR /flyway 4 | 5 | ARG FLYWAY_VERSION 6 | 7 | COPY flyway-commandline-${FLYWAY_VERSION}.tar.gz . 8 | 9 | RUN gzip -d flyway-commandline-${FLYWAY_VERSION}.tar.gz \ 10 | && tar -xf flyway-commandline-${FLYWAY_VERSION}.tar --strip-components=1 \ 11 | && rm flyway-commandline-${FLYWAY_VERSION}.tar \ 12 | && chmod -R a+r /flyway \ 13 | && chmod a+x /flyway/flyway 14 | 15 | FROM eclipse-temurin:17-jre-jammy AS flyway 16 | 17 | ARG FLYWAY_VERSION 18 | LABEL "org.opencontainers.image.version"="${FLYWAY_VERSION}" 19 | 20 | WORKDIR /flyway 21 | 22 | COPY --from=untar /flyway /flyway 23 | 24 | ENV PATH="/flyway:${PATH}" 25 | 26 | ENTRYPOINT ["flyway"] 27 | CMD ["-?"] 28 | 29 | FROM flyway AS redgate 30 | 31 | ENV REDGATE_DOCKER=true 32 | ARG SQLFLUFF_VERSION=3.0.7 33 | 34 | RUN apt-get update \ 35 | && apt-get install -y --no-install-recommends python3-pip \ 36 | && apt-get install -y --no-install-recommends libc6 libgcc1 libgcc-s1 libgssapi-krb5-2 libicu70 liblttng-ust1 libssl3 libstdc++6 libunwind8 zlib1g \ 37 | && pip3 install sqlfluff==${SQLFLUFF_VERSION} 38 | -------------------------------------------------------------------------------- /flyway-docker/dockerfiles/Dockerfile-mongo: -------------------------------------------------------------------------------- 1 | FROM bash:5 AS untar 2 | 3 | WORKDIR /flyway 4 | 5 | ARG FLYWAY_VERSION 6 | 7 | COPY flyway-commandline-${FLYWAY_VERSION}.tar.gz . 8 | 9 | RUN gzip -d flyway-commandline-${FLYWAY_VERSION}.tar.gz \ 10 | && tar -xf flyway-commandline-${FLYWAY_VERSION}.tar --strip-components=1 \ 11 | && rm flyway-commandline-${FLYWAY_VERSION}.tar \ 12 | && chmod -R a+r /flyway \ 13 | && chmod a+x /flyway/flyway 14 | 15 | FROM eclipse-temurin:17-jre-jammy AS flyway 16 | 17 | ARG FLYWAY_VERSION 18 | LABEL "org.opencontainers.image.version"="${FLYWAY_VERSION}" 19 | 20 | WORKDIR /flyway 21 | 22 | COPY --from=untar /flyway /flyway 23 | 24 | ENV PATH="/flyway:${PATH}" 25 | 26 | ENTRYPOINT ["flyway"] 27 | CMD ["-?"] 28 | 29 | FROM flyway as mongo 30 | 31 | RUN wget -qO- https://www.mongodb.org/static/pgp/server-8.0.asc | tee /etc/apt/trusted.gpg.d/server-8.0.asc 32 | RUN echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/8.0 multiverse" | tee /etc/apt/sources.list.d/mongodb-org-8.0.list 33 | RUN apt-get update 34 | RUN apt-get install -y mongodb-mongosh -------------------------------------------------------------------------------- /flyway-docker/dockerfiles/alpine/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bash:5 AS untar 2 | 3 | WORKDIR /flyway 4 | 5 | ARG FLYWAY_VERSION 6 | 7 | COPY flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar.gz . 8 | 9 | RUN gzip -d flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar.gz \ 10 | && tar -xf flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar --strip-components=1 \ 11 | && rm flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar \ 12 | && rm -rf /flyway/jre \ 13 | && chmod -R a+r /flyway \ 14 | && chmod a+x /flyway/flyway 15 | 16 | FROM eclipse-temurin:17-jre-alpine AS flyway 17 | 18 | ARG FLYWAY_VERSION 19 | LABEL "org.opencontainers.image.version"="${FLYWAY_VERSION}" 20 | 21 | RUN apk --no-cache add --update bash openssl 22 | 23 | WORKDIR /flyway 24 | 25 | COPY --from=untar /flyway /flyway 26 | 27 | ENV PATH="/flyway:${PATH}" 28 | 29 | ENTRYPOINT ["flyway"] 30 | CMD ["-?"] 31 | 32 | FROM flyway AS redgate 33 | 34 | ENV REDGATE_DOCKER=true 35 | ARG SQLFLUFF_VERSION=3.0.7 36 | 37 | RUN apk add --no-cache icu-libs krb5-libs libgcc libintl libssl3 libstdc++ zlib \ 38 | && apk --no-cache add --update python3 py3-pip \ 39 | && pip3 install --break-system-packages sqlfluff==${SQLFLUFF_VERSION} 40 | -------------------------------------------------------------------------------- /flyway-docker/dockerfiles/alpine/Dockerfile-mongo: -------------------------------------------------------------------------------- 1 | FROM bash:5 AS untar 2 | 3 | WORKDIR /flyway 4 | 5 | ARG FLYWAY_VERSION 6 | 7 | COPY flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar.gz . 8 | 9 | RUN gzip -d flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar.gz \ 10 | && tar -xf flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar --strip-components=1 \ 11 | && rm flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar \ 12 | && rm -rf /flyway/jre \ 13 | && chmod -R a+r /flyway \ 14 | && chmod a+x /flyway/flyway 15 | 16 | FROM eclipse-temurin:17-jre-alpine AS flyway 17 | 18 | ARG FLYWAY_VERSION 19 | LABEL "org.opencontainers.image.version"="${FLYWAY_VERSION}" 20 | 21 | RUN apk --no-cache add --update bash openssl 22 | 23 | WORKDIR /flyway 24 | 25 | COPY --from=untar /flyway /flyway 26 | 27 | ENV PATH="/flyway:${PATH}" 28 | 29 | ENTRYPOINT ["flyway"] 30 | CMD ["-?"] 31 | 32 | FROM flyway as mongo 33 | 34 | RUN apk --no-cache add --update npm 35 | 36 | RUN npm install -g mongosh -------------------------------------------------------------------------------- /flyway-docker/dockerfiles/azure/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM bash:5 AS untar 2 | 3 | WORKDIR /flyway 4 | 5 | ARG FLYWAY_VERSION 6 | 7 | COPY flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar.gz . 8 | 9 | RUN gzip -d flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar.gz \ 10 | && tar -xf flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar --strip-components=1 \ 11 | && rm flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar \ 12 | && chmod -R a+r /flyway \ 13 | && chmod a+x /flyway/flyway 14 | 15 | # Azure pipeline agents require specific things in their containers: 16 | # https://docs.microsoft.com/en-us/azure/devops/pipelines/process/container-phases?view=azure-devops#linux-based-containers 17 | 18 | FROM node:22-alpine AS flyway 19 | 20 | ARG FLYWAY_VERSION 21 | LABEL "org.opencontainers.image.version"="${FLYWAY_VERSION}" 22 | 23 | ENV LANG C.UTF-8 24 | 25 | RUN apk add --no-cache --virtual .pipeline-deps readline linux-pam \ 26 | && apk add bash sudo shadow openssl curl tar \ 27 | && apk del .pipeline-deps 28 | 29 | LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node" 30 | 31 | WORKDIR /flyway 32 | 33 | COPY --from=untar /flyway /flyway 34 | RUN ln -s /flyway/flyway /usr/local/bin/flyway 35 | 36 | FROM flyway AS redgate 37 | 38 | ENV REDGATE_DOCKER=true 39 | ARG SQLFLUFF_VERSION=3.0.7 40 | 41 | RUN apk add --no-cache icu-libs krb5-libs libgcc libintl libssl3 libstdc++ zlib icu \ 42 | && apk --no-cache add --update g++ python3 python3-dev py3-pip \ 43 | && pip3 install --break-system-packages sqlfluff==${SQLFLUFF_VERSION} 44 | -------------------------------------------------------------------------------- /flyway-docker/dockerfiles/azure/Dockerfile-mongo: -------------------------------------------------------------------------------- 1 | FROM bash:5 AS untar 2 | 3 | WORKDIR /flyway 4 | 5 | ARG FLYWAY_VERSION 6 | 7 | COPY flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar.gz . 8 | 9 | RUN gzip -d flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar.gz \ 10 | && tar -xf flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar --strip-components=1 \ 11 | && rm flyway-commandline-${FLYWAY_VERSION}-linux-alpine-x64.tar \ 12 | && chmod -R a+r /flyway \ 13 | && chmod a+x /flyway/flyway 14 | 15 | # Azure pipeline agents require specific things in their containers: 16 | # https://docs.microsoft.com/en-us/azure/devops/pipelines/process/container-phases?view=azure-devops#linux-based-containers 17 | 18 | FROM node:22-alpine AS flyway 19 | 20 | ARG FLYWAY_VERSION 21 | LABEL "org.opencontainers.image.version"="${FLYWAY_VERSION}" 22 | 23 | ENV LANG C.UTF-8 24 | 25 | RUN apk add --no-cache --virtual .pipeline-deps readline linux-pam \ 26 | && apk add bash sudo shadow openssl curl tar \ 27 | && apk del .pipeline-deps 28 | 29 | LABEL "com.azure.dev.pipelines.agent.handler.node.path"="/usr/local/bin/node" 30 | 31 | WORKDIR /flyway 32 | 33 | COPY --from=untar /flyway /flyway 34 | RUN ln -s /flyway/flyway /usr/local/bin/flyway 35 | 36 | FROM flyway as mongo 37 | 38 | RUN npm install -g mongosh -------------------------------------------------------------------------------- /flyway-docker/enterprise/README.md: -------------------------------------------------------------------------------- 1 | # Official Redgate Flyway Docker images 2 | 3 | This is the official repository for [Flyway Command-line](https://documentation.red-gate.com/fd/welcome-to-flyway-184127914.html) images. 4 | 5 | These images work across the complete range of Redgate Flyway editions, including Community, Teams and Enterprise, as well as providing compatibility with [Flyway Pipelines](https://flyway.red-gate.com/pipelines). Flyway Pipelines will help you gain centralized visibility of the state of your database deployments across projects so you can see what has been deployed, when and where for easy tracking. 6 | 7 | ## Supported Volumes 8 | 9 | To make it easy to run Flyway the way you want to, the following volumes are supported: 10 | 11 | Volume | Usage 12 | ------------------|------ 13 | `/flyway/conf` | Directory containing a [configuration file](https://documentation.red-gate.com/fd/configuration-files-224003079.html) 14 | `/flyway/drivers` | Directory containing the [JDBC driver for your database](https://documentation.red-gate.com/fd/command-line-184127404.html) 15 | `/flyway/sql` | The SQL files that you want Flyway to use (for [SQL-based migrations](https://documentation.red-gate.com/fd/migrations-184127470.html)) 16 | `/flyway/jars` | The jar files that you want Flyway to use (for [Java-based migrations](https://documentation.red-gate.com/fd/migrations-184127470.html)) 17 | 18 | ## Getting started 19 | 20 | The easiest way to get started is simply to test the default image by running 21 | 22 | `docker run --rm redgate/flyway` 23 | 24 | This will give you Flyway Command-line's usage instructions. 25 | 26 | To do anything useful however, you must pass the arguments that you need to the image. For example: 27 | 28 | `docker run --rm redgate/flyway -licenseKey="FL01..." -url=jdbc:h2:mem:test -user=sa info` 29 | 30 | Note that the syntax for **redgate/flyway:\*-azure** is slightly different in order to be compatible with Azure Pipelines 31 | agent job requirements. As it does not define an entrypoint, you need to explicitly add the `flyway` command. For example: 32 | 33 | `docker run --rm redgate/flyway:latest-azure flyway` 34 | 35 | ## Flyway Pipelines 36 | 37 | To learn more about Flyway Pipelines you can access our [official documentation](https://documentation.red-gate.com/fd/introducing-flyway-pipelines-251363987.html) 38 | 39 | You can access the Flyway Pipelines service here: https://flyway.red-gate.com/ 40 | 41 | To use Flyway Pipelines, you will need a [Personal Access Token](https://documentation.red-gate.com/fd/personal-access-tokens-251363983.html). 42 | 43 | ### Example 44 | 45 | To use the Flyway service within this image, include the following: 46 | ``` 47 | docker run --rm -v /absolute/path/to/my/sqldir:/flyway/sql -v /absolute/path/to/my/confdir:/flyway/conf redgate/flyway migrate –publishResults=true –email= -token= 48 | ``` 49 | 50 | ## Adding SQL files 51 | 52 | To add your own SQL files, place them in a directory and mount it as the `flyway/sql` volume. 53 | 54 | ### Example 55 | 56 | Create a new directory and add a file named `V1__Initial.sql` with following contents: 57 | 58 | ```sql 59 | CREATE TABLE MyTable ( 60 | MyColumn VARCHAR(100) NOT NULL 61 | ); 62 | ``` 63 | 64 | Now run the image with the volume mapped: 65 | 66 | `docker run --rm -v /absolute/path/to/my/sqldir:/flyway/sql redgate/flyway -licenseKey="FL01..." -url=jdbc:h2:mem:test -user=sa migrate` 67 | 68 | ## Adding a config file 69 | 70 | If you prefer to store those arguments in a config file you can also do so using the `flyway/conf` volume. 71 | 72 | ### Example 73 | 74 | Create a file named `flyway.conf` with the following contents: 75 | 76 | ``` 77 | flyway.url=jdbc:h2:mem:test 78 | flyway.user=sa 79 | flyway.licenseKey=FL01... 80 | ``` 81 | 82 | Now run the image with that volume mapped as well: 83 | 84 | `docker run --rm -v /absolute/path/to/my/sqldir:/flyway/sql -v /absolute/path/to/my/confdir:/flyway/conf redgate/flyway migrate` 85 | 86 | ## Adding a JDBC driver 87 | 88 | If your database driver is not shipped by default (you can check the official documentation [here](https://documentation.red-gate.com/fd/flyway-cli-and-api-183306238.html) to see if it is), or if you want to use a different or newer driver than the one included you can do so using the `flyway/drivers` volume. 89 | 90 | ### Example 91 | 92 | Create a directory and drop for example the MySQL JDBC driver in there. 93 | 94 | You can now let Flyway make use of it my mapping that volume as well: 95 | 96 | `docker run --rm -v /absolute/path/to/my/sqldir:/flyway/sql -v /absolute/path/to/my/confdir:/flyway/conf -v /absolute/path/to/my/driverdir:/flyway/drivers redgate/flyway migrate` 97 | 98 | ## Adding Java-based migrations and callbacks 99 | 100 | To pass in Java-based migrations and callbacks you can use the `flyway/jars` volume. 101 | 102 | ### Example 103 | 104 | Create a directory and drop for a jar with your Java-based migrations in there. 105 | 106 | You can now let Flyway make use of it my mapping that volume as well: 107 | 108 | `docker run --rm -v /absolute/path/to/my/sqldir:/flyway/sql -v /absolute/path/to/my/confdir:/flyway/conf -v /absolute/path/to/my/jardir:/flyway/jars redgate/flyway migrate` 109 | 110 | ## Docker Compose 111 | 112 | To run both Flyway and the database that will be migrated in containers, you can use a `docker-compose.yml` file that 113 | starts and links both containers. 114 | 115 | ### Example 116 | 117 | ``` 118 | version: '3' 119 | services: 120 | flyway: 121 | image: redgate/flyway 122 | command: -licenseKey="FL01..." -url=jdbc:mysql://db -schemas=myschema -user=root -password=P@ssw0rd -connectRetries=60 migrate 123 | volumes: 124 | - .:/flyway/sql 125 | depends_on: 126 | - db 127 | db: 128 | image: mysql 129 | environment: 130 | - MYSQL_ROOT_PASSWORD=P@ssw0rd 131 | command: --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci 132 | ports: 133 | - 3306:3306 134 | ``` 135 | 136 | Run `docker-compose up`, this will start both Flyway and MySQL. Flyway will automatically wait for up to one minute for MySQL to be initialized before it begins to migrate the database. 137 | -------------------------------------------------------------------------------- /flyway-docker/lastVersion.sh: -------------------------------------------------------------------------------- 1 | git fetch --tags 2 | lastVersion=$(git describe --tags --abbrev=0) 3 | echo ${lastVersion:1} 4 | -------------------------------------------------------------------------------- /flyway-docker/scripts/build_images.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import utils 3 | import subprocess 4 | 5 | 6 | def get_tag_flags(version, edition, tag_suffix, mongo=False): 7 | qualifier = "" 8 | if mongo: 9 | qualifier = "-mongo" 10 | tags = utils.generate_tags(version, tag_suffix) 11 | command_flags = "" 12 | for tag in tags: 13 | command_flags += f'-t {edition}/flyway:{tag}{qualifier} ' 14 | return command_flags 15 | 16 | 17 | def get_buildx_command(edition, version, tag_suffix, folder, mongo=False, push=False): 18 | pull_or_push = "pull" 19 | if push: 20 | pull_or_push = "push" 21 | platforms = "linux/arm/v7,linux/arm64/v8,linux/amd64" 22 | dockerfile = "Dockerfile" 23 | target = f"--target {edition}" 24 | if mongo: 25 | platforms = "linux/arm64/v8,linux/amd64" 26 | dockerfile = "Dockerfile-mongo" 27 | target = "" 28 | command = f'docker buildx build {target} --platform {platforms} --{pull_or_push} --build-arg FLYWAY_VERSION={version} ' 29 | command += get_tag_flags(version, edition, tag_suffix, mongo) 30 | file_flag = f'-f ./dockerfiles/{folder}/{dockerfile} ' 31 | return command + file_flag + folder 32 | 33 | 34 | def get_build_command(edition, version, tag_suffix, folder, mongo=False): 35 | dockerfile = "Dockerfile" 36 | target = f"--target {edition}" 37 | if mongo: 38 | dockerfile = "Dockerfile-mongo" 39 | target = "" 40 | command = f'docker build {target} --pull --build-arg FLYWAY_VERSION={version} ' 41 | command += get_tag_flags(version, edition, tag_suffix, mongo) 42 | file_flag = f'-f ./dockerfiles/{folder}/{dockerfile} ' 43 | return command + file_flag + "." 44 | 45 | 46 | if __name__ == "__main__": 47 | edition = sys.argv[1] 48 | version = sys.argv[2] 49 | 50 | commands = [] 51 | if edition == "flyway": # We only do multi-arch builds for OSS due to compatibility issues with Redgate Compare 52 | subprocess.run("docker buildx rm multi_arch_builder", shell=True) 53 | commands.append("docker run --rm --privileged multiarch/qemu-user-static --reset -p yes") 54 | commands.append("docker buildx create --name multi_arch_builder --driver docker-container --driver-opt network=bridge --use") 55 | commands.append(get_buildx_command(edition, version, "", ".")) 56 | commands.append(get_buildx_command(edition, version, "", ".", True)) 57 | commands.append(get_build_command(edition, version, "-alpine", "alpine")) 58 | commands.append(get_build_command(edition, version, "-azure", "azure")) 59 | commands.append(get_build_command(edition, version, "-alpine", "alpine", True)) 60 | commands.append(get_build_command(edition, version, "-azure", "azure", True)) 61 | else: 62 | commands.append(get_build_command(edition, version, "", ".")) 63 | commands.append(get_build_command(edition, version, "-alpine", "alpine")) 64 | commands.append(get_build_command(edition, version, "-azure", "azure")) 65 | 66 | for command in commands: 67 | print(f'Running docker build command: {command}') 68 | subprocess.run(command, check=True, shell=True) 69 | -------------------------------------------------------------------------------- /flyway-docker/scripts/download_artifacts.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import urllib.request 3 | from urllib.error import HTTPError 4 | import time 5 | 6 | 7 | def get_repo_url(edition, version, artifact_suffix): 8 | if edition == "flyway": 9 | return f'https://repo1.maven.org/maven2/org/flywaydb/flyway-commandline/{version}/flyway-commandline-{version}{artifact_suffix}.tar.gz' 10 | if edition == "redgate": 11 | return f'https://download.red-gate.com/maven/release/com/redgate/flyway/flyway-commandline/{version}/flyway-commandline-{version}{artifact_suffix}.tar.gz' 12 | print("Edition should be 'flyway' or 'redgate'") 13 | exit(1) 14 | 15 | 16 | def await_and_download_artifact(edition, version, artifact_suffix): 17 | url = get_repo_url(edition, version, artifact_suffix) 18 | while True: 19 | try: 20 | response = urllib.request.urlopen(url) 21 | artifact_file = open(f'flyway-commandline-{version}{artifact_suffix}.tar.gz', 'wb') 22 | artifact_file.write(response.read()) 23 | response.close() 24 | artifact_file.close() 25 | break 26 | except HTTPError: 27 | time.sleep(2) 28 | print("Unable to download artifacts. Trying again in 2 seconds...") 29 | 30 | 31 | if __name__ == "__main__": 32 | edition = sys.argv[1] 33 | version = sys.argv[2] 34 | await_and_download_artifact(edition, version, "") 35 | await_and_download_artifact(edition, version, "-linux-alpine-x64") 36 | 37 | -------------------------------------------------------------------------------- /flyway-docker/scripts/release.py: -------------------------------------------------------------------------------- 1 | import utils 2 | from build_images import get_buildx_command 3 | import subprocess 4 | import sys 5 | 6 | 7 | def get_push_command(edition, tag): 8 | return f'docker push {edition}/flyway:{tag}' 9 | 10 | 11 | if __name__ == "__main__": 12 | edition = sys.argv[1] 13 | version = sys.argv[2] 14 | 15 | release_commands = [] 16 | tags = [] 17 | if edition == "flyway": 18 | # Multi-arch images are pushed using the buildx command 19 | release_commands.append(get_buildx_command(edition, version, "", ".", False, True)) 20 | tags.extend(utils.generate_tags(version, "-alpine")) 21 | tags.extend(utils.generate_tags(version, "-azure")) 22 | release_commands.append(get_buildx_command(edition, version, "", ".", True, True)) 23 | tags.extend(utils.generate_tags(version, "-alpine-mongo")) 24 | tags.extend(utils.generate_tags(version, "-azure-mongo")) 25 | else: 26 | tags.extend(utils.generate_tags(version, "")) 27 | tags.extend(utils.generate_tags(version, "-alpine")) 28 | tags.extend(utils.generate_tags(version, "-azure")) 29 | 30 | release_commands.extend([get_push_command(edition, tag) for tag in tags]) 31 | 32 | for command in release_commands: 33 | print(command) 34 | subprocess.run(command, check=True, shell=True) 35 | -------------------------------------------------------------------------------- /flyway-docker/scripts/test_images.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | import subprocess 4 | 5 | 6 | def build_non_multi_arch_standard_flyway_image(version): 7 | build_command = f'docker build --target flyway --pull --build-arg FLYWAY_VERSION={version} -q -f ./dockerfiles/Dockerfile .' 8 | print(build_command) 9 | return subprocess.run(build_command, capture_output=True, encoding="UTF_8", check=True, shell=True).stdout.strip() 10 | 11 | 12 | if __name__ == "__main__": 13 | edition = sys.argv[1] 14 | version = sys.argv[2] 15 | 16 | images = [f'{edition}/flyway:{version}', f'{edition}/flyway:{version}-alpine', f'{edition}/flyway:{version}-azure'] 17 | flyway_commands = ["info", "migrate", "clean -cleanDisabled=false"] 18 | 19 | if edition == "flyway": 20 | images[0] = build_non_multi_arch_standard_flyway_image(version) 21 | 22 | test_sql_path = os.getcwd() + "/test-sql" 23 | 24 | env_var_flag = "" 25 | if len(sys.argv) > 3: 26 | env_var_flag = f'-e {sys.argv[3]}={os.getenv(sys.argv[3])}' 27 | 28 | flyway_cli_params = "-url=jdbc:sqlite:test " 29 | if edition == "redgate": 30 | flyway_cli_params += f'-licenseKey={os.environ["FLYWAY_LICENSE_KEY"]} ' 31 | flyway_commands.append("check -code -reportFilename=report") 32 | flyway_commands.append("check -changes -check.buildUrl=jdbc:sqlite:temp -reportFilename=report -cleanDisabled=false") 33 | 34 | for image in images: 35 | if "azure" in image: 36 | flyway = "flyway" 37 | else: 38 | flyway = "" 39 | for flyway_command in flyway_commands: 40 | run_command = f'docker run --rm -v "{test_sql_path}:/flyway/sql" {env_var_flag} {image} {flyway} {flyway_command} {flyway_cli_params}' 41 | print(run_command) 42 | subprocess.run(run_command, check=True, shell=True) 43 | -------------------------------------------------------------------------------- /flyway-docker/scripts/utils.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | 4 | def generate_tags(version, tag_suffix): 5 | tags = ["latest", version, get_major_and_minor_version(version), get_major_version(version)] 6 | return [t + tag_suffix for t in tags] 7 | 8 | 9 | def get_major_and_minor_version(version_number): 10 | return re.match(r"\d+\.\d+", version_number).group(0) 11 | 12 | 13 | def get_major_version(version_number): 14 | return re.match(r"\d+", version_number).group(0) -------------------------------------------------------------------------------- /flyway-docker/test-sql/.sqlfluff: -------------------------------------------------------------------------------- 1 | [sqlfluff] 2 | dialect = ansi 3 | -------------------------------------------------------------------------------- /flyway-docker/test-sql/V1__table.sql: -------------------------------------------------------------------------------- 1 | CREATE table TesT_1 ( 2 | id int 3 | ); 4 | --------------------------------------------------------------------------------