How to deploy a Nest app to Railway using Bitbucket pipelines
Tags: node, nestjs, bitbucket, cicd
Published: 2024-02-23 11:00:00

Deploying a project from GitHub to Railway is as straightforward as knowing your name, but there's more when deploying from Bitbucket. Many of us love Railway because it offers features that we (developers) find beneficial, such as easy deployment workflows, scalability, good performance, cost-effectiveness, and robust support for various programming languages and frameworks. For me, it's just a "plug-and-play" app.

The aggravation I felt knowing that Railway did not natively support Bitbucket prompted me to devise a workaround.

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong>Just for laugh:</strong> Railway only support "Big Boys" 😆</div>
</div>

After a futile search through the internet pages, expecting to locate an existing solution, an inspiration struck me: what if all I had to do was construct a deployment pipeline, like Railway had done behind the scenes for GitHub? That struck a chord in my mind.

If you have been trying to achieve this, sweat no more; you can now deploy from Bitbucket using CI/CD (bitbucket pipelines).

<div data-node-type="callout">
<div data-node-type="callout-emoji">💡</div>
<div data-node-type="callout-text"><strong>Just for laugh:</strong> You can tell Railway you're a "Bigger Boy" now 😆</div>
</div>

Without further ado, let’s begin.

Prerequisites:

* A Bitbucket account.
    
* A [Railway account](https://bit.ly/3OnffBY) already setup. (If you do not already have an account, you can create one [here](https://bit.ly/3OnffBY))
    

In the root folder of your application, create a file called `bitbucket-pipelines.yml` and add the following code snippet:

```yaml
image: node:18

clone:
  depth: full

pipelines:
  branches:
    main:
    - step:
        name: Deploy to railway
        caches:
          - node
        deployment: production # Only if you have more than one environment
        script:
          - npm i -g @railway/cli
          - RAILWAY_TOKEN=$RAILWAY_TOKEN railway up --service=$RAILWAY_SERVICE
```

**NOTE:** Please take note of the indention. Any incorrect indentation will render your pipeline invalid.

To avoid "story that touches," you can validate your pipeline before pushing to Bitbucket using this link: [https://bitbucket-pipelines.prod.public.atl-paas.net/validator](https://bitbucket-pipelines.prod.public.atl-paas.net/validator)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744131733/b9518702-241c-4a86-8e5d-a34bd69d7ed1.png)

After you've validated your pipeline with `VALID` status, you can push your repo to Bitbucket.

Just a step back, if you're a DevOps engineer, this pipeline is simple math; but, if you're unfamiliar with CI/CD pipelines, this may appear to be a mirage to you.

Check out the [official documentation](https://support.atlassian.com/bitbucket-cloud/docs/bitbucket-pipelines-configuration-reference/) to fully understand Bitbucket pipelines. To gain a basic grasp of CI/CD, check this article: [https://itnext.io/ci-cd-an-introduction-using-bitbucket-pipelines-8701a400b97d](https://itnext.io/ci-cd-an-introduction-using-bitbucket-pipelines-8701a400b97d)

Now, let me walk you through the pipeline I just constructed.

I used node v18 as my image, but you can use any node version you wish. One thing I enjoy doing is caching `node` to minimize build time; you should do the same.

Take heed of this line.

```yaml
deployment: production
```

This is unnecessary if you just have one deployment environment, but in practice, you will have several environments. This line instructs Bitbucket which environment variables to deploy. In our instance, it is the production environment, which implies that our pipeline will deploy utilizing variables from that environment. I'll go into how you can do this later.

Let us now go on to the last line, which completes the railway deployment.

```yaml
- RAILWAY_TOKEN=$RAILWAY_TOKEN railway up --service=$RAILWAY_SERVICE
```

You'll notice $RAILWAY\_TOKEN and $RAILWAY\_SERVICE. These two variables will serve as your environment variables later on, and they are required to start our pipeline.

For you to connect to your railway project, you'll need a railway token and a service ID to identify the exact service for which your project is hosted, but to achieve that, you have to set up your railway project.

**Step 1:** First, start a new project and select `Empty Project` .

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744219900/18c4d429-7072-4f9b-8bb9-faf7eac4d4f6.png)

**Step 2:** After your project has been created, you’ll see the following image prompting you to add a service. Simply follow the process of adding a service.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744246531/83b667e5-2bb1-4736-9384-58aac019fe86.png)

**Step 3:** Now it's time to acquire your token and service ID. Click on the service you created, as illustrated below:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744287919/fae11deb-5ea6-4488-9dbe-5c30050bd8d2.png)

Navigate to the page address, and you'll notice a URL string in this format:

`https://railway.app/project/<project-id>/service/<service-id>` .

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744317375/3de2d303-b301-4074-9fe3-ea21d25470c3.jpeg)

