Skip to content

Latest commit

 

History

History
192 lines (138 loc) · 6.4 KB

docker.mdx

File metadata and controls

192 lines (138 loc) · 6.4 KB
title description type i18nReady
Build your Astro Site with Docker
Learn how to build your Astro site using Docker.
recipe
true

import { Steps } from '@astrojs/starlight/components';

Docker is a tool to build, deploy, and run applications using containers.

Docker images and containers can be deployed to many different platforms, like AWS, Azure, and Google Cloud. This recipe won't cover how to deploy your site to a specific platform but will show you how to set up Docker for your project.

Prerequisites

Creating a Dockerfile

Create a file called Dockerfile in your project's root directory. This file contains the instructions to build your site, which will differ depending on your needs. This guide can't show all possible options but will give you starting points for SSR and static mode.

If you're using another package manager than npm, you'll need to adjust the commands accordingly.

SSR

This Dockerfile will build your site and serve it using Node.js on port 4321 and therefore requires the Node adapter installed in your Astro project.

FROM node:lts AS runtime
WORKDIR /app

COPY . .

RUN npm install
RUN npm run build

ENV HOST=0.0.0.0
ENV PORT=4321
EXPOSE 4321
CMD node ./dist/server/entry.mjs

:::tip[Keep this in mind] These are just examples of Dockerfiles. You can customize them to your needs. For example, you could use another image, like node:lts-alpine:

FROM node:lts as runtime
FROM node:lts-alpine as runtime

:::

Adding a .dockerignore

Adding a .dockerignore file to your project is best practice. This file describes which files or folders should be ignored in the Docker COPY or ADD commands, very similar to how .gitignore works. This speeds up the build process and reduces the size of the final image.

.DS_Store
node_modules
dist

This file should go in the same directory as the Dockerfile itself. Read the .dockerignore documentation for extra info

Static

Apache (httpd)

The following Dockerfile will build your site and serve it using Apache httpd on port 80 with the default configuration.

FROM node:lts AS build
WORKDIR /app
COPY . .
RUN npm i
RUN npm run build

FROM httpd:2.4 AS runtime
COPY --from=build /app/dist /usr/local/apache2/htdocs/
EXPOSE 80

:::caution[Recommendation] Use this approach for simple websites that don't need any special configuration. For more complex websites, it is recommended to use a custom configuration, either in Apache or NGINX. :::

NGINX

FROM node:lts AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build

FROM nginx:alpine AS runtime
COPY ./nginx/nginx.conf /etc/nginx/nginx.conf
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 8080

In order to build the Dockerfile above, you'll also need to create a configuration file for NGINX. Create a folder called nginx in your project's root directory and create a file called nginx.conf inside.

worker_processes  1;

events {
  worker_connections  1024;
}

http {
  server {
    listen 8080;
    server_name   _;

    root   /usr/share/nginx/html;
    index  index.html index.htm;
    include /etc/nginx/mime.types;

    gzip on;
    gzip_min_length 1000;
    gzip_proxied expired no-cache no-store private auth;
    gzip_types text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;

    error_page 404 /404.html;
    location = /404.html {
            root /usr/share/nginx/html;
            internal;
    }

    location / {
            try_files $uri $uri/index.html =404;
    }
  }
}

Multi-stage build (using SSR)

Here's an example of a more advanced Dockerfile that, thanks to Docker's multi-stage builds, optimizes the build process for your site by not reinstalling the npm dependencies when only the source code changes. This can reduce the build time even by minutes, depending on the size of your dependencies.

FROM node:lts AS base
WORKDIR /app

# By copying only the package.json and package-lock.json here, we ensure that the following `-deps` steps are independent of the source code.
# Therefore, the `-deps` steps will be skipped if only the source code changes.
COPY package.json package-lock.json ./

FROM base AS prod-deps
RUN npm install --production

FROM base AS build-deps
RUN npm install --production=false

FROM build-deps AS build
COPY . .
RUN npm run build

FROM base AS runtime
COPY --from=prod-deps /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist

ENV HOST=0.0.0.0
ENV PORT=4321
EXPOSE 4321
CMD node ./dist/server/entry.mjs

Recipe

1. Build your container by running the following command in your project's root directory. Use any name for ``:
```bash
docker build -t <your-astro-image-name> .
```

This will output an image, which you can run locally or deploy to a platform of your choice.
  1. To run your image as a local container, use the following command.

    Replace <local-port> with an open port on your machine. Replace <container-port> with the port exposed by your Docker container (4321, 80, or 8080 in the above examples.)

    docker run -p <local-port>:<container-port> <your-astro-image-name>

    You should be able to access your site at http://localhost:<local-port>.

  2. Now that your website is successfully built and packaged in a container, you can deploy it to a cloud provider. See the Google Cloud deployment guide for one example, and the Deploy your app page in the Docker docs.