Skip to content

Commit

Permalink
Adds support for PostgreSQL which resolves dani-garcia#87 and is ment…
Browse files Browse the repository at this point in the history
…ioned in dani-garcia#246.

This includes migrations as well as Dockerfile's for amd64.

The biggest change is that replace_into isn't supported by Diesel for the
PostgreSQL backend, instead requiring the use of on_conflict. This
unfortunately requires a branch for save() on all of the models currently
using replace_into.
  • Loading branch information
swedishborgie committed Sep 12, 2019
1 parent f9408a0 commit f5f9861
Show file tree
Hide file tree
Showing 18 changed files with 724 additions and 12 deletions.
12 changes: 12 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ build = "build.rs"
# Empty to keep compatibility, prefer to set USE_SYSLOG=true
enable_syslog = []
mysql = ["diesel/mysql", "diesel_migrations/mysql"]
postgresql = ["diesel/postgres", "diesel_migrations/postgres", "openssl"]
sqlite = ["diesel/sqlite", "diesel_migrations/sqlite", "libsqlite3-sys"]

[target."cfg(not(windows))".dependencies]
Expand Down Expand Up @@ -105,6 +106,9 @@ handlebars = "2.0.2"
soup = "0.4.1"
regex = "1.3.1"

# Required for SSL support for PostgreSQL
openssl = { version = "0.10.24", optional = true }

# URL encoding library
percent-encoding = "2.1.0"

Expand Down
8 changes: 6 additions & 2 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,13 @@ use std::process::Command;