Copy `<service-id>` which is your service ID, and save it somewhere for later use, as this will serve as your $RAILWAY\_SERVICE.

Now click on the `Tokens` tab. Create a new token with any name of your choice. I opted to use `BITBUCKET_DEPLOY` to signify that this token is intended for usage with Bitbucket.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744355653/f39f5206-6ef0-4ca9-82e5-22bf54233e28.png)

Copy the token immediately and securely store it as previously described, since this will function as your $RAILWAY\_TOKEN.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744371595/4288abd5-9a78-43aa-966a-0f5361e1301e.jpeg)

**NOTE:** You will only be shown the token once, after which you will be unable to copy it again.

**Step 4:** Check the build and start commands by accessing your service's `settings` page. **NOTE:** The default build and start commands are `npm run build` and `npm run start` respectively. If your project requires a different command, adjust it accordingly.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744406682/dcb2e364-2537-4e52-998d-e7985be745fc.png)

**Step 5 (optional):** If your project requires environment variables, which is the case in real life, proceed to the `Variables` tab.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744443631/2e96eadc-0f41-4e2c-8cd8-4a6ae7ef5528.png)

Click on `RAW Editor` .

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744466526/cb381f79-0d55-4876-9c7d-d6c5aa9e1e71.png)

Under the `ENV` tab, paste your `.env` variables from your nest app and hit the `Update Variables` button, and you're done.

Now, let's return to your Bitbucket repository and configure your pipeline. Click on `Repository settings`, go down to `Settings`, and then change `Enable Pipelines` to true.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744506526/a6bb4213-21c0-448f-9b56-a36c9c936075.png)

After that, click on `Deployments` and scroll down to choose the production environment, since you will be deploying to this environment. Create the variable `RAILWAY_TOKEN` and put the token you saved previously into it. Before adding it, ensure that the `Secured` option is set to `true`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744537360/8b44a660-fd5c-4918-9a5a-465af0c6f948.png)

**NOTE:** This page allows you to manage variables for various deployment environments.

Next, navigate to `Repository Variables`. Create a `RAILWAY_SERVICE` variable and put the service ID you saved previously into it. Also, before adding, ensure that the `Secured` option is set to `true`.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744564629/b26350a7-b2be-48d6-a411-f34bcca5885a.png)

Hurray! 💃 Your pipeline is ready to receive oil.

Now, return to your repo, choose the `Pipelines` tab, run the pipeline by clicking theb `Run initial pipeline` button, and follow through with the procedures.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744597316/de187fe1-5503-4540-a361-d14da50582e1.png)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744643439/622dc5fb-e5ec-484e-bc70-0cdfeba5fdae.png)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744658770/d71dc0f1-c1bf-49c4-8a50-d21797138bc5.png)

If the pipeline is successful, you should see the following:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744679863/151634da-2727-4b9e-8a01-70fb3a5c4456.png)

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744700499/9341605f-9234-4e13-b406-7fce73b1a03b.png)

Bravo! Now let's return to Railway to observe your deployment.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744717840/e773946f-70e8-4fd7-8a4c-2942c3675998.png)

You can see that your project is now being deployed. After it is successful, you will see the following:

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744730383/94951125-d002-4beb-9f89-c1fc60653afb.png)

At this point, your project has been successfully deployed. You may view the logs and see them for yourself.

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1707744748485/08839b1a-c2e5-4650-8de3-53370d8c36ed.png)

Now you can easily deploy from Bitbucket to Railway. My work here is done till we meet again.

P.S. You can also use this pipeline for other projects.