-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 411d327
Showing
4 changed files
with
181 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
name: Build and Publish Docker Image | ||
|
||
on: | ||
push: | ||
branches: | ||
- 'main' | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
permissions: | ||
contents: write | ||
packages: write | ||
id-token: write | ||
|
||
steps: | ||
- name: Checkout sources | ||
uses: actions/checkout@v3 | ||
|
||
- name: Set up QEMU | ||
uses: docker/setup-qemu-action@v2 | ||
|
||
- name: Set up Docker Buildx | ||
id: buildx | ||
uses: docker/setup-buildx-action@v2 | ||
with: | ||
platforms: linux/amd64,linux/arm64 | ||
|
||
- name: Login to GitHub Container Registry | ||
uses: docker/login-action@v2 | ||
with: | ||
registry: ghcr.io | ||
username: ${{ github.actor }} | ||
password: ${{ secrets.GITHUB_TOKEN }} | ||
|
||
- name: Build and Publish | ||
uses: docker/build-push-action@v4 | ||
with: | ||
file: Dockerfile | ||
platforms: linux/arm64, linux/amd64 | ||
push: true | ||
tags: ghcr.io/${{ github.repository }}:latest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
FROM alpine | ||
|
||
RUN apk update && apk add bash ncurses | ||
|
||
# Add the MongoDB package to the apk repositories. | ||
RUN echo "http://dl-cdn.alpinelinux.org/alpine/v3.12/main" >> /etc/apk/repositories | ||
RUN echo "http://dl-cdn.alpinelinux.org/alpine/v3.12/community" >> /etc/apk/repositories | ||
|
||
# Install MongoDB tools | ||
RUN apk add --no-cache mongodb-tools | ||
|
||
WORKDIR app | ||
|
||
ADD . . | ||
|
||
CMD bash migrate.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
# MySQL Plugin Migration | ||
|
||
Script and Docker image to automate migrating the Railway MySQL plugin to a Database service. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
#!/bin/bash | ||
|
||
sleep 2 | ||
|
||
set -o pipefail | ||
|
||
export TERM=ansi | ||
_GREEN=$(tput setaf 2) | ||
_BLUE=$(tput setaf 4) | ||
_MAGENTA=$(tput setaf 5) | ||
_CYAN=$(tput setaf 6) | ||
_RED=$(tput setaf 1) | ||
_YELLOW=$(tput setaf 3) | ||
_RESET=$(tput sgr0) | ||
_BOLD=$(tput bold) | ||
|
||
# Function to print error messages and exit | ||
error_exit() { | ||
printf "[ ${_RED}ERROR${_RESET} ] ${_RED}$1${_RESET}\n" >&2 | ||
exit 1 | ||
} | ||
|
||
section() { | ||
printf "${_RESET}\n" | ||
echo "${_BOLD}${_BLUE}==== $1 ====${_RESET}" | ||
} | ||
|
||
write_ok() { | ||
echo "[$_GREEN OK $_RESET] $1" | ||
} | ||
|
||
write_warn() { | ||
echo "[$_YELLOW WARN $_RESET] $1" | ||
} | ||
|
||
trap 'echo "An error occurred. Exiting..."; exit 1;' ERR | ||
|
||
printf "${_BOLD}${_MAGENTA}" | ||
echo "+-------------------------------------+" | ||
echo "| |" | ||
echo "| Railway Postgres Migration Script |" | ||
echo "| |" | ||
echo "+-------------------------------------+" | ||
printf "${_RESET}\n" | ||
|
||
echo "For more information, see https://docs.railway.app/database/migration" | ||
echo "If you run into any issues, please reach out to us on Discord: https://discord.gg/railway" | ||
printf "${_RESET}\n" | ||
|
||
section "Validating environment variables" | ||
|
||
# Parse components using a tool like 'sed' or 'awk' | ||
PLUGIN_USER=$(echo $PLUGIN_URL | sed -e 's/mysql:\/\/\(.*\):.*@.*/\1/') | ||
PLUGIN_PASSWORD=$(echo $PLUGIN_URL | sed -e 's/mysql:\/\/.*:\(.*\)@.*/\1/') | ||
PLUGIN_HOST=$(echo $PLUGIN_URL | sed -e 's/mysql:\/\/.*@\(.*\):.*/\1/') | ||
PLUGIN_PORT=$(echo $PLUGIN_URL | sed -e 's/mysql:\/\/.*@.*:\(.*\)\/.*/\1/') | ||
PLUGIN_DB=$(echo $PLUGIN_URL | sed -e 's/mysql:\/\/.*@.*\/\(.*\)/\1/') | ||
|
||
NEW_USER=$(echo $NEW_URL | sed -e 's/mysql:\/\/\(.*\):.*@.*/\1/') | ||
NEW_PASSWORD=$(echo $NEW_URL | sed -e 's/mysql:\/\/.*:\(.*\)@.*/\1/') | ||
NEW_HOST=$(echo $NEW_URL | sed -e 's/mysql:\/\/.*@\(.*\):.*/\1/') | ||
NEW_PORT=$(echo $NEW_URL | sed -e 's/mysql:\/\/.*@.*:\(.*\)\/.*/\1/') | ||
NEW_DB=$(echo $NEW_URL | sed -e 's/mysql:\/\/.*@.*\/\(.*\)/\1/') | ||
|
||
# Validate that PLUGIN_URL environment variable exists | ||
if [ -z "$PLUGIN_URL" ]; then | ||
error_exit "PLUGIN_URL environment variable is not set." | ||
fi | ||
|
||
write_ok "PLUGIN_URL correctly set" | ||
|
||
# Validate that NEW_URL environment variable exists | ||
if [ -z "$NEW_URL" ]; then | ||
error_exit "NEW_URL environment variable is not set." | ||
fi | ||
|
||
write_ok "NEW_URL correctly set" | ||
|
||
section "Checking if NEW_URL is empty" | ||
|
||
# Using mongo shell to check if any collection has documents | ||
result=$(mongo "$NEW_URL" --quiet --eval "db.getCollectionNames().length") | ||
|
||
if [[ "$result" -gt 0 ]]; then | ||
if [ -z "$OVERWRITE_DATABASE" ]; then | ||
error_exit "The new database is not empty. Aborting migration.\nSet the OVERWRITE_DATABASE environment variable to overwrite the new database." | ||
fi | ||
write_warn "The new database is not empty. Found OVERWRITE_DATABASE environment variable. Proceeding with restore." | ||
else | ||
write_ok "The new database is empty. Proceeding with restore." | ||
fi | ||
|
||
section "Dumping database from PLUGIN_URL" | ||
|
||
dump_file="plugin_dump.archive" | ||
mongodump --uri="$PLUGIN_URL" --archive=$dump_file | ||
|
||
write_ok "Successfully saved dump to $dump_file" | ||
|
||
dump_file_size=$(ls -lh "$dump_file" | awk '{print $5}') | ||
echo "Dump file size: $dump_file_size" | ||
|
||
section "Restoring database to NEW_URL" | ||
|
||
# Restore that data to the new database | ||
mongorestore --uri="$NEW_URL" --archive=$dump_file | ||
|
||
write_ok "Successfully restored database to NEW_URL" | ||
|
||
printf "${_RESET}\n" | ||
printf "${_RESET}\n" | ||
echo "${_BOLD}${_GREEN}Migration completed successfully${_RESET}" | ||
printf "${_RESET}\n" | ||
echo "Next steps..." | ||
echo "1. Update your application's DATABASE_URL environment variable to point to the new database." | ||
echo ' - You can use variable references to do this. For example `${{ MySQL.DATABASE_URL }}`' | ||
echo "2. Verify that your application is working as expected." | ||
echo "3. Remove the legacy plugin and this service from your Railway project." | ||
|
||
printf "${_RESET}\n" |