fn main() {
#[cfg(all(feature = "sqlite", feature = "mysql"))]
compile_error!("Can't enable both backends");
compile_error!("Can't enable both sqlite and mysql at the same time");
#[cfg(all(feature = "sqlite", feature = "postgresql"))]
compile_error!("Can't enable both sqlite and postgresql at the same time");
#[cfg(all(feature = "mysql", feature = "postgresql"))]
compile_error!("Can't enable both mysql and postgresql at the same time");

#[cfg(not(any(feature = "sqlite", feature = "mysql")))]
#[cfg(not(any(feature = "sqlite", feature = "mysql", feature = "postgresql")))]
compile_error!("You need to enable one DB backend. To build with previous defaults do: cargo build --features sqlite");

read_git_info().ok();
Expand Down
103 changes: 103 additions & 0 deletions docker/amd64/postgresql/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Using multistage build:
# https://docs.docker.com/develop/develop-images/multistage-build/
# https://whitfin.io/speeding-up-rust-docker-builds/
####################### VAULT BUILD IMAGE #######################
FROM alpine:3.10 as vault

ENV VAULT_VERSION "v2.12.0"

ENV URL "https://github.com/dani-garcia/bw_web_builds/releases/download/$VAULT_VERSION/bw_web_$VAULT_VERSION.tar.gz"

RUN apk add --no-cache --upgrade \
curl \
tar

RUN mkdir /web-vault
WORKDIR /web-vault

SHELL ["/bin/ash", "-eo", "pipefail", "-c"]

RUN curl -L $URL | tar xz
RUN ls

########################## BUILD IMAGE ##########################
# We need to use the Rust build image, because
# we need the Rust compiler and Cargo tooling
FROM rust:1.36 as build

# set mysql backend
ARG DB=postgresql

# Using bundled SQLite, no need to install it
# RUN apt-get update && apt-get install -y\
# --no-install-recommends \
# sqlite3\
# && rm -rf /var/lib/apt/lists/*

# Install MySQL package
RUN apt-get update && apt-get install -y \
--no-install-recommends \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*

# Creates a dummy project used to grab dependencies
RUN USER=root cargo new --bin app
WORKDIR /app

# Copies over *only* your manifests and build files
COPY ./Cargo.* ./
COPY ./rust-toolchain ./rust-toolchain
COPY ./build.rs ./build.rs

# Builds your dependencies and removes the
# dummy project, except the target folder
# This folder contains the compiled dependencies
RUN cargo build --features ${DB} --release
RUN find . -not -path "./target*" -delete

# Copies the complete project
# To avoid copying unneeded files, use .dockerignore
COPY . .

# Make sure that we actually build the project
RUN touch src/main.rs

# Builds again, this time it'll just be
# your actual source files being built
RUN cargo build --features ${DB} --release

######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
FROM debian:stretch-slim

ENV ROCKET_ENV "staging"
ENV ROCKET_PORT=80
ENV ROCKET_WORKERS=10

# Install needed libraries
RUN apt-get update && apt-get install -y \
--no-install-recommends \
openssl \
ca-certificates \
curl \
libpq5 \
&& rm -rf /var/lib/apt/lists/*

RUN mkdir /data
VOLUME /data
EXPOSE 80
EXPOSE 3012

# Copies the files from the context (Rocket.toml file and web-vault)
# and the binary from the "build" stage to the current stage
COPY Rocket.toml .
COPY --from=vault /web-vault ./web-vault
COPY --from=build app/target/release/bitwarden_rs .

COPY docker/healthcheck.sh ./healthcheck.sh

HEALTHCHECK --interval=30s --timeout=3s CMD sh healthcheck.sh || exit 1

# Configures the startup!
CMD ["./bitwarden_rs"]
85 changes: 85 additions & 0 deletions docker/amd64/postgresql/Dockerfile.alpine
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Using multistage build:
# https://docs.docker.com/develop/develop-images/multistage-build/
# https://whitfin.io/speeding-up-rust-docker-builds/
####################### VAULT BUILD IMAGE #######################
FROM alpine:3.10 as vault

ENV VAULT_VERSION "v2.12.0"

ENV URL "https://github.com/dani-garcia/bw_web_builds/releases/download/$VAULT_VERSION/bw_web_$VAULT_VERSION.tar.gz"

RUN apk add --no-cache --upgrade \
curl \
tar

RUN mkdir /web-vault
WORKDIR /web-vault

SHELL ["/bin/ash", "-eo", "pipefail", "-c"]

RUN curl -L $URL | tar xz
RUN ls

########################## BUILD IMAGE ##########################
# Musl build image for statically compiled binary
FROM clux/muslrust:nightly-2019-07-08 as build

# set mysql backend
ARG DB=postgresql

ENV USER "root"

# Install needed libraries
RUN apt-get update && apt-get install -y \
--no-install-recommends \
libpq-dev \
&& rm -rf /var/lib/apt/lists/*

WORKDIR /app

# Copies the complete project
# To avoid copying unneeded files, use .dockerignore
COPY . .

RUN rustup target add x86_64-unknown-linux-musl

# Make sure that we actually build the project
RUN touch src/main.rs

# Build
RUN cargo build --features ${DB} --release

######################## RUNTIME IMAGE ########################
# Create a new stage with a minimal image
# because we already have a binary built
FROM alpine:3.10

ENV ROCKET_ENV "staging"
ENV ROCKET_PORT=80
ENV ROCKET_WORKERS=10
ENV SSL_CERT_DIR=/etc/ssl/certs

# Install needed libraries
RUN apk add --no-cache \
openssl \
postgresql-libs \
curl \
ca-certificates

RUN mkdir /data
VOLUME /data
EXPOSE 80
EXPOSE 3012

# Copies the files from the context (Rocket.toml file and web-vault)
# and the binary from the "build" stage to the current stage
COPY Rocket.toml .
COPY --from=vault /web-vault ./web-vault
COPY --from=build /app/target/x86_64-unknown-linux-musl/release/bitwarden_rs .

COPY docker/healthcheck.sh ./healthcheck.sh

HEALTHCHECK --interval=30s --timeout=3s CMD sh healthcheck.sh || exit 1

# Configures the startup!
CMD ["./bitwarden_rs"]
13 changes: 13 additions & 0 deletions migrations/postgresql/2019-09-12-100000_create_tables/down.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
DROP TABLE devices;
DROP TABLE attachments;
DROP TABLE users_collections;
DROP TABLE users_organizations;
DROP TABLE folders_ciphers;
DROP TABLE ciphers_collections;
DROP TABLE twofactor;
DROP TABLE invitations;
DROP TABLE collections;
DROP TABLE folders;
DROP TABLE ciphers;
DROP TABLE users;
DROP TABLE organizations;
Loading

0 comments on commit f5f9861

Please sign in to comment.